rendered paste bodyIndex: src/game/Pet.cpp===================================================================--- src/game/Pet.cpp (revision 4889)+++ src/game/Pet.cpp (working copy)@@ -306,6 +306,8 @@ _LoadSpellCooldowns(); owner->SetPet(this); // in DB stored only full controlled creature+ if(GetOwnerGUID())+ GetOwner()->_UpdatePetAuras(0, true); sLog.outDebug("New Pet has guid %u", GetGUIDLow()); if(owner->GetTypeId() == TYPEID_PLAYER)Index: src/game/Pet.h===================================================================--- src/game/Pet.h (revision 4889)+++ src/game/Pet.h (working copy)@@ -201,6 +201,7 @@ time_t m_resetTalentsTime; bool m_removed; // prevent overwrite pet state in DB at next Pet::Update if pet already removed(saved)+ bool m_been_banished; // Indicates need to reload auras (like Spirit Bond, Demonic Knowledge) protected: uint32 m_regenTimer; uint32 m_happinessTimer;Index: src/game/Player.cpp===================================================================--- src/game/Player.cpp (revision 4889)+++ src/game/Player.cpp (working copy)@@ -2561,6 +2561,10 @@ CastSpell(this, spell_id, true); } + //update pet based on talents+ if (IsPassiveSpell(spell_id) || GetTalentSpellCost(spell_id))+ _UpdatePetAuras(0, true);+ // update used talent points count m_usedTalentCount += talentCost; Index: src/game/SpellAuras.cpp===================================================================--- src/game/SpellAuras.cpp (revision 4889)+++ src/game/SpellAuras.cpp (working copy)@@ -554,6 +554,12 @@ Group *pGroup = NULL; if (caster->GetTypeId() == TYPEID_PLAYER) pGroup = ((Player*)caster)->GetGroup();+ else if( ((Creature*)caster)->isPet() && isPetAura() )+ {+ Unit *owner = ((Pet*)caster)->GetOwner();+ if(owner && owner->GetTypeId() == TYPEID_PLAYER)+ pGroup = NULL;+ } else if(caster->GetCharmerOrOwnerGUID() != 0) { Unit *owner = caster->GetCharmerOrOwner();@@ -601,6 +607,29 @@ } } }+ else if(((Creature*)caster)->isPet() && ((Pet*)caster)->GetOwnerGUID() && isPetAura())+ {+ Unit *owner = ((Pet*)caster)->GetOwner();+ Aura *petAura = owner->GetAura(m_spellId, m_effIndex);+ if(caster->IsWithinDistInMap(owner, m_radius) && caster->isAlive()) + {+ if(!petAura)+ {+ AreaAura *aur = new AreaAura(GetSpellProto(), m_effIndex, &m_currentBasePoints, owner, caster);+ owner->AddAura(aur);+ }++ // Remove aura if pet is banished+ // Implemented in Unit::_UpdatePetAuras+ }+ else+ {+ if(petAura)+ owner->RemoveAurasDueToSpell(GetSpellProto()->Id);+ }+ if( !caster->IsInWorld() || caster->isDead())+ owner->RemoveAurasDueToSpell(GetSpellProto()->Id);+ } else if (caster->GetCharmerOrOwnerGUID() != 0) { // add / remove auras from the totem's ownerIndex: src/game/SpellAuras.h===================================================================--- src/game/SpellAuras.h (revision 4889)+++ src/game/SpellAuras.h (working copy)@@ -254,6 +254,9 @@ // add/remove SPELL_AURA_MOD_SHAPESHIFT (36) linked auras void HandleShapeshiftBoosts(bool apply);++ bool isPetAura() const { return m_spellProto->Effect[GetEffIndex()] == 119 || m_spellProto->Effect[GetEffIndex()] == 143; }+ protected: Modifier m_modifier; SpellModifier *m_spellmod;Index: src/game/SpellEffects.cpp===================================================================--- src/game/SpellEffects.cpp (revision 4889)+++ src/game/SpellEffects.cpp (working copy)@@ -199,7 +199,7 @@ &Spell::EffectNULL, //140 SPELL_EFFECT_140 &Spell::EffectNULL, //141 SPELL_EFFECT_141 &Spell::EffectNULL, //142 SPELL_EFFECT_142- &Spell::EffectNULL, //143 SPELL_EFFECT_143 probably apply aura again :)+ &Spell::EffectApplyPetAura, //143 SPELL_EFFECT_143 probably apply aura again :) &Spell::EffectNULL, //144 SPELL_EFFECT_144 &Spell::EffectNULL, //145 SPELL_EFFECT_145 &Spell::EffectNULL, //146 SPELL_EFFECT_146@@ -4237,15 +4237,16 @@ void Spell::EffectApplyPetAura(uint32 i) {- //spell aura for both pet and owner, think the pet has the aura and applies it to owner- EffectApplyAura(i);+ if( !((Creature*)m_caster)->isPet() || ( ((Pet*)m_caster)->getPetType() != SUMMON_PET && ((Pet*)m_caster)->getPetType() != HUNTER_PET ) )+ return; - Unit* owner = unitTarget->GetCharmerOrOwner();- if(owner)- {- unitTarget = owner;- EffectApplyAura(i);- }+ if(!((Pet*)m_caster)->GetOwnerGUID() || !((Pet*)m_caster)->GetOwner()->isAlive())+ return;++ AreaAura* Aur = new AreaAura(m_spellInfo, i, m_currentBasePoints, unitTarget, m_caster);+ m_caster->AddAura(Aur);++ return; } void Spell::EffectSummonDemon(uint32 i)Index: src/game/Unit.cpp===================================================================--- src/game/Unit.cpp (revision 4889)+++ src/game/Unit.cpp (working copy)@@ -2803,8 +2803,266 @@ ++dnext1; } }++ _UpdatePetAuras(time); } +void Unit::_UpdatePetAuras( uint32 time, bool refreshAll )+{+ Pet *pet = GetPet();+ if(!pet)+ return;++ bool isBanished = false;++ // Check for banish before update+ // Remove aura if pet is banished+ Unit::AuraList const &mImmunity = pet->GetAurasByType(SPELL_AURA_SCHOOL_IMMUNITY);+ for(Unit::AuraList::const_iterator i = mImmunity.begin(); i != mImmunity.end(); ++i)+ {+ if ((*i)->GetSpellProto()->SpellIconID == 96)+ {+ isBanished = true;+ break;+ }+ }++ if(isBanished)+ {+ pet->_RemovePetAuras();+ pet->RemoveAurasDueToSpell(25228); // Soul Link remove+ pet->m_been_banished = true;+ return;+ }++ // Following code needs to be executed only if we need to refresh pet's passive auras+ if(!refreshAll && !pet->m_been_banished)+ return;++ pet->m_been_banished = false;+ _RemovePetAuras();++ uint32 MD = 0;++ // TODO: Soul Link check+ // Update auras+ Unit::AuraList const &mDummy = GetAurasByType(SPELL_AURA_DUMMY);+ for(Unit::AuraList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr)+ {+ switch((*itr)->GetSpellProto()->Id)+ {+ // Demonic Knowledge+ case 35691:+ case 35692:+ case 35693:+ {+ pet->RemoveAurasDueToSpell(35696);+ int32 totalBonus = (*itr)->GetSpellProto()->EffectBasePoints[(*itr)->GetEffIndex()] + 1;+ totalBonus = int32( totalBonus * (pet->GetStat(STAT_STAMINA) + pet->GetStat(STAT_INTELLECT)) / 100.0f );+ pet->CastCustomSpell(pet, 35696, &totalBonus, 0, 0, true);+ break;+ }++ // Spirit Bond+ case 19578:+ pet->CastSpell(pet, 19579, true);+ break;+ case 20895:+ pet->CastSpell(pet, 24529, true);+ break;++ // Stalker's Ally+ case 28757:+ pet->CastSpell(pet, 28758, true);+ break;++ // Master Demonologist+ case 23785:+ switch(pet->GetEntry())+ {+ case 416: MD = 23759; break; // imp+ case 1860: MD = 23760; break; // voidwalker+ case 1863: MD = 23761; break; // succubus+ case 417: MD = 23762; break; // felhunter+ case 17252: MD = 35702; break; // felguard+ default: break;+ }+ if(MD) pet->CastSpell(pet, MD, true);+ break;+ case 23822:+ switch(pet->GetEntry())+ {+ case 416: MD = 23826; break; // imp+ case 1860: MD = 23841; break; // voidwalker+ case 1863: MD = 23833; break; // succubus+ case 417: MD = 23837; break; // felhunter+ case 17252: MD = 35703; break; // felguard+ default: break;+ }+ if(MD) pet->CastSpell(pet, MD, true);+ break;+ case 23823:+ switch(pet->GetEntry())+ {+ case 416: MD = 23827; break; // imp+ case 1860: MD = 23842; break; // voidwalker+ case 1863: MD = 23834; break; // succubus+ case 417: MD = 23838; break; // felhunter+ case 17252: MD = 35704; break; // felguard+ default: break;+ }+ if(MD) pet->CastSpell(pet, MD, true);+ break;+ case 23824:+ switch(pet->GetEntry())+ {+ case 416: MD = 23828; break; // imp+ case 1860: MD = 23842; break; // voidwalker+ case 1863: MD = 23835; break; // succubus+ case 417: MD = 23839; break; // felhunter+ case 17252: MD = 35705; break; // felguard+ default: break;+ }+ if(MD) pet->CastSpell(pet, MD, true);+ break;+ case 23825:+ switch(pet->GetEntry())+ {+ case 416: MD = 23829; break; // imp+ case 1860: MD = 23844; break; // voidwalker+ case 1863: MD = 23836; break; // succubus+ case 417: MD = 23840; break; // felhunter+ case 17252: MD = 35706; break; // felguard+ default: break;+ }+ if(MD) pet->CastSpell(pet, MD, true);+ break;+ default: break;+ }+ }+++ // Additional auras+ switch(pet->getPetType())+ {+ case HUNTER_PET:+ {+ // Remove first+ pet->RemoveAurasDueToSpell(8875);+ pet->RemoveAurasDueToSpell(19580);+ pet->RemoveAurasDueToSpell(19581);+ pet->RemoveAurasDueToSpell(19582);+ pet->RemoveAurasDueToSpell(19589);+ pet->RemoveAurasDueToSpell(19591);+ pet->RemoveAurasDueToSpell(20784);+ pet->RemoveAurasDueToSpell(34457);+ pet->RemoveAurasDueToSpell(34666);+ pet->RemoveAurasDueToSpell(34667);+ pet->RemoveAurasDueToSpell(34675);+ // Apply passive auras again+ pet->CastSpell(pet, 8875, true); // Damage+ pet->CastSpell(pet, 19580, true); // Armor+ pet->CastSpell(pet, 19581, true); // Health+ pet->CastSpell(pet, 19582, true); // Speed+ pet->CastSpell(pet, 19589, true); // Focus Regeneration+ pet->CastSpell(pet, 19591, true); // Crit and Spell crit chance+ pet->CastSpell(pet, 20784, true); // Chance to proc Frenzy+ pet->CastSpell(pet, 34457, true); // Chance to proc Ferocious inspiration+ pet->CastSpell(pet, 34666, true); // Chance to hit+ pet->CastSpell(pet, 34667, true); // Chance to dodge+ pet->CastSpell(pet, 34675, true); // Attack speed+ } break;+ case SUMMON_PET:+ {+ pet->RemoveAurasDueToSpell(35695);+ pet->RemoveAurasDueToSpell(35697);+ pet->CastSpell(this, 35695, true); // Demonic tactics (%crit+spellcrit)+ pet->CastSpell(this, 35697, true); // Demonic resilience+ switch(pet->GetEntry())+ {+ case 416:+ // Imp+ // Remove first+ pet->RemoveAurasDueToSpell(18728);+ pet->RemoveAurasDueToSpell(18737);+ pet->RemoveAurasDueToSpell(18740);+ // Apply passive auras again+ pet->CastSpell(pet, 18728, true); // All damage caused+ pet->CastSpell(pet, 18737, true); // Stamina+ pet->CastSpell(pet, 18740, true); // Intellect+ break;+ case 1860:+ // Voidwalker+ // Remove first+ pet->RemoveAurasDueToSpell(18727);+ pet->RemoveAurasDueToSpell(18735);+ pet->RemoveAurasDueToSpell(18742);+ // Apply passive auras again+ pet->CastSpell(pet, 18727, true); // All damage caused+ pet->CastSpell(pet, 18735, true); // Stamina+ pet->CastSpell(pet, 18742, true); // Intellect+ break;+ case 1863:+ // Succubus+ // Remove first+ pet->RemoveAurasDueToSpell(18729);+ pet->RemoveAurasDueToSpell(18736);+ pet->RemoveAurasDueToSpell(18741);+ // Apply passive auras again+ pet->CastSpell(pet, 18729, true); // All damage caused+ pet->CastSpell(pet, 18736, true); // Stamina+ pet->CastSpell(pet, 18741, true); // Intellect+ break;+ case 417:+ // Felhunter+ // Remove first+ pet->RemoveAurasDueToSpell(18730);+ pet->RemoveAurasDueToSpell(18738);+ pet->RemoveAurasDueToSpell(18739);+ pet->RemoveAurasDueToSpell(19007);+ // Apply passive auras again+ pet->CastSpell(pet, 18730, true); // All damage caused+ pet->CastSpell(pet, 18738, true); // Stamina+ pet->CastSpell(pet, 18739, true); // Intellect+ pet->CastSpell(pet, 19007, true); // Felhunter Resistances+ break;+ case 17252:+ // Felguard+ // Remove first+ pet->RemoveAurasDueToSpell(30147);+ pet->RemoveAurasDueToSpell(30148);+ pet->RemoveAurasDueToSpell(30149);+ // Apply passive auras again+ pet->CastSpell(pet, 30147, true); // All damage caused+ pet->CastSpell(pet, 30148, true); // Stamina+ pet->CastSpell(pet, 30149, true); // Intellect+ break;+ default: break;+ }+ } break;+ default: break;+ }+}++void Unit::_RemovePetAuras()+{+ Pet *pet = GetPet();+ if(!pet || !pet->isAlive())+ return;++ std::vector<uint32> toRemove;++ AuraList const &mPetAuras119 = pet->GetAurasByType(AuraType(119));+ for(AuraList::const_iterator itr = mPetAuras119.begin(); itr != mPetAuras119.end(); ++itr)+ toRemove.push_back((*itr)->GetId());+ AuraList const &mPetAuras143 = pet->GetAurasByType(AuraType(143));+ for(AuraList::const_iterator itr = mPetAuras143.begin(); itr != mPetAuras143.end(); ++itr)+ toRemove.push_back((*itr)->GetId());++ for(int itr = 0; itr < toRemove.size(); itr++)+ pet->RemoveAurasDueToSpell(itr);+}+ void Unit::_UpdateAutoRepeatSpell( uint32 time ) { if(m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->getState() == SPELL_STATE_FINISHED)Index: src/game/Unit.h===================================================================--- src/game/Unit.h (revision 4889)+++ src/game/Unit.h (working copy)@@ -1182,10 +1182,13 @@ void StartReactiveTimer( ReactiveType reactive ) { m_reactiveTimer[reactive] = REACTIVE_TIMER_START;} void UpdateReactives(uint32 p_time); + void _UpdatePetAuras(uint32 time, bool refreshAll = false);+ protected: explicit Unit ( WorldObject *instantiator ); void _UpdateSpells(uint32 time);+ void _RemovePetAuras(); void _UpdateAutoRepeatSpell(uint32 time); bool m_AutoRepeatFirstCast;