mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 09:17:18 +00:00
fix(Core/Spells): Forward core changes (#8841)
This commit is contained in:
@@ -74,17 +74,17 @@ void VisitorHelper(VISITOR& v, ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE>&
|
||||
VisitorHelper(v, c._TailElements);
|
||||
}
|
||||
|
||||
template<class VISITOR, class OBJECT_TYPES, class KEY_TYPE>
|
||||
template <class VISITOR, class OBJECT_TYPES, class KEY_TYPE>
|
||||
void VisitorHelper(VISITOR& v, TypeUnorderedMapContainer<OBJECT_TYPES, KEY_TYPE>& c)
|
||||
{
|
||||
VisitorHelper(v, c.GetElements());
|
||||
}
|
||||
|
||||
template<class VISITOR, class TYPE_CONTAINER>
|
||||
template <class VISITOR, class TYPE_CONTAINER>
|
||||
class TypeContainerVisitor
|
||||
{
|
||||
public:
|
||||
TypeContainerVisitor(VISITOR& v) : i_visitor(v) { }
|
||||
TypeContainerVisitor(VISITOR& v) : i_visitor(v) {}
|
||||
|
||||
void Visit(TYPE_CONTAINER& c)
|
||||
{
|
||||
|
||||
@@ -640,6 +640,11 @@ ConditionMgr::~ConditionMgr()
|
||||
Clean();
|
||||
}
|
||||
|
||||
bool ConditionMgr::IsSpellUsedInSpellClickConditions(uint32 spellId) const
|
||||
{
|
||||
return SpellsUsedInSpellClickConditions.find(spellId) != SpellsUsedInSpellClickConditions.end();
|
||||
}
|
||||
|
||||
ConditionMgr* ConditionMgr::instance()
|
||||
{
|
||||
static ConditionMgr instance;
|
||||
@@ -694,7 +699,7 @@ uint32 ConditionMgr::GetSearcherTypeMaskForConditionList(ConditionList const& co
|
||||
return mask;
|
||||
}
|
||||
|
||||
bool ConditionMgr::IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionList const& conditions)
|
||||
bool ConditionMgr::IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionList const& conditions) const
|
||||
{
|
||||
// groupId, groupCheckPassed
|
||||
std::map<uint32, bool> ElseGroupStore;
|
||||
@@ -738,19 +743,19 @@ bool ConditionMgr::IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ConditionMgr::IsObjectMeetToConditions(WorldObject* object, ConditionList const& conditions)
|
||||
bool ConditionMgr::IsObjectMeetToConditions(WorldObject* object, ConditionList const& conditions) const
|
||||
{
|
||||
ConditionSourceInfo srcInfo = ConditionSourceInfo(object);
|
||||
return IsObjectMeetToConditions(srcInfo, conditions);
|
||||
}
|
||||
|
||||
bool ConditionMgr::IsObjectMeetToConditions(WorldObject* object1, WorldObject* object2, ConditionList const& conditions)
|
||||
bool ConditionMgr::IsObjectMeetToConditions(WorldObject* object1, WorldObject* object2, ConditionList const& conditions) const
|
||||
{
|
||||
ConditionSourceInfo srcInfo = ConditionSourceInfo(object1, object2);
|
||||
return IsObjectMeetToConditions(srcInfo, conditions);
|
||||
}
|
||||
|
||||
bool ConditionMgr::IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, ConditionList const& conditions)
|
||||
bool ConditionMgr::IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, ConditionList const& conditions) const
|
||||
{
|
||||
if (conditions.empty())
|
||||
return true;
|
||||
@@ -1055,6 +1060,10 @@ 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
|
||||
@@ -1123,6 +1132,10 @@ 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());
|
||||
@@ -2314,7 +2327,7 @@ void ConditionMgr::Clean()
|
||||
itr->second.clear();
|
||||
}
|
||||
|
||||
SpellClickEventConditionStore.clear();
|
||||
SpellsUsedInSpellClickConditions.clear();
|
||||
|
||||
for (NpcVendorConditionContainer::iterator itr = NpcVendorConditionContainerStore.begin(); itr != NpcVendorConditionContainerStore.end(); ++itr)
|
||||
{
|
||||
|
||||
@@ -22,7 +22,10 @@
|
||||
#include "Errors.h"
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
class Creature;
|
||||
class Player;
|
||||
class Unit;
|
||||
class WorldObject;
|
||||
@@ -254,9 +257,9 @@ public:
|
||||
ConditionList GetConditionReferences(uint32 refId);
|
||||
|
||||
uint32 GetSearcherTypeMaskForConditionList(ConditionList const& conditions);
|
||||
bool IsObjectMeetToConditions(WorldObject* object, ConditionList const& conditions);
|
||||
bool IsObjectMeetToConditions(WorldObject* object1, WorldObject* object2, ConditionList const& conditions);
|
||||
bool IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, 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;
|
||||
[[nodiscard]] bool CanHaveSourceGroupSet(ConditionSourceType sourceType) const;
|
||||
[[nodiscard]] bool CanHaveSourceIdSet(ConditionSourceType sourceType) const;
|
||||
ConditionList GetConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry);
|
||||
@@ -264,6 +267,7 @@ 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);
|
||||
@@ -271,7 +275,7 @@ private:
|
||||
bool addToGossipMenus(Condition* cond);
|
||||
bool addToGossipMenuItems(Condition* cond);
|
||||
bool addToSpellImplicitTargetConditions(Condition* cond);
|
||||
bool IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionList const& conditions);
|
||||
bool IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionList const& conditions) const;
|
||||
|
||||
void Clean(); // free up resources
|
||||
std::list<Condition*> AllocatedMemoryStore; // some garbage collection :)
|
||||
@@ -282,6 +286,8 @@ private:
|
||||
CreatureSpellConditionContainer SpellClickEventConditionStore;
|
||||
NpcVendorConditionContainer NpcVendorConditionContainerStore;
|
||||
SmartEventConditionContainer SmartEventConditionStore;
|
||||
|
||||
std::unordered_set<uint32> SpellsUsedInSpellClickConditions;
|
||||
};
|
||||
|
||||
#define sConditionMgr ConditionMgr::instance()
|
||||
|
||||
@@ -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 UpdateForQuestWorldObjects();
|
||||
void UpdateVisibleGameobjectsOrSpellClicks();
|
||||
[[nodiscard]] bool CanShareQuest(uint32 quest_id) const;
|
||||
|
||||
void SendQuestComplete(uint32 quest_id);
|
||||
|
||||
@@ -1548,7 +1548,7 @@ void Player::SendQuestUpdate(uint32 questId)
|
||||
RemoveAurasDueToSpell(oldSpellId);
|
||||
}
|
||||
|
||||
UpdateForQuestWorldObjects();
|
||||
UpdateVisibleGameobjectsOrSpellClicks();
|
||||
}
|
||||
|
||||
QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver)
|
||||
@@ -1809,7 +1809,7 @@ void Player::ItemAddedQuestCheck(uint32 entry, uint32 count)
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateForQuestWorldObjects();
|
||||
UpdateVisibleGameobjectsOrSpellClicks();
|
||||
}
|
||||
|
||||
void Player::ItemRemovedQuestCheck(uint32 entry, uint32 count)
|
||||
@@ -1850,7 +1850,7 @@ void Player::ItemRemovedQuestCheck(uint32 entry, uint32 count)
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateForQuestWorldObjects();
|
||||
UpdateVisibleGameobjectsOrSpellClicks();
|
||||
}
|
||||
|
||||
void Player::KilledMonster(CreatureTemplate const* cInfo, ObjectGuid guid)
|
||||
|
||||
@@ -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);
|
||||
UpdateForQuestWorldObjects();
|
||||
UpdateVisibleGameobjectsOrSpellClicks();
|
||||
return pItem;
|
||||
}
|
||||
|
||||
|
||||
@@ -1820,7 +1820,7 @@ void Player::UpdateTriggerVisibility()
|
||||
GetSession()->SendPacket(&packet);
|
||||
}
|
||||
|
||||
void Player::UpdateForQuestWorldObjects()
|
||||
void Player::UpdateVisibleGameobjectsOrSpellClicks()
|
||||
{
|
||||
if (m_clientGUIDs.empty())
|
||||
return;
|
||||
@@ -1847,19 +1847,9 @@ void Player::UpdateForQuestWorldObjects()
|
||||
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);
|
||||
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;
|
||||
}
|
||||
obj->BuildValuesUpdateBlockForPlayer(&udata, this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4072,6 +4072,14 @@ 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
|
||||
@@ -4150,6 +4158,14 @@ 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();
|
||||
|
||||
@@ -165,6 +165,29 @@ namespace Acore
|
||||
|
||||
// WorldObject searchers & workers
|
||||
|
||||
// Generic base class to insert elements into arbitrary containers using push_back
|
||||
template <typename Type> class ContainerInserter
|
||||
{
|
||||
using InserterType = void (*)(void*, Type&&);
|
||||
|
||||
void* ref;
|
||||
InserterType inserter;
|
||||
|
||||
// MSVC workaround
|
||||
template <typename T> static void InserterOf(void* ref, Type&& type)
|
||||
{
|
||||
static_cast<T*>(ref)->push_back(std::move(type));
|
||||
}
|
||||
|
||||
protected:
|
||||
template <typename T> ContainerInserter(T& ref_) : ref(&ref_), inserter(&InserterOf<T>) {}
|
||||
|
||||
void Insert(Type type)
|
||||
{
|
||||
inserter(ref, std::move(type));
|
||||
}
|
||||
};
|
||||
|
||||
template<class Check>
|
||||
struct WorldObjectSearcher
|
||||
{
|
||||
@@ -206,15 +229,15 @@ namespace Acore
|
||||
};
|
||||
|
||||
template<class Check>
|
||||
struct WorldObjectListSearcher
|
||||
struct WorldObjectListSearcher : ContainerInserter<WorldObject*>
|
||||
{
|
||||
uint32 i_mapTypeMask;
|
||||
uint32 i_phaseMask;
|
||||
std::list<WorldObject*>& i_objects;
|
||||
Check& i_check;
|
||||
|
||||
WorldObjectListSearcher(WorldObject const* searcher, std::list<WorldObject*>& objects, Check& check, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL)
|
||||
: i_mapTypeMask(mapTypeMask), i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) {}
|
||||
template <typename Container> WorldObjectListSearcher(WorldObject const* searcher, Container& container, Check& check, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL)
|
||||
: ContainerInserter<WorldObject*>(container),
|
||||
i_mapTypeMask(mapTypeMask), i_phaseMask(searcher->GetPhaseMask()), i_check(check) {}
|
||||
|
||||
void Visit(PlayerMapType& m);
|
||||
void Visit(CreatureMapType& m);
|
||||
@@ -316,14 +339,14 @@ namespace Acore
|
||||
};
|
||||
|
||||
template<class Check>
|
||||
struct GameObjectListSearcher
|
||||
struct GameObjectListSearcher : ContainerInserter<GameObject*>
|
||||
{
|
||||
uint32 i_phaseMask;
|
||||
std::list<GameObject*>& i_objects;
|
||||
Check& i_check;
|
||||
|
||||
GameObjectListSearcher(WorldObject const* searcher, std::list<GameObject*>& objects, Check& check)
|
||||
: i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) {}
|
||||
template <typename Container> GameObjectListSearcher(WorldObject const* searcher, Container& container, Check& check)
|
||||
: ContainerInserter<GameObject*>(container),
|
||||
i_phaseMask(searcher->GetPhaseMask()), i_check(check) {}
|
||||
|
||||
void Visit(GameObjectMapType& m);
|
||||
|
||||
@@ -388,14 +411,14 @@ namespace Acore
|
||||
|
||||
// All accepted by Check units if any
|
||||
template<class Check>
|
||||
struct UnitListSearcher
|
||||
struct UnitListSearcher : ContainerInserter<Unit*>
|
||||
{
|
||||
uint32 i_phaseMask;
|
||||
std::list<Unit*>& i_objects;
|
||||
Check& i_check;
|
||||
|
||||
UnitListSearcher(WorldObject const* searcher, std::list<Unit*>& objects, Check& check)
|
||||
: i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) {}
|
||||
template <typename Container> UnitListSearcher(WorldObject const* searcher, Container& container, Check& check)
|
||||
: ContainerInserter<Unit*>(container),
|
||||
i_phaseMask(searcher->GetPhaseMask()), i_check(check) {}
|
||||
|
||||
void Visit(PlayerMapType& m);
|
||||
void Visit(CreatureMapType& m);
|
||||
@@ -437,14 +460,14 @@ namespace Acore
|
||||
};
|
||||
|
||||
template<class Check>
|
||||
struct CreatureListSearcher
|
||||
struct CreatureListSearcher : ContainerInserter<Creature*>
|
||||
{
|
||||
uint32 i_phaseMask;
|
||||
std::list<Creature*>& i_objects;
|
||||
Check& i_check;
|
||||
|
||||
CreatureListSearcher(WorldObject const* searcher, std::list<Creature*>& objects, Check& check)
|
||||
: i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) {}
|
||||
template <typename Container> CreatureListSearcher(WorldObject const* searcher, Container& container, Check& check)
|
||||
: ContainerInserter<Creature*>(container),
|
||||
i_phaseMask(searcher->GetPhaseMask()), i_check(check) {}
|
||||
|
||||
void Visit(CreatureMapType& m);
|
||||
|
||||
@@ -488,14 +511,14 @@ namespace Acore
|
||||
};
|
||||
|
||||
template<class Check>
|
||||
struct PlayerListSearcher
|
||||
struct PlayerListSearcher : ContainerInserter<Player*>
|
||||
{
|
||||
uint32 i_phaseMask;
|
||||
std::list<Player*>& i_objects;
|
||||
Check& i_check;
|
||||
|
||||
PlayerListSearcher(WorldObject const* searcher, std::list<Player*>& objects, Check& check)
|
||||
: i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) {}
|
||||
template <typename Container> PlayerListSearcher(WorldObject const* searcher, Container& container, Check& check)
|
||||
: ContainerInserter<Player*>(container),
|
||||
i_phaseMask(searcher->GetPhaseMask()), i_check(check) {}
|
||||
|
||||
void Visit(PlayerMapType& m);
|
||||
|
||||
@@ -803,20 +826,23 @@ 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)
|
||||
|
||||
bool operator()(Unit* u) const
|
||||
{
|
||||
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;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
WorldObject const* i_obj;
|
||||
Unit const* i_funit;
|
||||
float i_range;
|
||||
};
|
||||
|
||||
class AnyUnfriendlyNoTotemUnitInObjectRangeCheck
|
||||
{
|
||||
public:
|
||||
@@ -903,9 +929,19 @@ namespace Acore
|
||||
class AnyGroupedUnitInObjectRangeCheck
|
||||
{
|
||||
public:
|
||||
AnyGroupedUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool raid) : _source(obj), _refUnit(funit), _range(range), _raid(raid) {}
|
||||
AnyGroupedUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool raid, bool playerOnly = false) : _source(obj), _refUnit(funit), _range(range), _raid(raid), _playerOnly(playerOnly) {}
|
||||
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))
|
||||
@@ -922,6 +958,7 @@ namespace Acore
|
||||
Unit const* _refUnit;
|
||||
float _range;
|
||||
bool _raid;
|
||||
bool _playerOnly;
|
||||
};
|
||||
|
||||
class AnyUnitInObjectRangeCheck
|
||||
@@ -968,27 +1005,35 @@ namespace Acore
|
||||
class AnyAoETargetUnitInObjectRangeCheck
|
||||
{
|
||||
public:
|
||||
AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range)
|
||||
: i_obj(obj), i_funit(funit), _spellInfo(nullptr), i_range(range)
|
||||
AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, SpellInfo const* spellInfo = nullptr)
|
||||
: i_obj(obj), i_funit(funit), _spellInfo(spellInfo), 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 (i_obj->GetTypeId() == TYPEID_DYNAMICOBJECT)
|
||||
_spellInfo = sSpellMgr->GetSpellInfo(((DynamicObject*)i_obj)->GetSpellId());
|
||||
|
||||
if (!_spellInfo)
|
||||
{
|
||||
if (DynamicObject const* dynObj = i_obj->ToDynObject())
|
||||
{
|
||||
_spellInfo = sSpellMgr->GetSpellInfo(dynObj->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 (i_funit->_IsValidAttackTarget(u, _spellInfo, i_obj->GetTypeId() == TYPEID_DYNAMICOBJECT ? i_obj : nullptr) && i_obj->IsWithinDistInMap(u, i_range))
|
||||
return true;
|
||||
|
||||
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);
|
||||
}
|
||||
private:
|
||||
bool i_targetForPlayer;
|
||||
|
||||
@@ -253,7 +253,7 @@ void Acore::WorldObjectListSearcher<Check>::Visit(PlayerMapType& m)
|
||||
|
||||
for (PlayerMapType::iterator itr = m.begin(); itr != m.end(); ++itr)
|
||||
if (i_check(itr->GetSource()))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
Insert(itr->GetSource());
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
@@ -264,7 +264,7 @@ void Acore::WorldObjectListSearcher<Check>::Visit(CreatureMapType& m)
|
||||
|
||||
for (CreatureMapType::iterator itr = m.begin(); itr != m.end(); ++itr)
|
||||
if (i_check(itr->GetSource()))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
Insert(itr->GetSource());
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
@@ -275,7 +275,7 @@ void Acore::WorldObjectListSearcher<Check>::Visit(CorpseMapType& m)
|
||||
|
||||
for (CorpseMapType::iterator itr = m.begin(); itr != m.end(); ++itr)
|
||||
if (i_check(itr->GetSource()))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
Insert(itr->GetSource());
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
@@ -286,7 +286,7 @@ void Acore::WorldObjectListSearcher<Check>::Visit(GameObjectMapType& m)
|
||||
|
||||
for (GameObjectMapType::iterator itr = m.begin(); itr != m.end(); ++itr)
|
||||
if (i_check(itr->GetSource()))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
Insert(itr->GetSource());
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
@@ -297,7 +297,7 @@ void Acore::WorldObjectListSearcher<Check>::Visit(DynamicObjectMapType& m)
|
||||
|
||||
for (DynamicObjectMapType::iterator itr = m.begin(); itr != m.end(); ++itr)
|
||||
if (i_check(itr->GetSource()))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
Insert(itr->GetSource());
|
||||
}
|
||||
|
||||
// Gameobject searchers
|
||||
@@ -341,7 +341,7 @@ void Acore::GameObjectListSearcher<Check>::Visit(GameObjectMapType& m)
|
||||
for (GameObjectMapType::iterator itr = m.begin(); itr != m.end(); ++itr)
|
||||
if (itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
if (i_check(itr->GetSource()))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
Insert(itr->GetSource());
|
||||
}
|
||||
|
||||
// Unit searchers
|
||||
@@ -418,7 +418,7 @@ void Acore::UnitListSearcher<Check>::Visit(PlayerMapType& m)
|
||||
for (PlayerMapType::iterator itr = m.begin(); itr != m.end(); ++itr)
|
||||
if (itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
if (i_check(itr->GetSource()))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
Insert(itr->GetSource());
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
@@ -427,7 +427,7 @@ void Acore::UnitListSearcher<Check>::Visit(CreatureMapType& m)
|
||||
for (CreatureMapType::iterator itr = m.begin(); itr != m.end(); ++itr)
|
||||
if (itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
if (i_check(itr->GetSource()))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
Insert(itr->GetSource());
|
||||
}
|
||||
|
||||
// Creature searchers
|
||||
@@ -471,7 +471,7 @@ void Acore::CreatureListSearcher<Check>::Visit(CreatureMapType& m)
|
||||
for (CreatureMapType::iterator itr = m.begin(); itr != m.end(); ++itr)
|
||||
if (itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
if (i_check(itr->GetSource()))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
Insert(itr->GetSource());
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
@@ -480,7 +480,7 @@ void Acore::PlayerListSearcher<Check>::Visit(PlayerMapType& m)
|
||||
for (PlayerMapType::iterator itr = m.begin(); itr != m.end(); ++itr)
|
||||
if (itr->GetSource()->InSamePhase(i_phaseMask))
|
||||
if (i_check(itr->GetSource()))
|
||||
i_objects.push_back(itr->GetSource());
|
||||
Insert(itr->GetSource());
|
||||
}
|
||||
|
||||
template<class Check>
|
||||
|
||||
@@ -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->UpdateForQuestWorldObjects();
|
||||
player->UpdateVisibleGameobjectsOrSpellClicks();
|
||||
|
||||
// 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->UpdateForQuestWorldObjects();
|
||||
player->UpdateVisibleGameobjectsOrSpellClicks();
|
||||
|
||||
{
|
||||
// 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->UpdateForQuestWorldObjects();
|
||||
player->UpdateVisibleGameobjectsOrSpellClicks();
|
||||
}
|
||||
|
||||
WorldPacket data;
|
||||
@@ -774,7 +774,7 @@ void Group::Disband(bool hideDestroy /* = false */)
|
||||
|
||||
// quest related GO state dependent from raid membership
|
||||
if (isRaidGroup())
|
||||
player->UpdateForQuestWorldObjects();
|
||||
player->UpdateVisibleGameobjectsOrSpellClicks();
|
||||
|
||||
WorldPacket data;
|
||||
if (!hideDestroy)
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "ArenaSpectator.h"
|
||||
#include "CellImpl.h"
|
||||
#include "Common.h"
|
||||
#include "ConditionMgr.h"
|
||||
#include "DynamicObject.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "GridNotifiersImpl.h"
|
||||
@@ -560,19 +561,18 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply)
|
||||
m_updateTargetMapInterval = UPDATE_TARGET_MAP_INTERVAL;
|
||||
|
||||
// fill up to date target list
|
||||
// target, effMask
|
||||
std::map<Unit*, uint8> targets;
|
||||
|
||||
// target, effMask
|
||||
std::unordered_map<Unit*, uint8> targets;
|
||||
FillTargetMap(targets, caster);
|
||||
|
||||
UnitList targetsToRemove;
|
||||
std::deque<Unit*> targetsToRemove;
|
||||
|
||||
// mark all auras as ready to remove
|
||||
for (ApplicationMap::iterator appIter = m_applications.begin(); appIter != m_applications.end(); ++appIter)
|
||||
{
|
||||
std::map<Unit*, uint8>::iterator existing = targets.find(appIter->second->GetTarget());
|
||||
auto itr = targets.find(appIter->second->GetTarget());
|
||||
// not found in current area - remove the aura
|
||||
if (existing == targets.end())
|
||||
if (itr == 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 ((existing->second & (1 << effIndex)) && existing->first->IsImmunedToSpellEffect(GetSpellInfo(), effIndex))
|
||||
existing->second &= ~(1 << effIndex);
|
||||
if ((itr->second & (1 << effIndex)) && itr->first->IsImmunedToSpellEffect(GetSpellInfo(), effIndex))
|
||||
itr->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() != existing->second || !CanBeAppliedOn(existing->first))
|
||||
if (appIter->second->GetEffectMask() != itr->second || !CanBeAppliedOn(itr->first))
|
||||
targetsToRemove.push_back(appIter->second->GetTarget());
|
||||
// nothing todo - aura already applied
|
||||
// remove from auras to register list
|
||||
targets.erase(existing);
|
||||
targets.erase(itr);
|
||||
}
|
||||
}
|
||||
|
||||
// register auras for units
|
||||
for (std::map<Unit*, uint8>::iterator itr = targets.begin(); itr != targets.end();)
|
||||
for (auto 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
|
||||
targets.erase(itr++);
|
||||
itr = targets.erase(itr);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
@@ -675,7 +675,7 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply)
|
||||
}
|
||||
}
|
||||
if (!addUnit)
|
||||
targets.erase(itr++);
|
||||
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 (UnitList::iterator itr = targetsToRemove.begin(); itr != targetsToRemove.end(); ++itr)
|
||||
if (AuraApplication* aurApp = GetApplicationOfTarget((*itr)->GetGUID()))
|
||||
(*itr)->_UnapplyAura(aurApp, AURA_REMOVE_BY_DEFAULT);
|
||||
for (Unit* unit : targetsToRemove)
|
||||
if (AuraApplication* aurApp = GetApplicationOfTarget(unit->GetGUID()))
|
||||
unit->_UnapplyAura(aurApp, AURA_REMOVE_BY_DEFAULT);
|
||||
|
||||
if (!apply)
|
||||
return;
|
||||
|
||||
// apply aura effects for units
|
||||
for (std::map<Unit*, uint8>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
|
||||
for (auto itr = targets.begin(); itr != targets.end(); ++itr)
|
||||
{
|
||||
if (AuraApplication* aurApp = GetApplicationOfTarget(itr->first->GetGUID()))
|
||||
{
|
||||
@@ -2660,72 +2660,85 @@ void UnitAura::Remove(AuraRemoveMode removeMode)
|
||||
GetUnitOwner()->RemoveOwnedAura(this, removeMode);
|
||||
}
|
||||
|
||||
void UnitAura::FillTargetMap(std::map<Unit*, uint8>& targets, Unit* caster)
|
||||
void UnitAura::FillTargetMap(std::unordered_map<Unit*, uint8>& targets, Unit* caster)
|
||||
{
|
||||
for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
|
||||
{
|
||||
if (!HasEffect(effIndex))
|
||||
continue;
|
||||
UnitList targetList;
|
||||
|
||||
std::deque<Unit*> units;
|
||||
|
||||
// non-area aura
|
||||
if (GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_APPLY_AURA)
|
||||
{
|
||||
targetList.push_back(GetUnitOwner());
|
||||
}
|
||||
units.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:
|
||||
{
|
||||
targetList.push_back(GetUnitOwner());
|
||||
Acore::AnyGroupedUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID);
|
||||
Acore::UnitListSearcher<Acore::AnyGroupedUnitInObjectRangeCheck> searcher(GetUnitOwner(), targetList, u_check);
|
||||
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<Acore::AnyGroupedUnitInObjectRangeCheck> searcher(GetUnitOwner(), units, u_check);
|
||||
Cell::VisitAllObjects(GetUnitOwner(), searcher, radius);
|
||||
break;
|
||||
}
|
||||
case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
|
||||
{
|
||||
targetList.push_back(GetUnitOwner());
|
||||
Acore::AnyFriendlyUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius);
|
||||
Acore::UnitListSearcher<Acore::AnyFriendlyUnitInObjectRangeCheck> searcher(GetUnitOwner(), targetList, u_check);
|
||||
units.push_back(GetUnitOwner());
|
||||
Acore::AnyFriendlyUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER));
|
||||
Acore::UnitListSearcher<Acore::AnyFriendlyUnitInObjectRangeCheck> searcher(GetUnitOwner(), units, u_check);
|
||||
Cell::VisitAllObjects(GetUnitOwner(), searcher, radius);
|
||||
break;
|
||||
}
|
||||
case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
|
||||
{
|
||||
Acore::AnyAoETargetUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius); // No GetCharmer in searcher
|
||||
Acore::UnitListSearcher<Acore::AnyAoETargetUnitInObjectRangeCheck> searcher(GetUnitOwner(), targetList, u_check);
|
||||
Acore::AnyAoETargetUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, m_spellInfo); // No GetCharmer in searcher
|
||||
Acore::UnitListSearcher<Acore::AnyAoETargetUnitInObjectRangeCheck> searcher(GetUnitOwner(), units, u_check);
|
||||
Cell::VisitAllObjects(GetUnitOwner(), searcher, radius);
|
||||
break;
|
||||
}
|
||||
case SPELL_EFFECT_APPLY_AREA_AURA_PET:
|
||||
targetList.push_back(GetUnitOwner());
|
||||
if (!condList || sConditionMgr->IsObjectMeetToConditions(GetUnitOwner(), ref, *condList))
|
||||
units.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))
|
||||
targetList.push_back(owner);
|
||||
if (!condList || sConditionMgr->IsObjectMeetToConditions(owner, ref, *condList))
|
||||
units.push_back(owner);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (selectionType != TARGET_CHECK_DEFAULT)
|
||||
{
|
||||
Acore::WorldObjectSpellAreaTargetCheck check(radius, GetUnitOwner(), ref, GetUnitOwner(), m_spellInfo, selectionType, condList);
|
||||
Acore::UnitListSearcher<Acore::WorldObjectSpellAreaTargetCheck> 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<Unit*, uint8>::iterator existing = targets.find(*itr);
|
||||
if (existing != targets.end())
|
||||
existing->second |= 1 << effIndex;
|
||||
else
|
||||
targets[*itr] = 1 << effIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2747,7 +2760,7 @@ void DynObjAura::Remove(AuraRemoveMode removeMode)
|
||||
_Remove(removeMode);
|
||||
}
|
||||
|
||||
void DynObjAura::FillTargetMap(std::map<Unit*, uint8>& targets, Unit* /*caster*/)
|
||||
void DynObjAura::FillTargetMap(std::unordered_map<Unit*, uint8>& targets, Unit* /*caster*/)
|
||||
{
|
||||
Unit* dynObjOwnerCaster = GetDynobjOwner()->GetCaster();
|
||||
float radius = GetDynobjOwner()->GetRadius();
|
||||
@@ -2756,12 +2769,13 @@ void DynObjAura::FillTargetMap(std::map<Unit*, uint8>& targets, Unit* /*caster*/
|
||||
{
|
||||
if (!HasEffect(effIndex))
|
||||
continue;
|
||||
UnitList targetList;
|
||||
|
||||
std::deque<Unit*> units;
|
||||
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);
|
||||
Acore::UnitListSearcher<Acore::AnyFriendlyUnitInObjectRangeCheck> searcher(GetDynobjOwner(), targetList, u_check);
|
||||
Acore::AnyFriendlyUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius, m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_ON_PLAYER));
|
||||
Acore::UnitListSearcher<Acore::AnyFriendlyUnitInObjectRangeCheck> searcher(GetDynobjOwner(), units, 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
|
||||
@@ -2769,30 +2783,35 @@ void DynObjAura::FillTargetMap(std::map<Unit*, uint8>& targets, Unit* /*caster*/
|
||||
else if (GetSpellInfo()->Effects[effIndex].TargetB.GetTarget() == TARGET_DEST_DYNOBJ_NONE)
|
||||
{
|
||||
Acore::AnyAttackableUnitExceptForOriginalCasterInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius);
|
||||
Acore::UnitListSearcher<Acore::AnyAttackableUnitExceptForOriginalCasterInObjectRangeCheck> searcher(GetDynobjOwner(), targetList, u_check);
|
||||
Acore::UnitListSearcher<Acore::AnyAttackableUnitExceptForOriginalCasterInObjectRangeCheck> searcher(GetDynobjOwner(), units, u_check);
|
||||
Cell::VisitAllObjects(GetDynobjOwner(), searcher, radius);
|
||||
}
|
||||
else
|
||||
{
|
||||
Acore::AnyAoETargetUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius);
|
||||
Acore::UnitListSearcher<Acore::AnyAoETargetUnitInObjectRangeCheck> searcher(GetDynobjOwner(), targetList, u_check);
|
||||
Acore::UnitListSearcher<Acore::AnyAoETargetUnitInObjectRangeCheck> searcher(GetDynobjOwner(), units, u_check);
|
||||
Cell::VisitAllObjects(GetDynobjOwner(), searcher, radius);
|
||||
}
|
||||
|
||||
for (UnitList::iterator itr = targetList.begin(); itr != targetList.end(); ++itr)
|
||||
for (Unit* unit : units)
|
||||
{
|
||||
// xinef: check z level and los dependence
|
||||
Unit* target = *itr;
|
||||
float zLevel = GetDynobjOwner()->GetPositionZ();
|
||||
if (target->GetPositionZ() + 3.0f < zLevel || target->GetPositionZ() - 5.0f > zLevel)
|
||||
if (!target->IsWithinLOSInMap(GetDynobjOwner()))
|
||||
if (unit->GetPositionZ() + 3.0f < zLevel || unit->GetPositionZ() - 5.0f > zLevel)
|
||||
{
|
||||
if (!unit->IsWithinLOSInMap(GetDynobjOwner()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
std::map<Unit*, uint8>::iterator existing = targets.find(*itr);
|
||||
if (existing != targets.end())
|
||||
existing->second |= 1 << effIndex;
|
||||
auto itr = targets.find(unit);
|
||||
if (itr != targets.end())
|
||||
{
|
||||
itr->second |= 1 << effIndex;
|
||||
}
|
||||
else
|
||||
targets[*itr] = 1 << effIndex;
|
||||
targets[unit] = 1 << effIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,11 @@ 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; }
|
||||
Unit* GetUnitOwner() const
|
||||
{
|
||||
ASSERT(GetType() == UNIT_AURA_TYPE);
|
||||
return (Unit*) m_owner->ToUnit();
|
||||
}
|
||||
DynamicObject* GetDynobjOwner() const { ASSERT(GetType() == DYNOBJ_AURA_TYPE); return (DynamicObject*)m_owner; }
|
||||
|
||||
AuraObjectType GetType() const;
|
||||
@@ -115,7 +119,7 @@ public:
|
||||
void _Remove(AuraRemoveMode removeMode);
|
||||
virtual void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) = 0;
|
||||
|
||||
virtual void FillTargetMap(std::map<Unit*, uint8>& targets, Unit* caster) = 0;
|
||||
virtual void FillTargetMap(std::unordered_map<Unit*, uint8>& targets, Unit* caster) = 0;
|
||||
void UpdateTargetMap(Unit* caster, bool apply = true);
|
||||
|
||||
void _RegisterForTargets() {Unit* caster = GetCaster(); UpdateTargetMap(caster, false);}
|
||||
@@ -284,7 +288,7 @@ public:
|
||||
|
||||
void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) override;
|
||||
|
||||
void FillTargetMap(std::map<Unit*, uint8>& targets, Unit* caster) override;
|
||||
void FillTargetMap(std::unordered_map<Unit*, uint8>& targets, Unit* caster) override;
|
||||
|
||||
// Allow Apply Aura Handler to modify and access m_AuraDRGroup
|
||||
void SetDiminishGroup(DiminishingGroup group) { m_AuraDRGroup = group; }
|
||||
@@ -304,6 +308,6 @@ protected:
|
||||
public:
|
||||
void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) override;
|
||||
|
||||
void FillTargetMap(std::map<Unit*, uint8>& targets, Unit* caster) override;
|
||||
void FillTargetMap(std::unordered_map<Unit*, uint8>& targets, Unit* caster) override;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -169,7 +169,7 @@ public:
|
||||
_initialSelection = false;
|
||||
// Find victim of Summon Gargoyle spell
|
||||
std::list<Unit*> targets;
|
||||
Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(me, me, 50);
|
||||
Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(me, me, 50.0f);
|
||||
Acore::UnitListSearcher<Acore::AnyUnfriendlyUnitInObjectRangeCheck> searcher(me, targets, u_check);
|
||||
Cell::VisitAllObjects(me, searcher, 50.0f);
|
||||
for (std::list<Unit*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)
|
||||
|
||||
Reference in New Issue
Block a user