diff --git a/src/game/Player.cpp b/src/game/Player.cpp index e52d947c6..176691bf9 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2200,6 +2200,27 @@ void Player::SetInWater(bool apply) getHostileRefManager().updateThreatTables(); } +struct SetGameMasterOnHelper +{ + explicit SetGameMasterOnHelper() {} + void operator()(Unit* unit) const + { + unit->setFaction(35); + unit->getHostileRefManager().setOnlineOfflineState(false); + } +}; + +struct SetGameMasterOffHelper +{ + explicit SetGameMasterOffHelper(uint32 _faction) : faction(_faction) {} + void operator()(Unit* unit) const + { + unit->setFaction(faction); + unit->getHostileRefManager().setOnlineOfflineState(true); + } + uint32 faction; +}; + void Player::SetGameMaster(bool on) { if(on) @@ -2208,16 +2229,7 @@ void Player::SetGameMaster(bool on) setFaction(35); SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM); - if (Pet* pet = GetPet()) - { - pet->setFaction(35); - pet->getHostileRefManager().setOnlineOfflineState(false); - } - - for (int8 i = 0; i < MAX_TOTEM; ++i) - if(m_TotemSlot[i]) - if(Creature *totem = GetMap()->GetCreature(m_TotemSlot[i])) - totem->setFaction(35); + CallForAllControlledUnits(SetGameMasterOnHelper(),true,true,true,false); RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP); ResetContestedPvP(); @@ -2237,16 +2249,7 @@ void Player::SetGameMaster(bool on) setFactionForRace(getRace()); RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM); - if (Pet* pet = GetPet()) - { - pet->setFaction(getFaction()); - pet->getHostileRefManager().setOnlineOfflineState(true); - } - - for (int8 i = 0; i < MAX_TOTEM; ++i) - if(m_TotemSlot[i]) - if(Creature *totem = GetMap()->GetCreature(m_TotemSlot[i])) - totem->setFaction(getFaction()); + CallForAllControlledUnits(SetGameMasterOffHelper(getFaction()),true,true,true,false); // restore FFA PvP Server state if(sWorld.IsFFAPvPRealm()) diff --git a/src/game/Player.h b/src/game/Player.h index 44a3bcb9d..969539d6b 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1164,6 +1164,13 @@ class MANGOS_DLL_SPEC Player : public Unit void RemoveMiniPet(); Pet* GetMiniPet(); void SetMiniPet(Pet* pet) { m_miniPet = pet->GetGUID(); } + + template + void CallForAllControlledUnits(Func const& func, bool withTotems, bool withGuardians, bool withCharms, bool withMiniPet); + template + bool CheckAllControlledUnits(Func const& func, bool withTotems, bool withGuardians, bool withCharms, bool withMiniPet) const; + + uint32 GetPhaseMaskForSpawn() const; // used for proper set phase for DB at GM-mode creature/GO spawn void Say(const std::string& text, const uint32 language); @@ -2635,4 +2642,27 @@ template T Player::ApplySpellMod(uint32 spellId, SpellModOp op, T &bas basevalue = T((float)basevalue + diff); return T(diff); } + +template +void Player::CallForAllControlledUnits(Func const& func, bool withTotems, bool withGuardians, bool withCharms, bool withMiniPet) +{ + if (withMiniPet) + if(Unit* mini = GetMiniPet()) + func(mini); + + Unit::CallForAllControlledUnits(func,withTotems,withGuardians,withCharms); +} + +template +bool Player::CheckAllControlledUnits(Func const& func, bool withTotems, bool withGuardians, bool withCharms, bool withMiniPet) const +{ + if (withMiniPet) + if(Unit* mini = GetMiniPet()) + if (func(mini)) + return true; + + return Unit::CheckAllControlledUnits(func,withTotems,withGuardians,withCharms); +} + + #endif diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index dcb9c6043..30f2d9322 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -1379,6 +1379,13 @@ void Aura::ReapplyAffectedPassiveAuras( Unit* target, bool owner_mode ) /*********************************************************/ /*** BASIC AURA FUNCTION ***/ /*********************************************************/ +struct AuraHandleAddModifierHelper +{ + explicit AuraHandleAddModifierHelper(Aura* _aura) : aura(_aura) {} + void operator()(Unit* unit) const { aura->ReapplyAffectedPassiveAuras(unit, true); } + Aura* aura; +}; + void Aura::HandleAddModifier(bool apply, bool Real) { if(m_target->GetTypeId() != TYPEID_PLAYER || !Real) @@ -1422,15 +1429,8 @@ void Aura::HandleAddModifier(bool apply, bool Real) // reapply talents to own passive persistent auras ReapplyAffectedPassiveAuras(m_target, true); - // re-apply talents/passives/area auras applied to pet (it affected by player spellmods) - if(Pet* pet = m_target->GetPet()) - ReapplyAffectedPassiveAuras(pet, true); - - // re-apply talents/passives/area auras applied to totems (it affected by player spellmods) - for(int i = 0; i < MAX_TOTEM; ++i) - if(m_target->m_TotemSlot[i]) - if(Creature* totem = m_target->GetMap()->GetCreature(m_target->m_TotemSlot[i])) - ReapplyAffectedPassiveAuras(totem, true); + // re-apply talents/passives/area auras applied to pet/totems (it affected by player spellmods) + m_target->CallForAllControlledUnits(AuraHandleAddModifierHelper(this),true,false,false); // re-apply talents/passives/area auras applied to group members (it affected by player spellmods) if (Group* group = ((Player*)m_target)->GetGroup()) diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index 75324d13f..b11fa5c57 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -36,6 +36,9 @@ struct ProcTriggerSpell; // forward decl class Aura; +// internal helper +struct AuraHandleAddModifierHelper; + typedef void(Aura::*pAuraHandler)(bool Apply, bool Real); // Real == true at aura add/remove // Real == false at aura mod unapply/reapply; when adding/removing dependent aura/item/stat mods @@ -52,6 +55,7 @@ typedef void(Aura::*pAuraHandler)(bool Apply, bool Real); class MANGOS_DLL_SPEC Aura { + friend struct AuraHandleAddModifierHelper; friend Aura* CreateAura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem); public: diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index b81e8dba5..a367fee6b 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -8199,43 +8199,31 @@ void Unit::CombatStop(bool includingCast) ClearInCombat(); } +struct CombatStopWithPetsHelper +{ + explicit CombatStopWithPetsHelper(bool _includingCast) : includingCast(_includingCast) {} + void operator()(Unit* unit) const { unit->CombatStop(includingCast); } + bool includingCast; +}; + void Unit::CombatStopWithPets(bool includingCast) { CombatStop(includingCast); - if(Pet* pet = GetPet()) - pet->CombatStop(includingCast); - if(Unit* charm = GetCharm()) - charm->CombatStop(includingCast); - - for(GuardianPetList::const_iterator itr = m_guardianPets.begin(); itr != m_guardianPets.end(); ++itr) - if(Unit* guardian = Unit::GetUnit(*this,*itr)) - guardian->CombatStop(includingCast); + CallForAllControlledUnits(CombatStopWithPetsHelper(includingCast),false,true,true); } +struct IsAttackingPlayerHelper +{ + explicit IsAttackingPlayerHelper() {} + bool operator()(Unit* unit) const { return unit->isAttackingPlayer(); } +}; + bool Unit::isAttackingPlayer() const { if(hasUnitState(UNIT_STAT_ATTACK_PLAYER)) return true; - Pet* pet = GetPet(); - if(pet && pet->isAttackingPlayer()) - return true; - - Unit* charmed = GetCharm(); - if(charmed && charmed->isAttackingPlayer()) - return true; - - for (int8 i = 0; i < MAX_TOTEM; ++i) - { - if(m_TotemSlot[i]) - { - Creature *totem = GetMap()->GetCreature(m_TotemSlot[i]); - if(totem && totem->isAttackingPlayer()) - return true; - } - } - - return false; + return CheckAllControlledUnits(IsAttackingPlayerHelper(),true,true,true); } void Unit::RemoveAllAttackers() @@ -11063,7 +11051,7 @@ void Unit::ApplyDiminishingAura( DiminishingGroup group, bool apply ) } } -Unit* Unit::GetUnit(WorldObject& object, uint64 guid) +Unit* Unit::GetUnit(WorldObject const& object, uint64 guid) { return ObjectAccessor::GetUnit(object,guid); } @@ -12980,6 +12968,13 @@ void Unit::NearTeleportTo( float x, float y, float z, float orientation, bool ca } } +struct SetPvPHelper +{ + explicit SetPvPHelper(bool _state) : state(_state) {} + void operator()(Unit* unit) const { unit->SetPvP(state); } + bool state; +}; + void Unit::SetPvP( bool state ) { if(state) @@ -12987,15 +12982,7 @@ void Unit::SetPvP( bool state ) else RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); - if(Pet* pet = GetPet()) - pet->SetPvP(state); - if(Unit* charmed = GetCharm()) - charmed->SetPvP(state); - - for (int8 i = 0; i < MAX_TOTEM; ++i) - if(m_TotemSlot[i]) - if(Creature *totem = GetMap()->GetCreature(m_TotemSlot[i])) - totem->SetPvP(state); + CallForAllControlledUnits(SetPvPHelper(state),true,true,true); } void Unit::KnockBackFrom(Unit* target, float horizintalSpeed, float verticalSpeed) @@ -13119,6 +13106,13 @@ void Unit::SendThreatRemove(HostileReference* pHostileReference) SendMessageToSet(&data, false); } +struct StopAttackFactionHelper +{ + explicit StopAttackFactionHelper(uint32 _faction_id) : faction_id(_faction_id) {} + void operator()(Unit* unit) const { unit->StopAttackFaction(faction_id); } + uint32 faction_id; +}; + void Unit::StopAttackFaction(uint32 faction_id) { if (Unit* victim = getVictim()) @@ -13149,14 +13143,7 @@ void Unit::StopAttackFaction(uint32 faction_id) getHostileRefManager().deleteReferencesForFaction(faction_id); - if(Pet* pet = GetPet()) - pet->StopAttackFaction(faction_id); - if(Unit* charm = GetCharm()) - charm->StopAttackFaction(faction_id); - - for(GuardianPetList::const_iterator itr = m_guardianPets.begin(); itr != m_guardianPets.end(); ++itr) - if(Unit* guardian = Unit::GetUnit(*this,*itr)) - guardian->StopAttackFaction(faction_id); + CallForAllControlledUnits(StopAttackFactionHelper(faction_id),false,true,true); } void Unit::CleanupDeletedAuras() diff --git a/src/game/Unit.h b/src/game/Unit.h index 56a80343c..b789ac8d3 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1240,6 +1240,11 @@ class MANGOS_DLL_SPEC Unit : public WorldObject Pet* CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id = 0); + template + void CallForAllControlledUnits(Func const& func, bool withTotems, bool withGuardians, bool withCharms); + template + bool CheckAllControlledUnits(Func const& func, bool withTotems, bool withGuardians, bool withCharms) const; + bool AddAura(Aura *aur); // removing specific aura stack @@ -1535,7 +1540,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void addFollower(FollowerReference* pRef) { m_FollowingRefManager.insertFirst(pRef); } void removeFollower(FollowerReference* /*pRef*/ ) { /* nothing to do yet */ } - static Unit* GetUnit(WorldObject& object, uint64 guid); + static Unit* GetUnit(WorldObject const& object, uint64 guid); MotionMaster* GetMotionMaster() { return &i_motionMaster; } @@ -1657,4 +1662,64 @@ class MANGOS_DLL_SPEC Unit : public WorldObject GuardianPetList m_guardianPets; }; + +template +void Unit::CallForAllControlledUnits(Func const& func, bool withTotems, bool withGuardians, bool withCharms) +{ + if(Pet* pet = GetPet()) + func(pet); + + if (withGuardians) + { + for(GuardianPetList::const_iterator itr = m_guardianPets.begin(); itr != m_guardianPets.end(); ++itr) + if(Unit* guardian = Unit::GetUnit(*this,*itr)) + func(guardian); + } + + if (withTotems) + { + for (int8 i = 0; i < MAX_TOTEM; ++i) + if(m_TotemSlot[i]) + if(Creature *totem = GetMap()->GetCreature(m_TotemSlot[i])) + func(totem); + } + + if (withCharms) + if(Unit* charm = GetCharm()) + func(charm); +} + + +template +bool Unit::CheckAllControlledUnits(Func const& func, bool withTotems, bool withGuardians, bool withCharms) const +{ + if (Pet* pet = GetPet()) + if (func(pet)) + return true; + + if (withGuardians) + { + for(GuardianPetList::const_iterator itr = m_guardianPets.begin(); itr != m_guardianPets.end(); ++itr) + if (Unit* guardian = Unit::GetUnit(*this,*itr)) + if (func(guardian)) + return true; + + } + + if (withTotems) + { + for (int8 i = 0; i < MAX_TOTEM; ++i) + if (m_TotemSlot[i]) + if (Creature *totem = GetMap()->GetCreature(m_TotemSlot[i])) + if (func(totem)) + return true; + } + + if (withCharms) + if(Unit* charm = GetCharm()) + if (func(charm)) + return true; + + return false; +} #endif diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index b38533ab1..f1b3d446d 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "9185" + #define REVISION_NR "9186" #endif // __REVISION_NR_H__