refactor(Core/SmartScripts): GetTargets returns ObjectList instead of ObjectList* (#11950)

This commit is contained in:
IntelligentQuantum
2022-07-18 13:45:57 +04:30
committed by GitHub
parent cc52712ac1
commit 6ac7dfa26f
5 changed files with 2505 additions and 3309 deletions

View File

@@ -297,12 +297,12 @@ void SmartAI::EndPath(bool fail)
mEscortNPCFlags = 0;
}
ObjectList* targets = GetScript()->GetTargetList(SMART_ESCORT_TARGETS);
ObjectVector const* targets = GetScript()->GetStoredTargetVector(SMART_ESCORT_TARGETS);
if (targets && mEscortQuestID)
{
if (targets->size() == 1 && GetScript()->IsPlayer((*targets->begin())))
{
Player* player = (*targets->begin())->ToPlayer();
Player* player = targets->front()->ToPlayer();
if (Group* group = player->GetGroup())
{
for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next())
@@ -327,11 +327,11 @@ void SmartAI::EndPath(bool fail)
}
else
{
for (ObjectList::iterator iter = targets->begin(); iter != targets->end(); ++iter)
for (WorldObject* target : *targets)
{
if (GetScript()->IsPlayer((*iter)))
if (GetScript()->IsPlayer(target))
{
Player* player = (*iter)->ToPlayer();
Player* player = target->ToPlayer();
if (!fail && player->IsAtGroupRewardDistance(me) && !player->HasCorpse())
player->AreaExploredOrEventHappens(mEscortQuestID);
else if (fail && player->GetQuestStatus(mEscortQuestID) == QUEST_STATUS_INCOMPLETE)
@@ -535,8 +535,7 @@ void SmartAI::UpdateAI(uint32 diff)
bool SmartAI::IsEscortInvokerInRange()
{
ObjectList* targets = GetScript()->GetTargetList(SMART_ESCORT_TARGETS);
if (targets)
if (ObjectVector const* targets = GetScript()->GetStoredTargetVector(SMART_ESCORT_TARGETS))
{
float checkDist = me->GetInstanceScript() ? SMART_ESCORT_MAX_PLAYER_DIST * 2 : SMART_ESCORT_MAX_PLAYER_DIST;
if (targets->size() == 1 && GetScript()->IsPlayer((*targets->begin())))
@@ -558,11 +557,11 @@ bool SmartAI::IsEscortInvokerInRange()
}
else
{
for (ObjectList::iterator iter = targets->begin(); iter != targets->end(); ++iter)
for (WorldObject* target : *targets)
{
if (GetScript()->IsPlayer((*iter)))
if (GetScript()->IsPlayer(target))
{
if (me->GetDistance((*iter)->ToPlayer()) <= checkDist)
if (me->GetDistance(target->ToPlayer()) <= checkDist)
return true;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -39,19 +39,19 @@ public:
void ProcessEventsFor(SMART_EVENT e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, SpellInfo const* spell = nullptr, GameObject* gob = nullptr);
void ProcessEvent(SmartScriptHolder& e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, SpellInfo const* spell = nullptr, GameObject* gob = nullptr);
bool CheckTimer(SmartScriptHolder const& e) const;
void RecalcTimer(SmartScriptHolder& e, uint32 min, uint32 max);
static void RecalcTimer(SmartScriptHolder& e, uint32 min, uint32 max);
void UpdateTimer(SmartScriptHolder& e, uint32 const diff);
void InitTimer(SmartScriptHolder& e);
static void InitTimer(SmartScriptHolder& e);
void ProcessAction(SmartScriptHolder& e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, SpellInfo const* spell = nullptr, GameObject* gob = nullptr);
void ProcessTimedAction(SmartScriptHolder& e, uint32 const& min, uint32 const& max, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, SpellInfo const* spell = nullptr, GameObject* gob = nullptr);
ObjectList* GetTargets(SmartScriptHolder const& e, Unit* invoker = nullptr);
ObjectList* GetWorldObjectsInDist(float dist);
void GetTargets(ObjectVector& targets, SmartScriptHolder const& e, Unit* invoker = nullptr) const;
void GetWorldObjectsInDist(ObjectVector& objects, float dist) const;
void InstallTemplate(SmartScriptHolder const& e);
SmartScriptHolder CreateSmartEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, uint32 event_param5, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 target_param4, uint32 phaseMask);
static SmartScriptHolder CreateSmartEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, uint32 event_param5, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 target_param4, uint32 phaseMask);
void AddEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, uint32 event_param5, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 target_param4, uint32 phaseMask);
void SetPathId(uint32 id) { mPathId = id; }
uint32 GetPathId() const { return mPathId; }
WorldObject* GetBaseObject()
WorldObject* GetBaseObject() const
{
WorldObject* obj = nullptr;
if (me)
@@ -70,27 +70,17 @@ public:
void OnUpdate(const uint32 diff);
void OnMoveInLineOfSight(Unit* who);
Unit* DoSelectLowestHpFriendly(float range, uint32 MinHPDiff);
Unit* DoSelectLowestHpFriendly(float range, uint32 MinHPDiff) const;
Unit* DoSelectLowestHpPercentFriendly(float range, uint32 minHpPct, uint32 maxHpPct) const;
void DoFindFriendlyCC(std::list<Creature*>& _list, float range);
void DoFindFriendlyMissingBuff(std::list<Creature*>& list, float range, uint32 spellid);
Unit* DoFindClosestFriendlyInRange(float range, bool playerOnly);
void DoFindFriendlyCC(std::vector<Creature*>& creatures, float range) const;
void DoFindFriendlyMissingBuff(std::vector<Creature*>& creatures, float range, uint32 spellid) const;
Unit* DoFindClosestFriendlyInRange(float range, bool playerOnly) const;
void StoreTargetList(ObjectList* targets, uint32 id)
void StoreTargetList(ObjectVector const& targets, uint32 id)
{
if (!targets)
return;
if (mTargetStorage->find(id) != mTargetStorage->end())
{
// check if already stored
if ((*mTargetStorage)[id]->Equals(targets))
return;
delete (*mTargetStorage)[id];
}
(*mTargetStorage)[id] = new ObjectGuidList(targets, GetBaseObject());
// insert or replace
_storedTargets.erase(id);
_storedTargets.emplace(id, ObjectGuidVector(GetBaseObject(), targets));
}
bool IsSmart(Creature* c = nullptr)
@@ -122,11 +112,11 @@ public:
return smart;
}
ObjectList* GetTargetList(uint32 id)
ObjectVector const* GetStoredTargetVector(uint32 id) const
{
ObjectListMap::iterator itr = mTargetStorage->find(id);
if (itr != mTargetStorage->end())
return (*itr).second->GetObjectList();
auto itr = _storedTargets.find(id);
if (itr != _storedTargets.end())
return itr->second.GetObjectVector();
return nullptr;
}
@@ -187,8 +177,6 @@ public:
return creatureItr != bounds.second ? creatureItr->second : bounds.first->second;
}
ObjectListMap* mTargetStorage;
void OnReset();
void ResetBaseObject()
{
@@ -223,7 +211,7 @@ public:
//TIMED_ACTIONLIST (script type 9 aka script9)
void SetScript9(SmartScriptHolder& e, uint32 entry);
Unit* GetLastInvoker(Unit* invoker = nullptr);
Unit* GetLastInvoker(Unit* invoker = nullptr) const;
ObjectGuid mLastInvoker;
typedef std::unordered_map<uint32, uint32> CounterMap;
CounterMap mCounterList;
@@ -284,6 +272,8 @@ private:
// Xinef: misc
bool _allowPhaseReset;
ObjectVectorMap _storedTargets;
SMARTAI_TEMPLATE mTemplate;
void InstallEvents();

View File

@@ -1358,24 +1358,39 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
break;
}
case SMART_ACTION_RANDOM_EMOTE:
if (e.action.randomEmote.emote1 && !IsEmoteValid(e, e.action.randomEmote.emote1))
return false;
{
if (std::all_of(e.action.randomEmote.emotes.begin(), e.action.randomEmote.emotes.end(), [](uint32 emote) { return emote == 0; }))
{
LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} does not have any non-zero emote",
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
return false;
}
if (e.action.randomEmote.emote2 && !IsEmoteValid(e, e.action.randomEmote.emote2))
return false;
if (e.action.randomEmote.emote3 && !IsEmoteValid(e, e.action.randomEmote.emote3))
return false;
if (e.action.randomEmote.emote4 && !IsEmoteValid(e, e.action.randomEmote.emote4))
return false;
if (e.action.randomEmote.emote5 && !IsEmoteValid(e, e.action.randomEmote.emote5))
return false;
if (e.action.randomEmote.emote6 && !IsEmoteValid(e, e.action.randomEmote.emote6))
return false;
break;
for (uint32 emote : e.action.randomEmote.emotes)
if (emote && !IsEmoteValid(e, emote))
return false;
break;
}
case SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST:
{
if (std::all_of(e.action.randTimedActionList.actionLists.begin(), e.action.randTimedActionList.actionLists.end(), [](uint32 actionList) { return actionList == 0; }))
{
LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} does not have any non-zero action list",
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
return false;
}
break;
}
case SMART_ACTION_START_CLOSEST_WAYPOINT:
{
if (std::all_of(e.action.closestWaypointFromList.wps.begin(), e.action.closestWaypointFromList.wps.end(), [](uint32 wp) { return wp == 0; }))
{
LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} does not have any non-zero waypoint id",
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
return false;
}
break;
}
case SMART_ACTION_CAST:
case SMART_ACTION_INVOKER_CAST:
if (!IsSpellValid(e, e.action.cast.spell))
@@ -1434,36 +1449,29 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
break;
case SMART_ACTION_RANDOM_PHASE:
{
if (e.action.randomPhase.phase1 >= SMART_EVENT_PHASE_MAX ||
e.action.randomPhase.phase2 >= SMART_EVENT_PHASE_MAX ||
e.action.randomPhase.phase3 >= SMART_EVENT_PHASE_MAX ||
e.action.randomPhase.phase4 >= SMART_EVENT_PHASE_MAX ||
e.action.randomPhase.phase5 >= SMART_EVENT_PHASE_MAX ||
e.action.randomPhase.phase6 >= SMART_EVENT_PHASE_MAX)
{
LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} attempts to set invalid phase, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
return false;
}
if (e.action.randomPhase.phase1 == 0 &&
e.action.randomPhase.phase2 == 0 &&
e.action.randomPhase.phase3 == 0 &&
e.action.randomPhase.phase4 == 0 &&
e.action.randomPhase.phase5 == 0 &&
e.action.randomPhase.phase6 == 0)
if (std::all_of(e.action.randomPhase.phases.begin(), e.action.randomPhase.phases.end(), [](uint32 phase) { return phase == 0; }))
{
LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} does not have any non-zero phase",
e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
return false;
}
if (std::any_of(e.action.randomPhase.phases.begin(), e.action.randomPhase.phases.end(), [](uint32 phase) { return phase >= SMART_EVENT_PHASE_MAX; }))
{
LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} attempts to set invalid phase, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
return false;
}
break;
}
break;
case SMART_ACTION_RANDOM_PHASE_RANGE: //PhaseMin, PhaseMax
{
if (e.action.randomPhaseRange.phaseMin >= SMART_EVENT_PHASE_MAX ||
e.action.randomPhaseRange.phaseMax >= SMART_EVENT_PHASE_MAX)
e.action.randomPhaseRange.phaseMax >= SMART_EVENT_PHASE_MAX)
{
LOG_ERROR("sql.sql", "SmartAIMgr: Entry {} SourceType {} Event {} Action {} attempts to set invalid phase, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
return false;
}
if (!IsMinMaxValid(e, e.action.randomPhaseRange.phaseMin, e.action.randomPhaseRange.phaseMax))
return false;
break;
@@ -1570,7 +1578,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
}
case SMART_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST:
{
if (!IsMinMaxValid(e, e.action.randRangeTimedActionList.idMin, e.action.randRangeTimedActionList.idMax))
if (!IsMinMaxValid(e, e.action.randTimedActionList.actionLists[0], e.action.randTimedActionList.actionLists[1]))
return false;
break;
}
@@ -1625,12 +1633,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
{
if (e.GetScriptType() == SMART_SCRIPT_TYPE_CREATURE)
{
int8 equipId = (int8)e.action.equip.entry;
if (equipId)
if (int8 equipId = static_cast<int8>(e.action.equip.entry))
{
EquipmentInfo const* einfo = sObjectMgr->GetEquipmentInfo(e.entryOrGuid, equipId);
if (!einfo)
EquipmentInfo const* eInfo = sObjectMgr->GetEquipmentInfo(e.entryOrGuid, equipId);
if (!eInfo)
{
LOG_ERROR("scripts.ai.sai", "SmartScript: SMART_ACTION_EQUIP uses non-existent equipment info id {} for creature {}, skipped.", equipId, e.entryOrGuid);
return false;
@@ -1783,7 +1789,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
case SMART_ACTION_MOVE_TO_POS:
case SMART_ACTION_EVADE:
case SMART_ACTION_SET_ACTIVE:
case SMART_ACTION_START_CLOSEST_WAYPOINT:
case SMART_ACTION_FOLLOW:
case SMART_ACTION_SET_ORIENTATION:
case SMART_ACTION_STORE_TARGET_LIST:
@@ -1818,7 +1823,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
case SMART_ACTION_SET_NPC_FLAG:
case SMART_ACTION_ADD_NPC_FLAG:
case SMART_ACTION_REMOVE_NPC_FLAG:
case SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST:
case SMART_ACTION_RANDOM_MOVE:
case SMART_ACTION_SET_UNIT_FIELD_BYTES_1:
case SMART_ACTION_REMOVE_UNIT_FIELD_BYTES_1:

View File

@@ -49,6 +49,16 @@ struct WayPoint
uint32 delay;
};
enum eSmartAI
{
SMART_EVENT_PARAM_COUNT = 4,
SMART_ACTION_PARAM_COUNT = 6,
SMART_SUMMON_COUNTER = 0xFFFFFF,
SMART_ESCORT_LAST_OOC_POINT = 0xFFFFFF,
SMART_RANDOM_POINT = 0xFFFFFE,
SMART_ESCORT_TARGETS = 0xFFFFFF
};
enum SMART_EVENT_PHASE
{
SMART_EVENT_PHASE_ALWAYS = 0,
@@ -758,12 +768,7 @@ struct SmartAction
struct
{
uint32 emote1;
uint32 emote2;
uint32 emote3;
uint32 emote4;
uint32 emote5;
uint32 emote6;
std::array<uint32, SMART_ACTION_PARAM_COUNT> emotes;
} randomEmote;
struct
@@ -858,12 +863,7 @@ struct SmartAction
struct
{
uint32 phase1;
uint32 phase2;
uint32 phase3;
uint32 phase4;
uint32 phase5;
uint32 phase6;
std::array<uint32, SMART_ACTION_PARAM_COUNT> phases;
} randomPhase;
struct
@@ -1049,9 +1049,7 @@ struct SmartAction
{
uint32 entry;
uint32 mask;
uint32 slot1;
uint32 slot2;
uint32 slot3;
std::array<uint32, MAX_EQUIPMENT_ITEMS> slots;
} equip;
struct
@@ -1086,12 +1084,7 @@ struct SmartAction
struct
{
uint32 entry1;
uint32 entry2;
uint32 entry3;
uint32 entry4;
uint32 entry5;
uint32 entry6;
std::array<uint32, SMART_ACTION_PARAM_COUNT> actionLists;
} randTimedActionList;
struct
@@ -1209,12 +1202,7 @@ struct SmartAction
struct
{
uint32 wp1;
uint32 wp2;
uint32 wp3;
uint32 wp4;
uint32 wp5;
uint32 wp6;
std::array<uint32, SMART_ACTION_PARAM_COUNT> wps;
} closestWaypointFromList;
struct
@@ -1584,16 +1572,6 @@ enum SmartTargetRoleFlags
SMART_TARGET_ROLE_FLAG_DAMAGERS = 0x004
};
enum eSmartAI
{
SMART_EVENT_PARAM_COUNT = 4,
SMART_ACTION_PARAM_COUNT = 6,
SMART_SUMMON_COUNTER = 0xFFFFFF,
SMART_ESCORT_LAST_OOC_POINT = 0xFFFFFF,
SMART_RANDOM_POINT = 0xFFFFFE,
SMART_ESCORT_TARGETS = 0xFFFFFF
};
enum SmartScriptType
{
SMART_SCRIPT_TYPE_CREATURE = 0, //done
@@ -1802,60 +1780,43 @@ public:
typedef std::unordered_map<uint32, WayPoint*> WPPath;
typedef std::list<WorldObject*> ObjectList;
typedef std::vector<WorldObject*> ObjectVector;
class ObjectGuidList
class ObjectGuidVector
{
ObjectList* m_objectList;
GuidList* m_guidList;
WorldObject* m_baseObject;
public:
ObjectGuidList(ObjectList* objectList, WorldObject* baseObject)
ObjectGuidVector(WorldObject* baseObject, ObjectVector const& objectVector) : _baseObject(baseObject), _objectVector(objectVector)
{
ASSERT(objectList);
m_objectList = objectList;
m_baseObject = baseObject;
m_guidList = new GuidList();
for (ObjectList::iterator itr = objectList->begin(); itr != objectList->end(); ++itr)
{
m_guidList->push_back((*itr)->GetGUID());
}
_guidVector.reserve(_objectVector.size());
for (WorldObject* obj : _objectVector)
_guidVector.push_back(obj->GetGUID());
}
ObjectList* GetObjectList()
ObjectVector const* GetObjectVector() const
{
if (m_baseObject)
{
//sanitize list using m_guidList
m_objectList->clear();
for (GuidList::iterator itr = m_guidList->begin(); itr != m_guidList->end(); ++itr)
{
if (WorldObject* obj = ObjectAccessor::GetWorldObject(*m_baseObject, *itr))
m_objectList->push_back(obj);
//else
// LOG_DEBUG("scripts.ai", "SmartScript::mTargetStorage stores a guid to an invalid object: {}", (*itr).ToString());
}
}
return m_objectList;
UpdateObjects();
return &_objectVector;
}
bool Equals(ObjectList* objectList)
{
return m_objectList == objectList;
}
~ObjectGuidVector() { }
~ObjectGuidList()
private:
WorldObject* const _baseObject;
mutable ObjectVector _objectVector;
GuidVector _guidVector;
//sanitize vector using _guidVector
void UpdateObjects() const
{
delete m_objectList;
delete m_guidList;
_objectVector.clear();
for (ObjectGuid const& guid : _guidVector)
if (WorldObject* obj = ObjectAccessor::GetWorldObject(*_baseObject, guid))
_objectVector.push_back(obj);
}
};
typedef std::unordered_map<uint32, ObjectGuidList*> ObjectListMap;
typedef std::unordered_map<uint32, ObjectGuidVector> ObjectVectorMap;
class SmartWaypointMgr
{