diff --git a/source/CPacketSend.cpp b/source/CPacketSend.cpp index ba30f52d8..e74cc6f15 100644 --- a/source/CPacketSend.cpp +++ b/source/CPacketSend.cpp @@ -7665,6 +7665,27 @@ void CPToolTip::CopyItemData( CItem& cItem, size_t &totalStringLen, bool addAmou FinalizeData( tempEntry, totalStringLen ); } + if( cItem.GetHealthBonus() > 0 ) + { + tempEntry.stringNum = 1060431; // hit point increase ~1_val~ + tempEntry.ourText = oldstrutil::number( cItem.GetHealthBonus() ); + FinalizeData( tempEntry, totalStringLen ); + } + + if( cItem.GetStaminaBonus() > 0 ) + { + tempEntry.stringNum = 1060484; // stamina increase ~1_val~ + tempEntry.ourText = oldstrutil::number( cItem.GetStaminaBonus() ); + FinalizeData( tempEntry, totalStringLen ); + } + + if( cItem.GetManaBonus() > 0 ) + { + tempEntry.stringNum = 1060439; // mana increase ~1_val~ + tempEntry.ourText = oldstrutil::number( cItem.GetManaBonus() ); + FinalizeData( tempEntry, totalStringLen ); + } + if( cItem.GetStrength() > 1 ) { tempEntry.stringNum = 1061170; // strength requirement ~1_val~ diff --git a/source/Changelog.txt b/source/Changelog.txt index f62b29102..7641bf853 100644 --- a/source/Changelog.txt +++ b/source/Changelog.txt @@ -1,3 +1,11 @@ +13/06/2024 - Dragon Slayer + Added three More AOS Props + -HEALTHBONUS=# + -MANABONUS=# + -STAMINABONUS=# + Add this properties to any weapon/armor/jewlery will give the player more hp/mana/stam why its equiped. depending on number you add with it + These are also available as JS Engine object properties: .healthBonus, .staminaBonus, .manaBonus + 13/05/2024 - Dragon Slayer Added New Shield Type 107 so shield ID's no longer have to be in hard code for shields to work properly @@ -9,6 +17,7 @@ -ARTIFACTRARITY=# -Artifact Rarity is an item property that is visible on some artifacts and meant to give players an idea of how rare the item is. Items with rarity 1 are supposed to be common while rarity 12 are extremely scarce. + 1/05/2024 - Dragon Slayer/Xuri Fixed AutoUnequipAttempt function in clumsy.js, createfood.js level1target.js, will no longer fail on casting and return to hardcode. Fixed createfood to check for reagents on cast. diff --git a/source/UOXJSPropertyEnums.h b/source/UOXJSPropertyEnums.h index 45517f28d..d785c5137 100644 --- a/source/UOXJSPropertyEnums.h +++ b/source/UOXJSPropertyEnums.h @@ -517,6 +517,9 @@ enum CI_Properties CIP_ISCONTTYPE, CIP_CARVESECTION, CIP_SPEED, + CIP_HEALTHBONUS, + CIP_STAMINABONUS, + CIP_MANABONUS, CIP_MULTI, CIP_AMMOID, CIP_AMMOHUE, diff --git a/source/UOXJSPropertyFuncs.cpp b/source/UOXJSPropertyFuncs.cpp index 5fc2a3a82..906a73910 100644 --- a/source/UOXJSPropertyFuncs.cpp +++ b/source/UOXJSPropertyFuncs.cpp @@ -676,6 +676,9 @@ JSBool CItemProps_getProperty( JSContext *cx, JSObject *obj, jsval id, jsval *vp case CIP_DAMAGERAIN: *vp = BOOLEAN_TO_JSVAL( gPriv->GetWeatherDamage( RAIN )); break; case CIP_DAMAGESNOW: *vp = BOOLEAN_TO_JSVAL( gPriv->GetWeatherDamage( SNOW )); break; case CIP_SPEED: *vp = INT_TO_JSVAL( gPriv->GetSpeed() ); break; + case CIP_HEALTHBONUS: *vp = INT_TO_JSVAL( gPriv->GetHealthBonus() ); break; + case CIP_STAMINABONUS: *vp = INT_TO_JSVAL( gPriv->GetStaminaBonus() ); break; + case CIP_MANABONUS: *vp = INT_TO_JSVAL( gPriv->GetManaBonus() ); break; case CIP_ARTIFACTRARITY: *vp = INT_TO_JSVAL( gPriv->GetArtifactRarity() ); break; case CIP_NAME2: tString = JS_NewStringCopyZ( cx, gPriv->GetName2().c_str() ); @@ -1322,6 +1325,9 @@ JSBool CItemProps_setProperty( JSContext *cx, JSObject *obj, jsval id, jsval *vp case CIP_DAMAGERAIN: gPriv->SetWeatherDamage( RAIN, encaps.toBool() ); break; case CIP_DAMAGESNOW: gPriv->SetWeatherDamage( SNOW, encaps.toBool() ); break; case CIP_SPEED: gPriv->SetSpeed( static_cast( encaps.toInt() )); break; + case CIP_HEALTHBONUS: gPriv->SetHealthBonus( static_cast( encaps.toInt() )); break; + case CIP_STAMINABONUS: gPriv->SetStaminaBonus( static_cast( encaps.toInt() )); break; + case CIP_MANABONUS: gPriv->SetManaBonus( static_cast( encaps.toInt() )); break; case CIP_ARTIFACTRARITY: gPriv->SetArtifactRarity( static_cast( encaps.toInt() )); break; case CIP_NAME2: gPriv->SetName2( encaps.toString() ); break; case CIP_RACE: gPriv->SetRace( static_cast( encaps.toInt() )); break; diff --git a/source/UOXJSPropertySpecs.h b/source/UOXJSPropertySpecs.h index 8607ffab5..c81b1f58d 100644 --- a/source/UOXJSPropertySpecs.h +++ b/source/UOXJSPropertySpecs.h @@ -535,6 +535,9 @@ inline JSPropertySpec CItemProps[] = { "ammoFXHue", CIP_AMMOFXHUE, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "ammoFXRender", CIP_AMMOFXRENDER, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "speed", CIP_SPEED, JSPROP_ENUMANDPERM, nullptr, nullptr }, + { "healthBonus", CIP_HEALTHBONUS, JSPROP_ENUMANDPERM, nullptr, nullptr }, + { "staminaBonus", CIP_STAMINABONUS, JSPROP_ENUMANDPERM, nullptr, nullptr }, + { "manaBonus", CIP_MANABONUS, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "artifactRarity", CIP_ARTIFACTRARITY, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "multi", CIP_MULTI, JSPROP_ENUMANDPERM, nullptr, nullptr }, { "maxRange", CIP_MAXRANGE, JSPROP_ENUMANDPERM, nullptr, nullptr }, diff --git a/source/cBaseObject.cpp b/source/cBaseObject.cpp index 506c247ac..131f0417b 100644 --- a/source/cBaseObject.cpp +++ b/source/cBaseObject.cpp @@ -94,6 +94,9 @@ const SI16 DEFBASE_KILLS = 0; const UI16 DEFBASE_RESIST = 0; const bool DEFBASE_NAMEREQUESTACTIVE = 0; const ExpansionRuleset DEFBASE_ORIGIN = ER_UO; +const SI16 DEFBASE_HEALTHBONUS = 0; +const SI16 DEFBASE_STAMINABONOS = 0; +const SI16 DEFBASE_MANABONUS = 0; //o------------------------------------------------------------------------------------------------o //| Function - CBaseObject constructor @@ -110,7 +113,8 @@ loDamage( DEFBASE_LODAMAGE ), weight( DEFBASE_WEIGHT ), mana( DEFBASE_MANA ), stamina( DEFBASE_STAMINA ), scriptTrig( DEFBASE_SCPTRIG ), st2( DEFBASE_STR2 ), dx2( DEFBASE_DEX2 ), in2( DEFBASE_INT2 ), FilePosition( DEFBASE_FP ), poisoned( DEFBASE_POISONED ), carve( DEFBASE_CARVE ), oldLocX( 0 ), oldLocY( 0 ), oldLocZ( 0 ), oldTargLocX( 0 ), oldTargLocY( 0 ), -fame( DEFBASE_FAME ), karma( DEFBASE_KARMA ), kills( DEFBASE_KILLS ), subRegion( DEFBASE_SUBREGION ), nameRequestActive( DEFBASE_NAMEREQUESTACTIVE ), origin( DEFBASE_ORIGIN ) +fame( DEFBASE_FAME ), karma( DEFBASE_KARMA ), kills( DEFBASE_KILLS ), subRegion( DEFBASE_SUBREGION ), nameRequestActive( DEFBASE_NAMEREQUESTACTIVE ), origin( DEFBASE_ORIGIN ), +healthBonus( DEFBASE_HEALTHBONUS ),staminaBonus( DEFBASE_STAMINABONOS ), manaBonus( DEFBASE_MANABONUS ) { multis = nullptr; tempMulti = INVALIDSERIAL; @@ -1631,6 +1635,69 @@ void CBaseObject::SetIntelligence2( SI16 nVal ) } } +//o------------------------------------------------------------------------------------------------o +//| Function - CBaseObject::GetHealthBonus() +//| CBaseObject::SetHealthBonus() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Gets/Sets the health max var associated with the object. For chars, it's the +//| bonuses (via armour and such) +//o------------------------------------------------------------------------------------------------o +SI16 CBaseObject::GetHealthBonus( void ) const +{ + return healthBonus; +} +void CBaseObject::SetHealthBonus( SI16 nVal ) +{ + healthBonus = nVal; + + if( CanBeObjType( OT_ITEM )) + { + ( static_cast( this ))->UpdateRegion(); + } +} + +//o------------------------------------------------------------------------------------------------o +//| Function - CBaseObject::GetStaminaBonus() +//| CBaseObject::SetStaminaBonus() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Gets/Sets the stamina max var associated with the object. For chars, it's the +//| bonuses (via armour and such) +//o------------------------------------------------------------------------------------------------o +SI16 CBaseObject::GetStaminaBonus( void ) const +{ + return staminaBonus; +} +void CBaseObject::SetStaminaBonus( SI16 nVal ) +{ + staminaBonus = nVal; + + if( CanBeObjType( OT_ITEM )) + { + ( static_cast( this ))->UpdateRegion(); + } +} + +//o------------------------------------------------------------------------------------------------o +//| Function - CBaseObject::GetManaBonus() +//| CBaseObject::SetManaBonus() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Gets/Sets the Mana max var associated with the object. For chars, it's the +//| bonuses (via armour and such) +//o------------------------------------------------------------------------------------------------o +SI16 CBaseObject::GetManaBonus( void ) const +{ + return manaBonus; +} +void CBaseObject::SetManaBonus( SI16 nVal ) +{ + manaBonus = nVal; + + if( CanBeObjType( OT_ITEM )) + { + ( static_cast( this ))->UpdateRegion(); + } +} + //o------------------------------------------------------------------------------------------------o //| Function - CBaseObject::IncStrength() //o------------------------------------------------------------------------------------------------o diff --git a/source/cBaseObject.h b/source/cBaseObject.h index 638e826f7..b3c7e98f9 100644 --- a/source/cBaseObject.h +++ b/source/cBaseObject.h @@ -79,6 +79,9 @@ class CBaseObject SI16 st2; SI16 dx2; SI16 in2; + SI16 healthBonus; + SI16 staminaBonus; + SI16 manaBonus; mutable SI32 FilePosition; SERIAL tempMulti; std::string name; @@ -256,6 +259,15 @@ class CBaseObject void IncDexterity( SI16 toInc = 1 ); void IncIntelligence( SI16 toInc = 1 ); + SI16 GetHealthBonus( void ) const; + virtual void SetHealthBonus( SI16 nVal ); + + SI16 GetStaminaBonus( void ) const; + virtual void SetStaminaBonus( SI16 nVal ); + + SI16 GetManaBonus( void ) const; + virtual void SetManaBonus( SI16 nVal ); + virtual void PostLoadProcessing( void ); virtual bool LoadRemnants( void ) = 0; diff --git a/source/cChar.cpp b/source/cChar.cpp index 7aa03f6fa..bcd9e90f6 100644 --- a/source/cChar.cpp +++ b/source/cChar.cpp @@ -2920,6 +2920,10 @@ bool CChar::WearItem( CItem *toWear ) IncDexterity2( itemLayers[tLayer]->GetDexterity2() ); IncIntelligence2( itemLayers[tLayer]->GetIntelligence2() ); + IncHealthBonus( itemLayers[tLayer]->GetHealthBonus() ); + IncStaminaBonus( itemLayers[tLayer]->GetStaminaBonus() ); + IncManaBonus( itemLayers[tLayer]->GetManaBonus() ); + if( toWear->IsPostLoaded() ) { if( itemLayers[tLayer]->GetPoisoned() ) @@ -2979,6 +2983,11 @@ bool CChar::TakeOffItem( ItemLayers Layer ) IncStrength2( -itemLayers[Layer]->GetStrength2() ); IncDexterity2( -itemLayers[Layer]->GetDexterity2() ); IncIntelligence2( -itemLayers[Layer]->GetIntelligence2() ); + + IncHealthBonus( -itemLayers[Layer]->GetHealthBonus() ); + IncStaminaBonus( -itemLayers[Layer]->GetStaminaBonus() ); + IncManaBonus( -itemLayers[Layer]->GetManaBonus() ); + if( itemLayers[Layer]->GetPoisoned() ) { if( itemLayers[Layer]->GetPoisoned() > GetPoisoned() ) @@ -3787,7 +3796,7 @@ UI16 CChar::GetMaxHP( void ) oldRace = GetRace(); } - return maxHP; + return maxHP + GetHealthBonus(); } void CChar::SetMaxHP( UI16 newmaxhp, UI16 newoldstr, RACEID newoldrace ) { @@ -3830,7 +3839,7 @@ void CChar::SetFixedMaxHP( SI16 newmaxhp ) SI16 CChar::GetMaxMana( void ) { if(( maxMana_oldint != GetIntelligence() || oldRace != GetRace() ) && !GetMaxManaFixed() ) - //if int/race changed since last calculation, recalculate maxHp + //if int/race changed since last calculation, recalculate maxMana { CRace *pRace = Races->Race( GetRace() ); @@ -3847,7 +3856,7 @@ SI16 CChar::GetMaxMana( void ) oldRace = GetRace(); } - return maxMana; + return maxMana + GetManaBonus(); } void CChar::SetMaxMana( SI16 newmaxmana, UI16 newoldint, RACEID newoldrace ) { @@ -3889,7 +3898,7 @@ void CChar::SetFixedMaxMana( SI16 newmaxmana ) //o------------------------------------------------------------------------------------------------o SI16 CChar::GetMaxStam( void ) { - // If dex/race changed since last calculation, recalculate maxHp + // If dex/race changed since last calculation, recalculate maxStam if(( maxStam_olddex != GetDexterity() || oldRace != GetRace() ) && !GetMaxStamFixed() ) { CRace *pRace = Races->Race( GetRace() ); @@ -3907,7 +3916,7 @@ SI16 CChar::GetMaxStam( void ) oldRace = GetRace(); } - return maxStam; + return maxStam + GetStaminaBonus(); } void CChar::SetMaxStam( SI16 newmaxstam, UI16 newolddex, RACEID newoldrace ) { @@ -5593,6 +5602,74 @@ void CChar::SetIntelligence2( SI16 nVal ) UpdateRegion(); } +//o------------------------------------------------------------------------------------------------o +//| Function - CChar::SetHealthBonus() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Sets bonus Hits stat for character +//o------------------------------------------------------------------------------------------------o +void CChar::SetHealthBonus( SI16 nVal ) +{ + CBaseObject::SetHealthBonus( nVal ); + Dirty( UT_HITPOINTS ); + UpdateRegion(); +} + +//o------------------------------------------------------------------------------------------------o +//| Function - CChar::SetStaminaBonus() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Sets bonus Stam stat for character +//o------------------------------------------------------------------------------------------------o +void CChar::SetStaminaBonus( SI16 nVal ) +{ + CBaseObject::SetStaminaBonus( nVal ); + Dirty( UT_STAMINA ); + UpdateRegion(); +} + +//o------------------------------------------------------------------------------------------------o +//| Function - CChar::SetManaBonus() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Sets bonus Mana stat for character +//o------------------------------------------------------------------------------------------------o +void CChar::SetManaBonus( SI16 nVal ) +{ + CBaseObject::SetManaBonus( nVal ); + Dirty( UT_MANA ); + UpdateRegion(); +} + +//o------------------------------------------------------------------------------------------------o +//| Function - CChar::IncHealthBonus() +//o------------------------------------------------------------------------------------------------o +//| Purpose - Increments GetHealthBonus (modifications) by toAdd +//o------------------------------------------------------------------------------------------------o +void CChar::IncHealthBonus( SI16 toAdd ) +{ + SetHealthBonus( static_cast( GetHealthBonus() + toAdd )); +} + +//o------------------------------------------------------------------------------------------------o +//| Function - CChar::IncStaminaBonus() +//| Date - 26 May 2024 +//o------------------------------------------------------------------------------------------------o +//| Purpose - Increments GetBonusStam (modifications) by toAdd +//o------------------------------------------------------------------------------------------------o +void CChar::IncStaminaBonus( SI16 toAdd ) +{ + SetStaminaBonus( static_cast( GetStaminaBonus() + toAdd )); +} + +//o------------------------------------------------------------------------------------------------o +//| Function - CChar::IncManaBonus() +//| Date - 26 May 2024 +//o------------------------------------------------------------------------------------------------o +//| Purpose - Increments GetBonusMana (modifications) by toAdd +//o------------------------------------------------------------------------------------------------o +void CChar::IncManaBonus( SI16 toAdd ) +{ + SetManaBonus( static_cast( GetManaBonus() + toAdd )); +} + //o------------------------------------------------------------------------------------------------o //| Function - CChar::IncStamina() //o------------------------------------------------------------------------------------------------o diff --git a/source/cChar.h b/source/cChar.h index ed4cc90ba..ae387a58c 100644 --- a/source/cChar.h +++ b/source/cChar.h @@ -628,6 +628,15 @@ class CChar : public CBaseObject virtual void SetStrength2( SI16 newValue ) override; virtual void SetDexterity2( SI16 newValue ) override; virtual void SetIntelligence2( SI16 newValue ) override; + + virtual void SetHealthBonus( SI16 newValue ) override; + virtual void SetStaminaBonus( SI16 newValue ) override; + virtual void SetManaBonus( SI16 newValue ) override; + + void IncHealthBonus( SI16 toAdd = 1 ); + void IncStaminaBonus( SI16 toAdd = 1 ); + void IncManaBonus( SI16 toAdd = 1 ); + void IncStamina( SI16 toInc ); void IncMana( SI16 toInc ); void SetMaxLoyalty( UI16 newMaxLoyalty ); diff --git a/source/cItem.cpp b/source/cItem.cpp index 3a2acd106..ed6672205 100644 --- a/source/cItem.cpp +++ b/source/cItem.cpp @@ -1671,6 +1671,9 @@ auto CItem::CopyData( CItem *target ) -> void target->SetWeightMax( GetWeightMax() ); target->SetBaseWeight( GetBaseWeight() ); target->SetMaxItems( GetMaxItems() ); + target->SetHealthBonus( GetHealthBonus() ); + target->SetStaminaBonus( GetStaminaBonus() ); + target->SetManaBonus( GetManaBonus() ); //target->SetWipeable( IsWipeable() ); target->SetPriv( GetPriv() ); target->SetBaseRange( GetBaseRange() ); @@ -1754,6 +1757,7 @@ bool CItem::DumpBody( std::ostream &outStream ) const outStream << "MaxItems=" + std::to_string( GetMaxItems() ) + newLine; outStream << "MaxHP=" + std::to_string( GetMaxHP() ) + newLine; outStream << "Speed=" + std::to_string( GetSpeed() ) + newLine; + outStream << "BonusStats=" + std::to_string( GetHealthBonus() ) + "," + std::to_string( GetStaminaBonus() ) + "," + std::to_string( GetManaBonus() ) + newLine; outStream << "ArtifactRarity=" + std::to_string( GetArtifactRarity() ) + newLine; outStream << "Movable=" + std::to_string( GetMovable() ) + newLine; outStream << "Priv=" + std::to_string( GetPriv() ) + newLine; @@ -1843,6 +1847,13 @@ bool CItem::HandleLine( std::string &UTag, std::string &data ) bools = static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( data, "//" )), nullptr, 0 )); rValue = true; } + else if( UTag == "BONUSSTATS" ) + { + SetHealthBonus( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( csecs[0], "//" )), nullptr, 0 ))); + SetStaminaBonus( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( csecs[1], "//" )), nullptr, 0 ))); + SetManaBonus( static_cast( std::stoul( oldstrutil::trim( oldstrutil::removeTrailing( csecs[2], "//" )), nullptr, 0 ))); + rValue = true; + } break; case 'C': if( UTag == "CONT" ) diff --git a/source/items.cpp b/source/items.cpp index a95e80f70..101f7338c 100644 --- a/source/items.cpp +++ b/source/items.cpp @@ -140,6 +140,9 @@ auto ApplyItemSection( CItem *applyTo, CScriptSection *toApply, std::string sect break; case DFNTAG_AC: applyTo->SetArmourClass( static_cast( ndata )); break; case DFNTAG_BASERANGE: applyTo->SetBaseRange( static_cast( ndata )); break; + case DFNTAG_HEALTHBONUS: applyTo->SetHealthBonus( static_cast( ndata )); break; + case DFNTAG_STAMINABONUS: applyTo->SetStaminaBonus( static_cast( ndata )); break; + case DFNTAG_MANABONUS: applyTo->SetManaBonus( static_cast( ndata )); break; case DFNTAG_CREATOR: applyTo->SetCreator( ndata ); break; case DFNTAG_COLOUR: applyTo->SetColour( static_cast( ndata )); break; case DFNTAG_COLOURLIST: applyTo->SetColour( AddRandomColor( cdata )); break; diff --git a/source/ssection.cpp b/source/ssection.cpp index fae41e7a1..8b37b854b 100644 --- a/source/ssection.cpp +++ b/source/ssection.cpp @@ -216,6 +216,9 @@ const UI08 dfnDataTypes[DFNTAG_COUNTOFTAGS] = DFN_STRING, // DFNTAG_SPAWNOBJ, DFN_STRING, // DFNTAG_SPAWNOBJLIST, DFN_NUMERIC, // DFNTAG_SPD, + DFN_NUMERIC, // DFNTAG_HEALTHBONUS, + DFN_NUMERIC, // DFNTAG_STAMINABONUS, + DFN_NUMERIC, // DFNTAG_MANABONUS, DFN_STRING, // DFNTAG_SPELLS, DFN_DOUBLENUMERIC, // DFNTAG_SPELLWEAVING, DFN_DOUBLENUMERIC, // DFNTAG_SPIRITSPEAK, @@ -285,6 +288,9 @@ const std::map strToDFNTag {"BLACKSMITHING"s, DFNTAG_BLACKSMITHING}, {"BOWCRAFT"s, DFNTAG_BOWCRAFT}, {"BUSHIDO"s, DFNTAG_BUSHIDO}, + {"HEALTHBONUS"s, DFNTAG_HEALTHBONUS}, + {"STAMINABONUS"s, DFNTAG_STAMINABONUS}, + {"MANABONUS"s, DFNTAG_MANABONUS}, {"CAMPING"s, DFNTAG_CAMPING}, {"CARPENTRY"s, DFNTAG_CARPENTRY}, {"CARTOGRAPHY"s, DFNTAG_CARTOGRAPHY}, diff --git a/source/ssection.h b/source/ssection.h index c652b9d3b..f7c34b2dd 100644 --- a/source/ssection.h +++ b/source/ssection.h @@ -223,6 +223,9 @@ enum DFNTAGS DFNTAG_SPAWNOBJ, DFNTAG_SPAWNOBJLIST, DFNTAG_SPD, + DFNTAG_HEALTHBONUS, + DFNTAG_STAMINABONUS, + DFNTAG_MANABONUS, DFNTAG_SPELLS, DFNTAG_SPELLWEAVING, DFNTAG_SPIRITSPEAK,