rendered paste bodyIndex: src/game/Chat.cpp===================================================================--- src/game/Chat.cpp (revision 6488)+++ src/game/Chat.cpp (working copy)@@ -219,6 +219,7 @@ { "spell_chain", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellChainCommand, "", NULL }, { "spell_elixir", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellElixirCommand, "", NULL }, { "spell_learn_spell", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellLearnSpellCommand, "", NULL },+ { "spell_pet_auras", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellPetAurasCommand, "", NULL }, { "spell_proc_event", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellProcEventCommand, "", NULL }, { "spell_script_target", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellScriptTargetCommand, "", NULL }, { "spell_scripts", SEC_ADMINISTRATOR, &ChatHandler::HandleReloadSpellScriptsCommand, "", NULL },Index: src/game/Chat.h===================================================================--- src/game/Chat.h (revision 6488)+++ src/game/Chat.h (working copy)@@ -191,6 +191,7 @@ bool HandleReloadSpellScriptsCommand(const char* args); bool HandleReloadSpellTargetPositionCommand(const char* args); bool HandleReloadSpellThreatsCommand(const char* args);+ bool HandleReloadSpellPetAurasCommand(const char* args); bool HandleReloadPageTextsCommand(const char* args); bool HandleReloadItemEnchantementsCommand(const char* args); Index: src/game/Level3.cpp===================================================================--- src/game/Level3.cpp (revision 6488)+++ src/game/Level3.cpp (working copy)@@ -133,6 +133,7 @@ HandleReloadSpellScriptTargetCommand("a"); HandleReloadSpellTargetPositionCommand("a"); HandleReloadSpellThreatsCommand("a");+ HandleReloadSpellPetAurasCommand("a"); return true; } @@ -390,6 +391,14 @@ return true; } +bool ChatHandler::HandleReloadSpellPetAurasCommand(const char*)+{+ sLog.outString( "Re-Loading Spell pet auras...");+ spellmgr.LoadSpellPetAuras();+ SendGlobalSysMessage("DB table `spell_pet_auras` reloaded.");+ return true;+}+ bool ChatHandler::HandleReloadPageTextsCommand(const char*) { sLog.outString( "Re-Loading Page Texts..." );Index: src/game/Pet.cpp===================================================================--- src/game/Pet.cpp (revision 6488)+++ src/game/Pet.cpp (working copy)@@ -316,6 +316,7 @@ else { LearnPetPassives();+ CastPetAuras(); } if(getPetType() == SUMMON_PET && !current) //all (?) summon pets come with full health when called, but not when they are current@@ -514,7 +515,10 @@ } } else if(getDeathState()==ALIVE)+ { RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE);+ CastPetAuras();+ } } void Pet::Update(uint32 diff)@@ -1366,11 +1370,13 @@ AuraMap const& auras = GetAuras(); for(AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) {- // skip all auras from spell that apply at cast SPELL_AURA_MOD_SHAPESHIFT or SPELL_AURA_MOD_STEALTH auras.+ // skip all auras from spell that apply at cast SPELL_AURA_MOD_SHAPESHIFT or pet area auras. SpellEntry const *spellInfo = itr->second->GetSpellProto(); uint8 i; for (i = 0; i < 3; i++)- if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_STEALTH)+ if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_STEALTH ||+ spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_OWNER ||+ spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PET ) break; if (i == 3 && !itr->second->IsPassive())@@ -1570,6 +1576,8 @@ LearnPetPassives(); + CastPetAuras();+ SetTP(-usedtrainpoints); } @@ -1690,3 +1698,21 @@ addSpell(*petSet); } }++void Pet::CastPetAuras()+{+ Unit* owner = GetOwner();+ if(!owner)+ return;++ if(getPetType() != HUNTER_PET && (getPetType() != SUMMON_PET || owner->getClass() != CLASS_WARLOCK))+ return;++ for(std::list<PetAura const*>::iterator itr = owner->m_petAuras.begin(); itr != owner->m_petAuras.end(); ++itr)+ {+ if(uint16 aura = (*itr)->GetAura(GetEntry()))+ {+ CastSpell(this, aura, true);+ }+ }+}Index: src/game/Pet.h===================================================================--- src/game/Pet.h (revision 6488)+++ src/game/Pet.h (working copy)@@ -176,6 +176,7 @@ void AddTeachSpell(uint32 learned_id, uint32 source_id) { m_teachspells[learned_id] = source_id; } void LearnPetPassives();+ void CastPetAuras(); void _LoadSpellCooldowns(); void _SaveSpellCooldowns();Index: src/game/SpellAuras.cpp===================================================================--- src/game/SpellAuras.cpp (revision 6488)+++ src/game/SpellAuras.cpp (working copy)@@ -2174,6 +2174,24 @@ break; } }++ // pet auras+ if(PetAura const* petSpell = spellmgr.GetPetAura(GetId()))+ {+ if(apply)+ {+ m_target->m_petAuras.push_back(petSpell);+ if(Pet* pet = m_target->GetPet())+ pet->CastSpell(pet, petSpell->GetAura(pet->GetEntry()), true);+ }+ else+ {+ m_target->m_petAuras.remove(petSpell);+ if(Pet* pet = m_target->GetPet())+ pet->RemoveAurasDueToSpell(petSpell->GetAura(pet->GetEntry()));+ }+ return;+ } } void Aura::HandleAuraPeriodicDummy(bool apply, bool Real)Index: src/game/SpellMgr.cpp===================================================================--- src/game/SpellMgr.cpp (revision 6488)+++ src/game/SpellMgr.cpp (working copy)@@ -1808,6 +1808,88 @@ sLog.outString(">> Loaded %u Spell Script Targets", count); } +void SpellMgr::LoadSpellPetAuras()+{+ mSpellPetAuraMap.clear(); // need for reload case++ uint32 count = 0;++ // 0 1 2+ QueryResult *result = WorldDatabase.Query("SELECT spell, pet, aura FROM spell_pet_auras");+ if( !result )+ {++ barGoLink bar( 1 );++ bar.step();++ sLog.outString();+ sLog.outString( ">> Loaded %u spell pet auras", count );+ return;+ }++ barGoLink bar( result->GetRowCount() );++ do+ {+ Field *fields = result->Fetch();++ bar.step();++ uint16 spell = fields[0].GetUInt16();+ uint16 pet = fields[1].GetUInt16();+ uint16 aura = fields[2].GetUInt16();++ SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);+ if (!spellInfo)+ {+ sLog.outErrorDb("Spell %u listed in `spell_pet_auras` does not exist", spell);+ continue;+ }+ bool foundDummy = false;+ for(int i = 0; i < 3; ++i)+ {+ if( spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA &&+ spellInfo->EffectApplyAuraName[i] == SPELL_AURA_DUMMY )+ {+ foundDummy = true;+ break;+ }+ }+ if(!foundDummy)+ {+ sLog.outError("Spell %u listed in `spell_pet_auras` does not have dummy aura", spell); + continue;+ }++ SpellEntry const* spellInfo2 = sSpellStore.LookupEntry(aura);+ if (!spellInfo2)+ {+ sLog.outErrorDb("Aura %u listed in `spell_pet_auras` does not exist", aura);+ continue;+ }++ SpellPetAuraMap::iterator itr = mSpellPetAuraMap.find(spell);+ if(itr != mSpellPetAuraMap.end())+ {+ itr->second.auras[pet] = aura;+ }+ else+ {+ PetAura pa;+ pa.auras[pet] = aura;+ mSpellPetAuraMap[spell] = pa;+ }+ + ++count;+ } while( result->NextRow() );++ delete result;++ sLog.outString();+ sLog.outString( ">> Loaded %u spell pet auras", count );+}+ /// Some checks for spells, to prevent adding depricated/broken spells for trainers, spell book, etc bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg) {Index: src/game/SpellMgr.h===================================================================--- src/game/SpellMgr.h (revision 6488)+++ src/game/SpellMgr.h (working copy)@@ -524,6 +524,28 @@ typedef HM_NAMESPACE::hash_map<uint32, SpellTargetPosition> SpellTargetPositionMap; +// Spell pet auras+class PetAura+{+ public:+ std::map<uint16, uint16> auras;+ uint16 GetAura(uint16 petEntry) const+ {+ std::map<uint16, uint16>::const_iterator itr = auras.find(petEntry);+ if(itr != auras.end())+ return itr->second;+ else+ {+ std::map<uint16, uint16>::const_iterator itr = auras.find(0);+ if(itr != auras.end())+ return itr->second;+ else+ return 0;+ }+ }+};+typedef std::map<uint16, PetAura> SpellPetAuraMap;+ // Spell rank chain (accessed using SpellMgr functions) struct SpellChainNode {@@ -755,6 +777,15 @@ return mSkillLineAbilityMap.upper_bound(spell_id); } + PetAura const* GetPetAura(uint16 spell_id)+ {+ SpellPetAuraMap::const_iterator itr = mSpellPetAuraMap.find(spell_id);+ if(itr != mSpellPetAuraMap.end())+ return &itr->second;+ else+ return NULL;+ }+ // Modifiers public: static SpellMgr& Instance();@@ -770,6 +801,7 @@ void LoadSpellTargetPositions(); void LoadSpellThreats(); void LoadSkillLineAbilityMap();+ void LoadSpellPetAuras(); private: SpellScriptTarget mSpellScriptTarget;@@ -782,6 +814,7 @@ SpellElixirMap mSpellElixirs; SpellProcEventMap mSpellProcEventMap; SkillLineAbilityMap mSkillLineAbilityMap;+ SpellPetAuraMap mSpellPetAuraMap; }; #define spellmgr SpellMgr::Instance()Index: src/game/Unit.h===================================================================--- src/game/Unit.h (revision 6488)+++ src/game/Unit.h (working copy)@@ -234,6 +234,7 @@ class Item; class Pet; class Path;+class PetAura; struct SpellImmune {@@ -1208,6 +1209,8 @@ // group updates void UpdateAuraForGroup(uint8 slot); + std::list<PetAura const*> m_petAuras;+ protected: explicit Unit (); Index: src/game/World.cpp===================================================================--- src/game/World.cpp (revision 6488)+++ src/game/World.cpp (working copy)@@ -841,6 +841,9 @@ sLog.outString( "Loading SpellAffect definitions..." ); spellmgr.LoadSpellAffects(); + sLog.outString( "Loading spell pet auras..." );+ spellmgr.LoadSpellPetAuras();+ sLog.outString( "Loading player Create Info & Level Stats..." ); objmgr.LoadPlayerInfo();