diff --git a/src/common/Dynamic/TypeContainerVisitor.h b/src/common/Dynamic/TypeContainerVisitor.h index f593f3b5d..cab848b4b 100644 --- a/src/common/Dynamic/TypeContainerVisitor.h +++ b/src/common/Dynamic/TypeContainerVisitor.h @@ -74,17 +74,17 @@ void VisitorHelper(VISITOR& v, ContainerUnorderedMap, KEY_TYPE>& VisitorHelper(v, c._TailElements); } -template +template void VisitorHelper(VISITOR& v, TypeUnorderedMapContainer& c) { VisitorHelper(v, c.GetElements()); } -template +template class TypeContainerVisitor { public: - TypeContainerVisitor(VISITOR& v) : i_visitor(v) {} + TypeContainerVisitor(VISITOR& v) : i_visitor(v) { } void Visit(TYPE_CONTAINER& c) { diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index a2a4ff585..3945a0eae 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -640,11 +640,6 @@ ConditionMgr::~ConditionMgr() Clean(); } -bool ConditionMgr::IsSpellUsedInSpellClickConditions(uint32 spellId) const -{ - return SpellsUsedInSpellClickConditions.find(spellId) != SpellsUsedInSpellClickConditions.end(); -} - ConditionMgr* ConditionMgr::instance() { static ConditionMgr instance; @@ -699,7 +694,7 @@ uint32 ConditionMgr::GetSearcherTypeMaskForConditionList(ConditionList const& co return mask; } -bool ConditionMgr::IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionList const& conditions) const +bool ConditionMgr::IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionList const& conditions) { // groupId, groupCheckPassed std::map ElseGroupStore; @@ -743,19 +738,19 @@ bool ConditionMgr::IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, return false; } -bool ConditionMgr::IsObjectMeetToConditions(WorldObject* object, ConditionList const& conditions) const +bool ConditionMgr::IsObjectMeetToConditions(WorldObject* object, ConditionList const& conditions) { ConditionSourceInfo srcInfo = ConditionSourceInfo(object); return IsObjectMeetToConditions(srcInfo, conditions); } -bool ConditionMgr::IsObjectMeetToConditions(WorldObject* object1, WorldObject* object2, ConditionList const& conditions) const +bool ConditionMgr::IsObjectMeetToConditions(WorldObject* object1, WorldObject* object2, ConditionList const& conditions) { ConditionSourceInfo srcInfo = ConditionSourceInfo(object1, object2); return IsObjectMeetToConditions(srcInfo, conditions); } -bool ConditionMgr::IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, ConditionList const& conditions) const +bool ConditionMgr::IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, ConditionList const& conditions) { if (conditions.empty()) return true; @@ -1060,10 +1055,6 @@ void ConditionMgr::LoadConditions(bool isReload) case CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT: { SpellClickEventConditionStore[cond->SourceGroup][cond->SourceEntry].push_back(cond); - if (cond->ConditionType == CONDITION_AURA) - { - SpellsUsedInSpellClickConditions.insert(cond->ConditionValue1); - } valid = true; ++count; continue; // do not add to m_AllocatedMemory to avoid double deleting @@ -1132,10 +1123,6 @@ void ConditionMgr::LoadConditions(bool isReload) } // add new Condition to storage based on Type/Entry - if (cond->SourceType == CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT && cond->ConditionType == CONDITION_AURA) - { - SpellsUsedInSpellClickConditions.insert(cond->ConditionValue1); - } ConditionStore[cond->SourceType][cond->SourceEntry].push_back(cond); ++count; } while (result->NextRow()); @@ -2327,7 +2314,7 @@ void ConditionMgr::Clean() itr->second.clear(); } - SpellsUsedInSpellClickConditions.clear(); + SpellClickEventConditionStore.clear(); for (NpcVendorConditionContainer::iterator itr = NpcVendorConditionContainerStore.begin(); itr != NpcVendorConditionContainerStore.end(); ++itr) { diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index ce68f0b33..d3989dfeb 100644 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -22,10 +22,7 @@ #include "Errors.h" #include #include -#include -#include -class Creature; class Player; class Unit; class WorldObject; @@ -257,9 +254,9 @@ public: ConditionList GetConditionReferences(uint32 refId); uint32 GetSearcherTypeMaskForConditionList(ConditionList const& conditions); - bool IsObjectMeetToConditions(WorldObject* object, ConditionList const& conditions) const; - bool IsObjectMeetToConditions(WorldObject* object1, WorldObject* object2, ConditionList const& conditions) const; - bool IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, ConditionList const& conditions) const; + bool IsObjectMeetToConditions(WorldObject* object, ConditionList const& conditions); + bool IsObjectMeetToConditions(WorldObject* object1, WorldObject* object2, ConditionList const& conditions); + bool IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, ConditionList const& conditions); [[nodiscard]] bool CanHaveSourceGroupSet(ConditionSourceType sourceType) const; [[nodiscard]] bool CanHaveSourceIdSet(ConditionSourceType sourceType) const; ConditionList GetConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry); @@ -267,7 +264,6 @@ public: ConditionList GetConditionsForSmartEvent(int32 entryOrGuid, uint32 eventId, uint32 sourceType); ConditionList GetConditionsForVehicleSpell(uint32 creatureId, uint32 spellId); ConditionList GetConditionsForNpcVendorEvent(uint32 creatureId, uint32 itemId); - bool IsSpellUsedInSpellClickConditions(uint32 spellId) const; private: bool isSourceTypeValid(Condition* cond); @@ -275,7 +271,7 @@ private: bool addToGossipMenus(Condition* cond); bool addToGossipMenuItems(Condition* cond); bool addToSpellImplicitTargetConditions(Condition* cond); - bool IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionList const& conditions) const; + bool IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionList const& conditions); void Clean(); // free up resources std::list AllocatedMemoryStore; // some garbage collection :) @@ -286,8 +282,6 @@ private: CreatureSpellConditionContainer SpellClickEventConditionStore; NpcVendorConditionContainer NpcVendorConditionContainerStore; SmartEventConditionContainer SmartEventConditionStore; - - std::unordered_set SpellsUsedInSpellClickConditions; }; #define sConditionMgr ConditionMgr::instance() diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 994a393c7..690983189 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1473,7 +1473,7 @@ public: [[nodiscard]] bool HasQuestForItem(uint32 itemId, uint32 excludeQuestId = 0, bool turnIn = false, bool* showInLoot = nullptr) const; [[nodiscard]] bool HasQuestForGO(int32 GOId) const; [[nodiscard]] bool HasQuest(uint32 questId) const; - void UpdateVisibleGameobjectsOrSpellClicks(); + void UpdateForQuestWorldObjects(); [[nodiscard]] bool CanShareQuest(uint32 quest_id) const; void SendQuestComplete(uint32 quest_id); diff --git a/src/server/game/Entities/Player/PlayerQuest.cpp b/src/server/game/Entities/Player/PlayerQuest.cpp index b1271c008..2c5ccff18 100644 --- a/src/server/game/Entities/Player/PlayerQuest.cpp +++ b/src/server/game/Entities/Player/PlayerQuest.cpp @@ -1548,7 +1548,7 @@ void Player::SendQuestUpdate(uint32 questId) RemoveAurasDueToSpell(oldSpellId); } - UpdateVisibleGameobjectsOrSpellClicks(); + UpdateForQuestWorldObjects(); } QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver) @@ -1809,7 +1809,7 @@ void Player::ItemAddedQuestCheck(uint32 entry, uint32 count) } } } - UpdateVisibleGameobjectsOrSpellClicks(); + UpdateForQuestWorldObjects(); } void Player::ItemRemovedQuestCheck(uint32 entry, uint32 count) @@ -1850,7 +1850,7 @@ void Player::ItemRemovedQuestCheck(uint32 entry, uint32 count) } } } - UpdateVisibleGameobjectsOrSpellClicks(); + UpdateForQuestWorldObjects(); } void Player::KilledMonster(CreatureTemplate const* cInfo, ObjectGuid guid) diff --git a/src/server/game/Entities/Player/PlayerStorage.cpp b/src/server/game/Entities/Player/PlayerStorage.cpp index 0a9cb59e5..43517b3f8 100644 --- a/src/server/game/Entities/Player/PlayerStorage.cpp +++ b/src/server/game/Entities/Player/PlayerStorage.cpp @@ -2848,7 +2848,7 @@ Item* Player::EquipItem(uint16 pos, Item* pItem, bool update) UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM, pItem->GetEntry(), slot); sScriptMgr->OnEquip(this, pItem, bag, slot, update); - UpdateVisibleGameobjectsOrSpellClicks(); + UpdateForQuestWorldObjects(); return pItem; } diff --git a/src/server/game/Entities/Player/PlayerUpdates.cpp b/src/server/game/Entities/Player/PlayerUpdates.cpp index 0a70bc5e1..9477c6007 100644 --- a/src/server/game/Entities/Player/PlayerUpdates.cpp +++ b/src/server/game/Entities/Player/PlayerUpdates.cpp @@ -1829,7 +1829,7 @@ void Player::UpdateTriggerVisibility() GetSession()->SendPacket(&packet); } -void Player::UpdateVisibleGameobjectsOrSpellClicks() +void Player::UpdateForQuestWorldObjects() { if (m_clientGUIDs.empty()) return; @@ -1856,9 +1856,19 @@ void Player::UpdateVisibleGameobjectsOrSpellClicks() SpellClickInfoMapBounds clickPair = sObjectMgr->GetSpellClickInfoMapBounds(obj->GetEntry()); for (SpellClickInfoContainer::const_iterator _itr = clickPair.first; _itr != clickPair.second; ++_itr) { + //! This code doesn't look right, but it was logically converted to condition system to do the exact + //! same thing it did before. It definitely needs to be overlooked for intended functionality. ConditionList conds = sConditionMgr->GetConditionsForSpellClickEvent(obj->GetEntry(), _itr->second.spellId); - obj->BuildValuesUpdateBlockForPlayer(&udata, this); - break; + bool buildUpdateBlock = false; + for (ConditionList::const_iterator jtr = conds.begin(); jtr != conds.end() && !buildUpdateBlock; ++jtr) + if ((*jtr)->ConditionType == CONDITION_QUESTREWARDED || (*jtr)->ConditionType == CONDITION_QUESTTAKEN) + buildUpdateBlock = true; + + if (buildUpdateBlock) + { + obj->BuildValuesUpdateBlockForPlayer(&udata, this); + break; + } } } } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 341a0f4d9..b5624ec5a 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -4081,14 +4081,6 @@ void Unit::_ApplyAura(AuraApplication* aurApp, uint8 effMask) if (effMask & 1 << i && (!aurApp->GetRemoveMode())) aurApp->_HandleEffect(i, true); } - - if (Player* player = ToPlayer()) - { - if (sConditionMgr->IsSpellUsedInSpellClickConditions(aurApp->GetBase()->GetId())) - { - player->UpdateVisibleGameobjectsOrSpellClicks(); - } - } } // removes aura application from lists and unapplies effects @@ -4167,14 +4159,6 @@ void Unit::_UnapplyAura(AuraApplicationMap::iterator& i, AuraRemoveMode removeMo aura->HandleAuraSpecificMods(aurApp, caster, false, false); - if (Player* player = ToPlayer()) - { - if (sConditionMgr->IsSpellUsedInSpellClickConditions(aurApp->GetBase()->GetId())) - { - player->UpdateVisibleGameobjectsOrSpellClicks(); - } - } - // only way correctly remove all auras from list //if (removedAuras != m_removedAurasCount) new aura may be added i = m_appliedAuras.begin(); diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index 2b5ac506a..540d49112 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -165,29 +165,6 @@ namespace Acore // WorldObject searchers & workers - // Generic base class to insert elements into arbitrary containers using push_back - template class ContainerInserter - { - using InserterType = void (*)(void*, Type&&); - - void* ref; - InserterType inserter; - - // MSVC workaround - template static void InserterOf(void* ref, Type&& type) - { - static_cast(ref)->push_back(std::move(type)); - } - - protected: - template ContainerInserter(T& ref_) : ref(&ref_), inserter(&InserterOf) {} - - void Insert(Type type) - { - inserter(ref, std::move(type)); - } - }; - template struct WorldObjectSearcher { @@ -229,15 +206,15 @@ namespace Acore }; template - struct WorldObjectListSearcher : ContainerInserter + struct WorldObjectListSearcher { uint32 i_mapTypeMask; uint32 i_phaseMask; + std::list& i_objects; Check& i_check; - template WorldObjectListSearcher(WorldObject const* searcher, Container& container, Check& check, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL) - : ContainerInserter(container), - i_mapTypeMask(mapTypeMask), i_phaseMask(searcher->GetPhaseMask()), i_check(check) {} + WorldObjectListSearcher(WorldObject const* searcher, std::list& objects, Check& check, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL) + : i_mapTypeMask(mapTypeMask), i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) {} void Visit(PlayerMapType& m); void Visit(CreatureMapType& m); @@ -339,14 +316,14 @@ namespace Acore }; template - struct GameObjectListSearcher : ContainerInserter + struct GameObjectListSearcher { uint32 i_phaseMask; + std::list& i_objects; Check& i_check; - template GameObjectListSearcher(WorldObject const* searcher, Container& container, Check& check) - : ContainerInserter(container), - i_phaseMask(searcher->GetPhaseMask()), i_check(check) {} + GameObjectListSearcher(WorldObject const* searcher, std::list& objects, Check& check) + : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) {} void Visit(GameObjectMapType& m); @@ -411,14 +388,14 @@ namespace Acore // All accepted by Check units if any template - struct UnitListSearcher : ContainerInserter + struct UnitListSearcher { uint32 i_phaseMask; + std::list& i_objects; Check& i_check; - template UnitListSearcher(WorldObject const* searcher, Container& container, Check& check) - : ContainerInserter(container), - i_phaseMask(searcher->GetPhaseMask()), i_check(check) {} + UnitListSearcher(WorldObject const* searcher, std::list& objects, Check& check) + : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) {} void Visit(PlayerMapType& m); void Visit(CreatureMapType& m); @@ -460,14 +437,14 @@ namespace Acore }; template - struct CreatureListSearcher : ContainerInserter + struct CreatureListSearcher { uint32 i_phaseMask; + std::list& i_objects; Check& i_check; - template CreatureListSearcher(WorldObject const* searcher, Container& container, Check& check) - : ContainerInserter(container), - i_phaseMask(searcher->GetPhaseMask()), i_check(check) {} + CreatureListSearcher(WorldObject const* searcher, std::list& objects, Check& check) + : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) {} void Visit(CreatureMapType& m); @@ -511,14 +488,14 @@ namespace Acore }; template - struct PlayerListSearcher : ContainerInserter + struct PlayerListSearcher { uint32 i_phaseMask; + std::list& i_objects; Check& i_check; - template PlayerListSearcher(WorldObject const* searcher, Container& container, Check& check) - : ContainerInserter(container), - i_phaseMask(searcher->GetPhaseMask()), i_check(check) {} + PlayerListSearcher(WorldObject const* searcher, std::list& objects, Check& check) + : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) {} void Visit(PlayerMapType& m); @@ -826,23 +803,20 @@ namespace Acore { public: AnyUnfriendlyUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) : i_obj(obj), i_funit(funit), i_range(range) {} - - bool operator()(Unit* u) const + bool operator()(Unit* u) { if (u->IsAlive() && i_obj->IsWithinDistInMap(u, i_range) && !i_funit->IsFriendlyTo(u) && - (i_funit->GetTypeId() != TYPEID_UNIT || !i_funit->ToCreature()->IsAvoidingAOE())) // pussywizard) - { + (i_funit->GetTypeId() != TYPEID_UNIT || !i_funit->ToCreature()->IsAvoidingAOE())) // pussywizard return true; - } - - return false; + else + return false; } - private: WorldObject const* i_obj; Unit const* i_funit; float i_range; }; + class AnyUnfriendlyNoTotemUnitInObjectRangeCheck { public: @@ -929,19 +903,9 @@ namespace Acore class AnyGroupedUnitInObjectRangeCheck { public: - AnyGroupedUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool raid, bool playerOnly = false) : _source(obj), _refUnit(funit), _range(range), _raid(raid), _playerOnly(playerOnly) {} + AnyGroupedUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool raid) : _source(obj), _refUnit(funit), _range(range), _raid(raid) {} bool operator()(Unit* u) { - if (G3D::fuzzyEq(_range, 0.0f)) - { - return false; - } - - if (_playerOnly && u->GetTypeId() != TYPEID_PLAYER) - { - return false; - } - if (_raid) { if (!_refUnit->IsInRaidWith(u)) @@ -958,7 +922,6 @@ namespace Acore Unit const* _refUnit; float _range; bool _raid; - bool _playerOnly; }; class AnyUnitInObjectRangeCheck @@ -1005,35 +968,27 @@ namespace Acore class AnyAoETargetUnitInObjectRangeCheck { public: - AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, SpellInfo const* spellInfo = nullptr) - : i_obj(obj), i_funit(funit), _spellInfo(spellInfo), i_range(range) + AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) + : i_obj(obj), i_funit(funit), _spellInfo(nullptr), i_range(range) { Unit const* check = i_funit; Unit const* owner = i_funit->GetOwner(); if (owner) check = owner; i_targetForPlayer = (check->GetTypeId() == TYPEID_PLAYER); - - if (!_spellInfo) - { - if (DynamicObject const* dynObj = i_obj->ToDynObject()) - { - _spellInfo = sSpellMgr->GetSpellInfo(dynObj->GetSpellId()); - } - } + if (i_obj->GetTypeId() == TYPEID_DYNAMICOBJECT) + _spellInfo = sSpellMgr->GetSpellInfo(((DynamicObject*)i_obj)->GetSpellId()); } bool operator()(Unit* u) { // Check contains checks for: live, non-selectable, non-attackable flags, flight check and GM check, ignore totems - if (u->GetTypeId() == TYPEID_UNIT && ((Creature*) u)->IsTotem()) - { + if (u->GetTypeId() == TYPEID_UNIT && ((Creature*)u)->IsTotem()) return false; - } - if (_spellInfo && _spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER) && u->GetTypeId() != TYPEID_PLAYER) - { - return false; - } - return i_funit->_IsValidAttackTarget(u, _spellInfo, i_obj->GetTypeId() == TYPEID_DYNAMICOBJECT ? i_obj : nullptr) && i_obj->IsWithinDistInMap(u, i_range); + + if (i_funit->_IsValidAttackTarget(u, _spellInfo, i_obj->GetTypeId() == TYPEID_DYNAMICOBJECT ? i_obj : nullptr) && i_obj->IsWithinDistInMap(u, i_range)) + return true; + + return false; } private: bool i_targetForPlayer; diff --git a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h index 3cd1b77dc..4cb57cfdf 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h +++ b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h @@ -253,7 +253,7 @@ void Acore::WorldObjectListSearcher::Visit(PlayerMapType& m) for (PlayerMapType::iterator itr = m.begin(); itr != m.end(); ++itr) if (i_check(itr->GetSource())) - Insert(itr->GetSource()); + i_objects.push_back(itr->GetSource()); } template @@ -264,7 +264,7 @@ void Acore::WorldObjectListSearcher::Visit(CreatureMapType& m) for (CreatureMapType::iterator itr = m.begin(); itr != m.end(); ++itr) if (i_check(itr->GetSource())) - Insert(itr->GetSource()); + i_objects.push_back(itr->GetSource()); } template @@ -275,7 +275,7 @@ void Acore::WorldObjectListSearcher::Visit(CorpseMapType& m) for (CorpseMapType::iterator itr = m.begin(); itr != m.end(); ++itr) if (i_check(itr->GetSource())) - Insert(itr->GetSource()); + i_objects.push_back(itr->GetSource()); } template @@ -286,7 +286,7 @@ void Acore::WorldObjectListSearcher::Visit(GameObjectMapType& m) for (GameObjectMapType::iterator itr = m.begin(); itr != m.end(); ++itr) if (i_check(itr->GetSource())) - Insert(itr->GetSource()); + i_objects.push_back(itr->GetSource()); } template @@ -297,7 +297,7 @@ void Acore::WorldObjectListSearcher::Visit(DynamicObjectMapType& m) for (DynamicObjectMapType::iterator itr = m.begin(); itr != m.end(); ++itr) if (i_check(itr->GetSource())) - Insert(itr->GetSource()); + i_objects.push_back(itr->GetSource()); } // Gameobject searchers @@ -341,7 +341,7 @@ void Acore::GameObjectListSearcher::Visit(GameObjectMapType& m) for (GameObjectMapType::iterator itr = m.begin(); itr != m.end(); ++itr) if (itr->GetSource()->InSamePhase(i_phaseMask)) if (i_check(itr->GetSource())) - Insert(itr->GetSource()); + i_objects.push_back(itr->GetSource()); } // Unit searchers @@ -418,7 +418,7 @@ void Acore::UnitListSearcher::Visit(PlayerMapType& m) for (PlayerMapType::iterator itr = m.begin(); itr != m.end(); ++itr) if (itr->GetSource()->InSamePhase(i_phaseMask)) if (i_check(itr->GetSource())) - Insert(itr->GetSource()); + i_objects.push_back(itr->GetSource()); } template @@ -427,7 +427,7 @@ void Acore::UnitListSearcher::Visit(CreatureMapType& m) for (CreatureMapType::iterator itr = m.begin(); itr != m.end(); ++itr) if (itr->GetSource()->InSamePhase(i_phaseMask)) if (i_check(itr->GetSource())) - Insert(itr->GetSource()); + i_objects.push_back(itr->GetSource()); } // Creature searchers @@ -471,7 +471,7 @@ void Acore::CreatureListSearcher::Visit(CreatureMapType& m) for (CreatureMapType::iterator itr = m.begin(); itr != m.end(); ++itr) if (itr->GetSource()->InSamePhase(i_phaseMask)) if (i_check(itr->GetSource())) - Insert(itr->GetSource()); + i_objects.push_back(itr->GetSource()); } template @@ -480,7 +480,7 @@ void Acore::PlayerListSearcher::Visit(PlayerMapType& m) for (PlayerMapType::iterator itr = m.begin(); itr != m.end(); ++itr) if (itr->GetSource()->InSamePhase(i_phaseMask)) if (i_check(itr->GetSource())) - Insert(itr->GetSource()); + i_objects.push_back(itr->GetSource()); } template diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 39c764555..3049b4c19 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -298,7 +298,7 @@ void Group::ConvertToRaid() // update quest related GO states (quest activity dependent from raid membership) for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) if (Player* player = ObjectAccessor::FindPlayer(citr->guid)) - player->UpdateVisibleGameobjectsOrSpellClicks(); + player->UpdateForQuestWorldObjects(); // pussywizard: client automatically clears df "eye" near minimap, so remove from raid browser if (sLFGMgr->GetState(GetLeaderGUID()) == lfg::LFG_STATE_RAIDBROWSER) @@ -475,7 +475,7 @@ bool Group::AddMember(Player* player) // quest related GO state dependent from raid membership if (isRaidGroup()) - player->UpdateVisibleGameobjectsOrSpellClicks(); + player->UpdateForQuestWorldObjects(); { // Broadcast new player group member fields to rest of the group @@ -560,7 +560,7 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R player->SetGroup(nullptr); // quest related GO state dependent from raid membership - player->UpdateVisibleGameobjectsOrSpellClicks(); + player->UpdateForQuestWorldObjects(); } WorldPacket data; @@ -774,7 +774,7 @@ void Group::Disband(bool hideDestroy /* = false */) // quest related GO state dependent from raid membership if (isRaidGroup()) - player->UpdateVisibleGameobjectsOrSpellClicks(); + player->UpdateForQuestWorldObjects(); WorldPacket data; if (!hideDestroy) diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 706aacbd6..026538e7c 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -18,7 +18,6 @@ #include "ArenaSpectator.h" #include "CellImpl.h" #include "Common.h" -#include "ConditionMgr.h" #include "DynamicObject.h" #include "GridNotifiers.h" #include "GridNotifiersImpl.h" @@ -561,18 +560,19 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply) m_updateTargetMapInterval = UPDATE_TARGET_MAP_INTERVAL; // fill up to date target list - // target, effMask - std::unordered_map targets; + // target, effMask + std::map targets; + FillTargetMap(targets, caster); - std::deque targetsToRemove; + UnitList targetsToRemove; // mark all auras as ready to remove for (ApplicationMap::iterator appIter = m_applications.begin(); appIter != m_applications.end(); ++appIter) { - auto itr = targets.find(appIter->second->GetTarget()); + std::map::iterator existing = targets.find(appIter->second->GetTarget()); // not found in current area - remove the aura - if (itr == targets.end()) + if (existing == targets.end()) targetsToRemove.push_back(appIter->second->GetTarget()); else { @@ -580,22 +580,22 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply) if (IsArea()) for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex) { - if ((itr->second & (1 << effIndex)) && itr->first->IsImmunedToSpellEffect(GetSpellInfo(), effIndex)) - itr->second &= ~(1 << effIndex); + if ((existing->second & (1 << effIndex)) && existing->first->IsImmunedToSpellEffect(GetSpellInfo(), effIndex)) + existing->second &= ~(1 << effIndex); } // needs readding - remove now, will be applied in next update cycle // (dbcs do not have auras which apply on same type of targets but have different radius, so this is not really needed) - if (appIter->second->GetEffectMask() != itr->second || !CanBeAppliedOn(itr->first)) + if (appIter->second->GetEffectMask() != existing->second || !CanBeAppliedOn(existing->first)) targetsToRemove.push_back(appIter->second->GetTarget()); // nothing todo - aura already applied // remove from auras to register list - targets.erase(itr); + targets.erase(existing); } } // register auras for units - for (auto itr = targets.begin(); itr != targets.end();) + for (std::map::iterator itr = targets.begin(); itr != targets.end();) { // aura mustn't be already applied on target if (AuraApplication* aurApp = GetApplicationOfTarget(itr->first->GetGUID())) @@ -608,7 +608,7 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply) if (aurApp->GetTarget() != itr->first) { // remove from auras to register list - itr = targets.erase(itr); + targets.erase(itr++); continue; } else @@ -675,7 +675,7 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply) } } if (!addUnit) - itr = targets.erase(itr); + targets.erase(itr++); else { // owner has to be in world, or effect has to be applied to self @@ -693,15 +693,15 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply) } // remove auras from units no longer needing them - for (Unit* unit : targetsToRemove) - if (AuraApplication* aurApp = GetApplicationOfTarget(unit->GetGUID())) - unit->_UnapplyAura(aurApp, AURA_REMOVE_BY_DEFAULT); + for (UnitList::iterator itr = targetsToRemove.begin(); itr != targetsToRemove.end(); ++itr) + if (AuraApplication* aurApp = GetApplicationOfTarget((*itr)->GetGUID())) + (*itr)->_UnapplyAura(aurApp, AURA_REMOVE_BY_DEFAULT); if (!apply) return; // apply aura effects for units - for (auto itr = targets.begin(); itr != targets.end(); ++itr) + for (std::map::iterator itr = targets.begin(); itr != targets.end(); ++itr) { if (AuraApplication* aurApp = GetApplicationOfTarget(itr->first->GetGUID())) { @@ -2660,85 +2660,72 @@ void UnitAura::Remove(AuraRemoveMode removeMode) GetUnitOwner()->RemoveOwnedAura(this, removeMode); } -void UnitAura::FillTargetMap(std::unordered_map& targets, Unit* caster) +void UnitAura::FillTargetMap(std::map& targets, Unit* caster) { for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex) { if (!HasEffect(effIndex)) continue; - - std::deque units; - + UnitList targetList; // non-area aura if (GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_APPLY_AURA) - units.push_back(GetUnitOwner()); + { + targetList.push_back(GetUnitOwner()); + } else { float radius = GetSpellInfo()->Effects[effIndex].CalcRadius(caster); if (!GetUnitOwner()->HasUnitState(UNIT_STATE_ISOLATED)) { - Unit* ref = caster; - ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions; - SpellTargetCheckTypes selectionType = TARGET_CHECK_DEFAULT; switch (GetSpellInfo()->Effects[effIndex].Effect) { case SPELL_EFFECT_APPLY_AREA_AURA_PARTY: case SPELL_EFFECT_APPLY_AREA_AURA_RAID: { - units.push_back(GetUnitOwner()); - Acore::AnyGroupedUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER)); - Acore::UnitListSearcher searcher(GetUnitOwner(), units, u_check); + targetList.push_back(GetUnitOwner()); + Acore::AnyGroupedUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID); + Acore::UnitListSearcher searcher(GetUnitOwner(), targetList, u_check); Cell::VisitAllObjects(GetUnitOwner(), searcher, radius); break; } case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND: { - units.push_back(GetUnitOwner()); - Acore::AnyFriendlyUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER)); - Acore::UnitListSearcher searcher(GetUnitOwner(), units, u_check); + targetList.push_back(GetUnitOwner()); + Acore::AnyFriendlyUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius); + Acore::UnitListSearcher searcher(GetUnitOwner(), targetList, u_check); Cell::VisitAllObjects(GetUnitOwner(), searcher, radius); break; } case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY: { - Acore::AnyAoETargetUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, m_spellInfo); // No GetCharmer in searcher - Acore::UnitListSearcher searcher(GetUnitOwner(), units, u_check); + Acore::AnyAoETargetUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius); // No GetCharmer in searcher + Acore::UnitListSearcher searcher(GetUnitOwner(), targetList, u_check); Cell::VisitAllObjects(GetUnitOwner(), searcher, radius); break; } case SPELL_EFFECT_APPLY_AREA_AURA_PET: - if (!condList || sConditionMgr->IsObjectMeetToConditions(GetUnitOwner(), ref, *condList)) - units.push_back(GetUnitOwner()); + targetList.push_back(GetUnitOwner()); [[fallthrough]]; // TODO: Not sure whether the fallthrough was a mistake (forgetting a break) or intended. This should be double-checked. case SPELL_EFFECT_APPLY_AREA_AURA_OWNER: { if (Unit* owner = GetUnitOwner()->GetCharmerOrOwner()) if (GetUnitOwner()->IsWithinDistInMap(owner, radius)) - if (!condList || sConditionMgr->IsObjectMeetToConditions(owner, ref, *condList)) - units.push_back(owner); + targetList.push_back(owner); break; } - default: - break; - } - if (selectionType != TARGET_CHECK_DEFAULT) - { - Acore::WorldObjectSpellAreaTargetCheck check(radius, GetUnitOwner(), ref, GetUnitOwner(), m_spellInfo, selectionType, condList); - Acore::UnitListSearcher searcher(GetUnitOwner(), units, check); - Cell::VisitAllObjects(GetUnitOwner(), searcher, radius); - } - - for (Unit* unit : units) - { - auto itr = targets.find(unit); - if (itr != targets.end()) - itr->second |= 1 << effIndex; - else - targets[unit] = 1 << effIndex; } } } + + for (UnitList::iterator itr = targetList.begin(); itr != targetList.end(); ++itr) + { + std::map::iterator existing = targets.find(*itr); + if (existing != targets.end()) + existing->second |= 1 << effIndex; + else + targets[*itr] = 1 << effIndex; + } } } @@ -2760,7 +2747,7 @@ void DynObjAura::Remove(AuraRemoveMode removeMode) _Remove(removeMode); } -void DynObjAura::FillTargetMap(std::unordered_map& targets, Unit* /*caster*/) +void DynObjAura::FillTargetMap(std::map& targets, Unit* /*caster*/) { Unit* dynObjOwnerCaster = GetDynobjOwner()->GetCaster(); float radius = GetDynobjOwner()->GetRadius(); @@ -2769,13 +2756,12 @@ void DynObjAura::FillTargetMap(std::unordered_map& targets, Unit* { if (!HasEffect(effIndex)) continue; - - std::deque units; + UnitList targetList; if (GetSpellInfo()->Effects[effIndex].TargetB.GetTarget() == TARGET_DEST_DYNOBJ_ALLY || GetSpellInfo()->Effects[effIndex].TargetB.GetTarget() == TARGET_UNIT_DEST_AREA_ALLY) { - Acore::AnyFriendlyUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER)); - Acore::UnitListSearcher searcher(GetDynobjOwner(), units, u_check); + Acore::AnyFriendlyUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius); + Acore::UnitListSearcher searcher(GetDynobjOwner(), targetList, u_check); Cell::VisitAllObjects(GetDynobjOwner(), searcher, radius); } // pussywizard: TARGET_DEST_DYNOBJ_NONE is supposed to search for both friendly and unfriendly targets, so for any unit @@ -2783,35 +2769,30 @@ void DynObjAura::FillTargetMap(std::unordered_map& targets, Unit* else if (GetSpellInfo()->Effects[effIndex].TargetB.GetTarget() == TARGET_DEST_DYNOBJ_NONE) { Acore::AnyAttackableUnitExceptForOriginalCasterInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius); - Acore::UnitListSearcher searcher(GetDynobjOwner(), units, u_check); + Acore::UnitListSearcher searcher(GetDynobjOwner(), targetList, u_check); Cell::VisitAllObjects(GetDynobjOwner(), searcher, radius); } else { Acore::AnyAoETargetUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius); - Acore::UnitListSearcher searcher(GetDynobjOwner(), units, u_check); + Acore::UnitListSearcher searcher(GetDynobjOwner(), targetList, u_check); Cell::VisitAllObjects(GetDynobjOwner(), searcher, radius); } - for (Unit* unit : units) + for (UnitList::iterator itr = targetList.begin(); itr != targetList.end(); ++itr) { // xinef: check z level and los dependence + Unit* target = *itr; float zLevel = GetDynobjOwner()->GetPositionZ(); - if (unit->GetPositionZ() + 3.0f < zLevel || unit->GetPositionZ() - 5.0f > zLevel) - { - if (!unit->IsWithinLOSInMap(GetDynobjOwner())) - { + if (target->GetPositionZ() + 3.0f < zLevel || target->GetPositionZ() - 5.0f > zLevel) + if (!target->IsWithinLOSInMap(GetDynobjOwner())) continue; - } - } - auto itr = targets.find(unit); - if (itr != targets.end()) - { - itr->second |= 1 << effIndex; - } + std::map::iterator existing = targets.find(*itr); + if (existing != targets.end()) + existing->second |= 1 << effIndex; else - targets[unit] = 1 << effIndex; + targets[*itr] = 1 << effIndex; } } } diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index 7cf4fbb95..15320e5a1 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -105,11 +105,7 @@ public: ObjectGuid GetCasterGUID() const { return m_casterGuid; } Unit* GetCaster() const; WorldObject* GetOwner() const { return m_owner; } - Unit* GetUnitOwner() const - { - ASSERT(GetType() == UNIT_AURA_TYPE); - return (Unit*) m_owner->ToUnit(); - } + Unit* GetUnitOwner() const { ASSERT(GetType() == UNIT_AURA_TYPE); return (Unit*)m_owner; } DynamicObject* GetDynobjOwner() const { ASSERT(GetType() == DYNOBJ_AURA_TYPE); return (DynamicObject*)m_owner; } AuraObjectType GetType() const; @@ -119,7 +115,7 @@ public: void _Remove(AuraRemoveMode removeMode); virtual void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) = 0; - virtual void FillTargetMap(std::unordered_map& targets, Unit* caster) = 0; + virtual void FillTargetMap(std::map& targets, Unit* caster) = 0; void UpdateTargetMap(Unit* caster, bool apply = true); void _RegisterForTargets() {Unit* caster = GetCaster(); UpdateTargetMap(caster, false);} @@ -288,7 +284,7 @@ public: void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) override; - void FillTargetMap(std::unordered_map& targets, Unit* caster) override; + void FillTargetMap(std::map& targets, Unit* caster) override; // Allow Apply Aura Handler to modify and access m_AuraDRGroup void SetDiminishGroup(DiminishingGroup group) { m_AuraDRGroup = group; } @@ -308,6 +304,6 @@ protected: public: void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) override; - void FillTargetMap(std::unordered_map& targets, Unit* caster) override; + void FillTargetMap(std::map& targets, Unit* caster) override; }; #endif diff --git a/src/server/scripts/Pet/pet_dk.cpp b/src/server/scripts/Pet/pet_dk.cpp index 6c33acc3e..312db264d 100644 --- a/src/server/scripts/Pet/pet_dk.cpp +++ b/src/server/scripts/Pet/pet_dk.cpp @@ -169,7 +169,7 @@ public: _initialSelection = false; // Find victim of Summon Gargoyle spell std::list targets; - Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(me, me, 50.0f); + Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(me, me, 50); Acore::UnitListSearcher searcher(me, targets, u_check); Cell::VisitAllObjects(me, searcher, 50.0f); for (std::list::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)