aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2017-06-03 10:21:06 +0200
committerCarbenium <carbenium@outlook.com>2020-07-16 20:59:25 +0200
commit259bde591444980c27a17524c140f078c4159f55 (patch)
tree60043db1cbdc52692608421e23bf2d0c01e0b047 /src
parenteb7d09b0b7bf2e5cb3bb4ab0b5a1c6def37395f9 (diff)
Core/SAI: Change SmartScript::GetTargets to return an ObjectList instead of a ObjectList*
Applied the same treatment to GetWorldObjectsInDist Honestly no idea why the original idea insisted so much on using pointers. No more missing null checks or deletes. SmartAI's "ObjectList" is now a std::vector instead of a std::list because no where it was being used as an actual list. Original idea by DDuarte :P (cherry picked from commit a97439e8d63c0a78bda8a6ed4801f122385936e3)
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp20
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp1987
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.h42
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp130
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h84
5 files changed, 780 insertions, 1483 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index 065ca31bee0..a99fb660383 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -236,12 +236,12 @@ void SmartAI::EndPath(bool fail)
else
GetScript()->SetPathId(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 (!fail && player->IsAtGroupRewardDistance(me) && !player->HasCorpse())
player->GroupEventHappens(mEscortQuestID, me);
@@ -265,11 +265,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)
@@ -278,6 +278,7 @@ void SmartAI::EndPath(bool fail)
}
}
}
+
if (mDespawnState == 1)
StartDespawn();
}
@@ -409,8 +410,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())))
@@ -431,11 +431,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;
}
}
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index a1c6d3af9b6..39ce2b88022 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -50,7 +50,6 @@ SmartScript::SmartScript()
sceneTemplate = nullptr;
mEventPhase = 0;
mPathId = 0;
- mTargetStorage = new ObjectListMap();
mTextTimer = 0;
mLastTextID = 0;
mUseTextTimer = false;
@@ -62,11 +61,6 @@ SmartScript::SmartScript()
SmartScript::~SmartScript()
{
- for (ObjectListMap::iterator itr = mTargetStorage->begin(); itr != mTargetStorage->end(); ++itr)
- delete itr->second;
-
- delete mTargetStorage;
- mCounterList.clear();
}
bool SmartScript::IsSmart(Creature* c /*= NULL*/)
@@ -98,31 +92,6 @@ bool SmartScript::IsSmartGO(GameObject* g /*= NULL*/)
return smart;
}
-void SmartScript::StoreTargetList(ObjectList* 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());
-}
-
-ObjectList* SmartScript::GetTargetList(uint32 id)
-{
- ObjectListMap::iterator itr = mTargetStorage->find(id);
- if (itr != mTargetStorage->end())
- return (*itr).second->GetObjectList();
- return NULL;
-}
-
void SmartScript::StoreCounter(uint32 id, uint32 value, uint32 reset)
{
CounterMap::iterator itr = mCounterList.find(id);
@@ -231,7 +200,7 @@ void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint3
void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob, std::string const& varString)
{
- //calc random
+ // calc random
if (e.GetEventType() != SMART_EVENT_LINK && e.event.event_chance < 100 && e.event.event_chance)
{
if (!roll_chance_i(e.event.event_chance))
@@ -245,38 +214,35 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (Unit* tempInvoker = GetLastInvoker())
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: Invoker: %s (%s)", tempInvoker->GetName().c_str(), tempInvoker->GetGUID().ToString().c_str());
+ ObjectVector targets;
+ GetTargets(targets, e, unit);
+
switch (e.GetActionType())
{
case SMART_ACTION_TALK:
{
- ObjectList* targets = GetTargets(e, unit);
Creature* talker = e.target.type == 0 ? me : nullptr;
Unit* talkTarget = nullptr;
- if (targets)
+ for (WorldObject* target : targets)
{
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ if (IsCreature(target) && !target->ToCreature()->IsPet()) // Prevented sending text to pets.
{
- if (IsCreature(*itr) && !(*itr)->ToCreature()->IsPet()) // Prevented sending text to pets.
- {
- if (e.action.talk.useTalkTarget)
- {
- talker = me;
- talkTarget = (*itr)->ToCreature();
- }
- else
- talker = (*itr)->ToCreature();
- break;
- }
- else if (IsPlayer(*itr))
+ if (e.action.talk.useTalkTarget)
{
talker = me;
- talkTarget = (*itr)->ToPlayer();
- break;
+ talkTarget = target->ToCreature();
}
+ else
+ talker = target->ToCreature();
+ break;
+ }
+ else if (IsPlayer(target))
+ {
+ talker = me;
+ talkTarget = target->ToPlayer();
+ break;
}
-
- delete targets;
}
if (!talkTarget)
@@ -296,107 +262,79 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
case SMART_ACTION_SIMPLE_TALK:
{
- ObjectList* targets = GetTargets(e, unit);
- if (targets)
+ for (WorldObject* target : targets)
{
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ if (IsCreature(target))
+ sCreatureTextMgr->SendChat(target->ToCreature(), uint8(e.action.talk.textGroupID), IsPlayer(GetLastInvoker()) ? GetLastInvoker() : 0);
+ else if (IsPlayer(target) && me)
{
- if (IsCreature(*itr))
- sCreatureTextMgr->SendChat((*itr)->ToCreature(), uint8(e.action.talk.textGroupID), IsPlayer(GetLastInvoker()) ? GetLastInvoker() : 0);
- else if (IsPlayer(*itr) && me)
- {
- Unit* templastInvoker = GetLastInvoker();
- sCreatureTextMgr->SendChat(me, uint8(e.action.talk.textGroupID), IsPlayer(templastInvoker) ? templastInvoker : 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, (*itr)->ToPlayer());
- }
- TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SIMPLE_TALK: talker: %s (%s), textGroupId: %u",
- (*itr)->GetName().c_str(), (*itr)->GetGUID().ToString().c_str(), uint8(e.action.talk.textGroupID));
+ Unit* templastInvoker = GetLastInvoker();
+ sCreatureTextMgr->SendChat(me, uint8(e.action.talk.textGroupID), IsPlayer(templastInvoker) ? templastInvoker : 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, target->ToPlayer());
}
-
- delete targets;
+ TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SIMPLE_TALK: talker: %s (%s), textGroupId: %u",
+ target->GetName().c_str(), target->GetGUID().ToString().c_str(), uint8(e.action.talk.textGroupID));
}
break;
}
case SMART_ACTION_PLAY_EMOTE:
{
- ObjectList* targets = GetTargets(e, unit);
- if (targets)
+ for (WorldObject* target : targets)
{
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ if (IsUnit(target))
{
- if (IsUnit(*itr))
- {
- (*itr)->ToUnit()->HandleEmoteCommand(e.action.emote.emote);
- TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_PLAY_EMOTE: target: %s (%s), emote: %u",
- (*itr)->GetName().c_str(), (*itr)->GetGUID().ToString().c_str(), e.action.emote.emote);
- }
+ target->ToUnit()->HandleEmoteCommand(e.action.emote.emote);
+ TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_PLAY_EMOTE: target: %s (%s), emote: %u",
+ target->GetName().c_str(), target->GetGUID().ToString().c_str(), e.action.emote.emote);
}
-
- delete targets;
}
break;
}
case SMART_ACTION_SOUND:
{
- ObjectList* targets = GetTargets(e, unit);
- if (targets)
+ for (WorldObject* target : targets)
{
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ if (IsUnit(target))
{
- if (IsUnit(*itr))
- {
- (*itr)->PlayDirectSound(e.action.sound.sound, e.action.sound.onlySelf ? (*itr)->ToPlayer() : nullptr);
- TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SOUND: target: %s (%s), sound: %u, onlyself: %u",
- (*itr)->GetName().c_str(), (*itr)->GetGUID().ToString().c_str(), e.action.sound.sound, e.action.sound.onlySelf);
- }
+ target->PlayDirectSound(e.action.sound.sound, e.action.sound.onlySelf ? target->ToPlayer() : nullptr);
+ TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SOUND: target: %s (%s), sound: %u, onlyself: %u",
+ target->GetName().c_str(), target->GetGUID().ToString().c_str(), e.action.sound.sound, e.action.sound.onlySelf);
}
-
- delete targets;
}
break;
}
case SMART_ACTION_SET_FACTION:
{
- ObjectList* targets = GetTargets(e, unit);
- if (targets)
+ for (WorldObject* target : targets)
{
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ if (IsCreature(target))
{
- if (IsCreature(*itr))
+ if (e.action.faction.factionID)
{
- if (e.action.faction.factionID)
- {
- (*itr)->ToCreature()->SetFaction(e.action.faction.factionID);
- TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_FACTION: Creature entry %u, %s set faction to %u",
- (*itr)->GetEntry(), (*itr)->GetGUID().ToString().c_str(), e.action.faction.factionID);
- }
- else
+ target->ToCreature()->SetFaction(e.action.faction.factionID);
+ TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_FACTION: Creature entry %u, %s set faction to %u",
+ target->GetEntry(), target->GetGUID().ToString().c_str(), e.action.faction.factionID);
+ }
+ else
+ {
+ if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(target->ToCreature()->GetEntry()))
{
- if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate((*itr)->ToCreature()->GetEntry()))
+ if (target->ToCreature()->GetFaction() != ci->faction)
{
- if ((*itr)->ToCreature()->GetFaction() != ci->faction)
- {
- (*itr)->ToCreature()->SetFaction(ci->faction);
- TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_FACTION: Creature entry %u, %s set faction to %u",
- (*itr)->GetEntry(), (*itr)->GetGUID().ToString().c_str(), ci->faction);
- }
+ target->ToCreature()->SetFaction(ci->faction);
+ TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_FACTION: Creature entry %u, %s set faction to %u",
+ target->GetEntry(), target->GetGUID().ToString().c_str(), ci->faction);
}
}
}
}
-
- delete targets;
}
break;
}
case SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (!IsCreature(*itr))
+ if (!IsCreature(target))
continue;
if (e.action.morphOrMount.creature || e.action.morphOrMount.model)
@@ -407,143 +345,99 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(e.action.morphOrMount.creature))
{
CreatureModel const* model = ObjectMgr::ChooseDisplayId(ci);
- (*itr)->ToCreature()->SetDisplayId(model->CreatureDisplayID, model->DisplayScale);
+ target->ToCreature()->SetDisplayId(model->CreatureDisplayID, model->DisplayScale);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: Creature entry %u, %s set displayid to %u",
- (*itr)->GetEntry(), (*itr)->GetGUID().ToString().c_str(), model->CreatureDisplayID);
+ target->GetEntry(), target->GetGUID().ToString().c_str(), model->CreatureDisplayID);
}
}
//if no param1, then use value from param2 (modelId)
else
{
- (*itr)->ToCreature()->SetDisplayId(e.action.morphOrMount.model);
+ target->ToCreature()->SetDisplayId(e.action.morphOrMount.model);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: Creature entry %u, %s set displayid to %u",
- (*itr)->GetEntry(), (*itr)->GetGUID().ToString().c_str(), e.action.morphOrMount.model);
+ target->GetEntry(), target->GetGUID().ToString().c_str(), e.action.morphOrMount.model);
}
}
else
{
- (*itr)->ToCreature()->DeMorph();
+ target->ToCreature()->DeMorph();
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: Creature entry %u, %s demorphs.",
- (*itr)->GetEntry(), (*itr)->GetGUID().ToString().c_str());
+ target->GetEntry(), target->GetGUID().ToString().c_str());
}
}
-
- delete targets;
break;
}
case SMART_ACTION_FAIL_QUEST:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (IsPlayer(*itr))
+ if (IsPlayer(target))
{
- (*itr)->ToPlayer()->FailQuest(e.action.quest.quest);
+ target->ToPlayer()->FailQuest(e.action.quest.quest);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_FAIL_QUEST: Player %s fails quest %u",
- (*itr)->GetGUID().ToString().c_str(), e.action.quest.quest);
+ target->GetGUID().ToString().c_str(), e.action.quest.quest);
}
}
-
- delete targets;
break;
}
case SMART_ACTION_OFFER_QUEST:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (Player* pTarget = (*itr)->ToPlayer())
+ if (Player* player = target->ToPlayer())
{
if (Quest const* q = sObjectMgr->GetQuestTemplate(e.action.questOffer.questID))
{
if (me && e.action.questOffer.directAdd == 0)
{
- if (pTarget->CanTakeQuest(q, true))
- if (WorldSession* session = pTarget->GetSession())
+ if (player->CanTakeQuest(q, true))
+ {
+ if (WorldSession* session = player->GetSession())
{
PlayerMenu menu(session);
menu.SendQuestGiverQuestDetails(q, me->GetGUID(), true, false);
- TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_OFFER_QUEST: Player %s - offering quest %u", pTarget->GetGUID().ToString().c_str(), e.action.questOffer.questID);
+ TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_OFFER_QUEST: Player %s - offering quest %u", player->GetGUID().ToString().c_str(), e.action.questOffer.questID);
}
+ }
}
else
{
- (*itr)->ToPlayer()->AddQuestAndCheckCompletion(q, nullptr);
- TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_ADD_QUEST: Player %s add quest %u",
- (*itr)->GetGUID().ToString().c_str(), e.action.questOffer.questID);
+ player->AddQuestAndCheckCompletion(q, nullptr);
+ TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_OFFER_QUEST: Player %s - quest %u added",
+ player->GetGUID().ToString().c_str(), e.action.questOffer.questID);
}
}
}
}
-
- delete targets;
break;
}
case SMART_ACTION_SET_REACT_STATE:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (!IsCreature(*itr))
+ if (!IsCreature(target))
continue;
- (*itr)->ToCreature()->SetReactState(ReactStates(e.action.react.state));
+ target->ToCreature()->SetReactState(ReactStates(e.action.react.state));
}
-
- delete targets;
break;
}
case SMART_ACTION_RANDOM_EMOTE:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
+ std::vector<uint32> emotes;
+ std::copy_if(e.action.randomEmote.emotes.begin(), e.action.randomEmote.emotes.end(),
+ std::back_inserter(emotes), [](uint32 emote) { return emote != 0; });
- uint32 emotes[SMART_ACTION_PARAM_COUNT];
- emotes[0] = e.action.randomEmote.emote1;
- emotes[1] = e.action.randomEmote.emote2;
- emotes[2] = e.action.randomEmote.emote3;
- emotes[3] = e.action.randomEmote.emote4;
- emotes[4] = e.action.randomEmote.emote5;
- emotes[5] = e.action.randomEmote.emote6;
- uint32 temp[SMART_ACTION_PARAM_COUNT];
- uint32 count = 0;
- for (uint8 i = 0; i < SMART_ACTION_PARAM_COUNT; i++)
+ for (WorldObject* target : targets)
{
- if (emotes[i])
+ if (IsUnit(target))
{
- temp[count] = emotes[i];
- ++count;
- }
- }
-
- if (count == 0)
- {
- delete targets;
- break;
- }
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- {
- if (IsUnit(*itr))
- {
- uint32 emote = temp[urand(0, count - 1)];
- (*itr)->ToUnit()->HandleEmoteCommand(emote);
+ uint32 emote = Trinity::Containers::SelectRandomContainerElement(emotes);
+ target->ToUnit()->HandleEmoteCommand(emote);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_RANDOM_EMOTE: Creature %s handle random emote %u",
- (*itr)->GetGUID().ToString().c_str(), emote);
+ target->GetGUID().ToString().c_str(), emote);
}
}
-
- delete targets;
break;
}
case SMART_ACTION_THREAT_ALL_PCT:
@@ -552,7 +446,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
break;
ThreatContainer::StorageType threatList = me->getThreatManager().getThreatList();
- for (ThreatContainer::StorageType::const_iterator i = threatList.begin(); i != threatList.end(); ++i)
+ for (auto i = threatList.begin(); i != threatList.end(); ++i)
{
if (Unit* target = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid()))
{
@@ -569,72 +463,57 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!me)
break;
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (IsUnit(*itr))
+ if (IsUnit(target))
{
- me->getThreatManager().modifyThreatPercent((*itr)->ToUnit(), e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC);
+ me->getThreatManager().modifyThreatPercent(target->ToUnit(), e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_THREAT_SINGLE_PCT: Creature %s modify threat for %s, value %i",
- me->GetGUID().ToString().c_str(), (*itr)->GetGUID().ToString().c_str(),
+ me->GetGUID().ToString().c_str(), target->GetGUID().ToString().c_str(),
e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC);
}
}
-
- delete targets;
break;
}
case SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
// Special handling for vehicles
- if (IsUnit(*itr))
- if (Vehicle* vehicle = (*itr)->ToUnit()->GetVehicleKit())
+ if (IsUnit(target))
+ if (Vehicle* vehicle = target->ToUnit()->GetVehicleKit())
for (SeatMap::iterator it = vehicle->Seats.begin(); it != vehicle->Seats.end(); ++it)
- if (Player* player = ObjectAccessor::GetPlayer(*(*itr), it->second.Passenger.Guid))
+ if (Player* player = ObjectAccessor::GetPlayer(*target, it->second.Passenger.Guid))
player->AreaExploredOrEventHappens(e.action.quest.quest);
- if (IsPlayer(*itr))
+ if (IsPlayer(target))
{
- (*itr)->ToPlayer()->AreaExploredOrEventHappens(e.action.quest.quest);
+ target->ToPlayer()->AreaExploredOrEventHappens(e.action.quest.quest);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS: %s credited quest %u",
- (*itr)->GetGUID().ToString().c_str(), e.action.quest.quest);
+ target->GetGUID().ToString().c_str(), e.action.quest.quest);
}
}
-
- delete targets;
break;
}
case SMART_ACTION_CAST:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
+ if (targets.empty())
break;
- if (e.action.cast.targetsLimit > 0 && targets->size() > e.action.cast.targetsLimit)
- Trinity::Containers::RandomResize(*targets, e.action.cast.targetsLimit);
+ if (e.action.cast.targetsLimit > 0 && targets.size() > e.action.cast.targetsLimit)
+ Trinity::Containers::RandomResize(targets, e.action.cast.targetsLimit);
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
+ // may be nullptr
if (go)
- {
- // may be nullptr
- go->CastSpell((*itr)->ToUnit(), e.action.cast.spell);
- }
+ go->CastSpell(target->ToUnit(), e.action.cast.spell);
- if (!IsUnit(*itr))
+ if (!IsUnit(target))
continue;
- if (!(e.action.cast.castFlags & SMARTCAST_AURA_NOT_PRESENT) || !(*itr)->ToUnit()->HasAura(e.action.cast.spell))
+ if (!(e.action.cast.castFlags & SMARTCAST_AURA_NOT_PRESENT) || !target->ToUnit()->HasAura(e.action.cast.spell))
{
TriggerCastFlags triggerFlag = TRIGGERED_NONE;
if (e.action.cast.castFlags & SMARTCAST_TRIGGERED)
@@ -655,7 +534,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
// If cast flag SMARTCAST_COMBAT_MOVE is set combat movement will not be allowed
// unless target is outside spell range, out of mana, or LOS.
- bool _allowMove = false;
+ bool allowMove = false;
SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(e.action.cast.spell, me->GetMap()->GetDifficultyID());
std::vector<SpellPowerCost> costs = spellInfo->CalcPowerCost(me, spellInfo->GetSchoolMask());
bool hasPower = true;
@@ -680,27 +559,25 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
- if (me->GetDistance(*itr) > spellInfo->GetMaxRange(true) ||
- me->GetDistance(*itr) < spellInfo->GetMinRange(true) ||
- !me->IsWithinLOSInMap(*itr) || !hasPower)
- _allowMove = true;
+ if (me->GetDistance(target) > spellInfo->GetMaxRange(true) ||
+ me->GetDistance(target) < spellInfo->GetMinRange(true) ||
+ !me->IsWithinLOSInMap(target) || !hasPower)
+ allowMove = true;
- ENSURE_AI(SmartAI, me->AI())->SetCombatMove(_allowMove);
+ ENSURE_AI(SmartAI, me->AI())->SetCombatMove(allowMove);
}
- me->CastSpell((*itr)->ToUnit(), e.action.cast.spell, triggerFlag);
+ me->CastSpell(target->ToUnit(), e.action.cast.spell, triggerFlag);
}
else if (go)
- go->CastSpell((*itr)->ToUnit(), e.action.cast.spell, triggerFlag);
+ go->CastSpell(target->ToUnit(), e.action.cast.spell, triggerFlag);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_CAST:: %s casts spell %u on target %s with castflags %u",
- (me ? me->GetGUID() : go->GetGUID()).ToString().c_str(), e.action.cast.spell, (*itr)->GetGUID().ToString().c_str(), e.action.cast.castFlags);
+ (me ? me->GetGUID() : go->GetGUID()).ToString().c_str(), e.action.cast.spell, target->GetGUID().ToString().c_str(), e.action.cast.castFlags);
}
else
- TC_LOG_DEBUG("scripts.ai", "Spell %u not cast because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (%s) already has the aura", e.action.cast.spell, (*itr)->GetGUID().ToString().c_str());
+ TC_LOG_DEBUG("scripts.ai", "Spell %u not cast because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (%s) already has the aura", e.action.cast.spell, target->GetGUID().ToString().c_str());
}
-
- delete targets;
break;
}
case SMART_ACTION_INVOKER_CAST:
@@ -709,19 +586,18 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!tempLastInvoker)
break;
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
+ if (targets.empty())
break;
- if (e.action.cast.targetsLimit > 0 && targets->size() > e.action.cast.targetsLimit)
- Trinity::Containers::RandomResize(*targets, e.action.cast.targetsLimit);
+ if (e.action.cast.targetsLimit > 0 && targets.size() > e.action.cast.targetsLimit)
+ Trinity::Containers::RandomResize(targets, e.action.cast.targetsLimit);
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (!IsUnit(*itr))
+ if (!IsUnit(target))
continue;
- if (!(e.action.cast.castFlags & SMARTCAST_AURA_NOT_PRESENT) || !(*itr)->ToUnit()->HasAura(e.action.cast.spell))
+ if (!(e.action.cast.castFlags & SMARTCAST_AURA_NOT_PRESENT) || !target->ToUnit()->HasAura(e.action.cast.spell))
{
if (e.action.cast.castFlags & SMARTCAST_INTERRUPT_PREVIOUS)
tempLastInvoker->InterruptNonMeleeSpells(false);
@@ -735,149 +611,111 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
triggerFlag = TRIGGERED_FULL_MASK;
}
- tempLastInvoker->CastSpell((*itr)->ToUnit(), e.action.cast.spell, triggerFlag);
+ tempLastInvoker->CastSpell(target->ToUnit(), e.action.cast.spell, triggerFlag);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_INVOKER_CAST: Invoker %s casts spell %u on target %s with castflags %u",
- tempLastInvoker->GetGUID().ToString().c_str(), e.action.cast.spell, (*itr)->GetGUID().ToString().c_str(), e.action.cast.castFlags);
+ tempLastInvoker->GetGUID().ToString().c_str(), e.action.cast.spell, target->GetGUID().ToString().c_str(), e.action.cast.castFlags);
}
else
- TC_LOG_DEBUG("scripts.ai", "Spell %u not cast because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (%s) already has the aura", e.action.cast.spell, (*itr)->GetGUID().ToString().c_str());
+ TC_LOG_DEBUG("scripts.ai", "Spell %u not cast because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (%s) already has the aura", e.action.cast.spell, target->GetGUID().ToString().c_str());
}
-
- delete targets;
break;
}
case SMART_ACTION_ADD_AURA:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (IsUnit(*itr))
+ if (IsUnit(target))
{
- (*itr)->ToUnit()->AddAura(e.action.cast.spell, (*itr)->ToUnit());
+ target->ToUnit()->AddAura(e.action.cast.spell, target->ToUnit());
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_ADD_AURA: Adding aura %u to %s",
- e.action.cast.spell, (*itr)->GetGUID().ToString().c_str());
+ e.action.cast.spell, target->GetGUID().ToString().c_str());
}
}
-
- delete targets;
break;
}
case SMART_ACTION_ACTIVATE_GOBJECT:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (IsGameObject(*itr))
+ if (IsGameObject(target))
{
// Activate
- (*itr)->ToGameObject()->SetLootState(GO_READY);
- (*itr)->ToGameObject()->UseDoorOrButton(0, false, unit);
+ target->ToGameObject()->SetLootState(GO_READY);
+ target->ToGameObject()->UseDoorOrButton(0, false, unit);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_ACTIVATE_GOBJECT. %s (entry: %u) activated",
- (*itr)->GetGUID().ToString().c_str(), (*itr)->GetEntry());
+ target->GetGUID().ToString().c_str(), target->GetEntry());
}
}
-
- delete targets;
break;
}
case SMART_ACTION_RESET_GOBJECT:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (IsGameObject(*itr))
+ if (IsGameObject(target))
{
- (*itr)->ToGameObject()->ResetDoorOrButton();
+ target->ToGameObject()->ResetDoorOrButton();
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_RESET_GOBJECT. %s (entry: %u) reset",
- (*itr)->GetGUID().ToString().c_str(), (*itr)->GetEntry());
+ target->GetGUID().ToString().c_str(), target->GetEntry());
}
}
-
- delete targets;
break;
}
case SMART_ACTION_SET_EMOTE_STATE:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (IsUnit(*itr))
+ if (IsUnit(target))
{
- (*itr)->ToUnit()->SetEmoteState(Emote(e.action.emote.emote));
+ target->ToUnit()->SetEmoteState(Emote(e.action.emote.emote));
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_EMOTE_STATE. %s set emotestate to %u",
- (*itr)->GetGUID().ToString().c_str(), e.action.emote.emote);
+ target->GetGUID().ToString().c_str(), e.action.emote.emote);
}
}
-
- delete targets;
break;
}
case SMART_ACTION_SET_UNIT_FLAG:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (IsUnit(*itr))
+ if (IsUnit(target))
{
if (!e.action.unitFlag.type)
{
- (*itr)->ToUnit()->AddUnitFlag(UnitFlags(e.action.unitFlag.flag));
+ target->ToUnit()->AddUnitFlag(UnitFlags(e.action.unitFlag.flag));
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_UNIT_FLAG. %s added flag %u to UNIT_FIELD_FLAGS",
- (*itr)->GetGUID().ToString().c_str(), e.action.unitFlag.flag);
+ target->GetGUID().ToString().c_str(), e.action.unitFlag.flag);
}
else
{
- (*itr)->ToUnit()->AddUnitFlag2(UnitFlags2(e.action.unitFlag.flag));
+ target->ToUnit()->AddUnitFlag2(UnitFlags2(e.action.unitFlag.flag));
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_UNIT_FLAG. %s added flag %u to UNIT_FIELD_FLAGS_2",
- (*itr)->GetGUID().ToString().c_str(), e.action.unitFlag.flag);
+ target->GetGUID().ToString().c_str(), e.action.unitFlag.flag);
}
}
}
-
- delete targets;
break;
}
case SMART_ACTION_REMOVE_UNIT_FLAG:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (IsUnit(*itr))
+ if (IsUnit(target))
{
if (!e.action.unitFlag.type)
{
- (*itr)->ToUnit()->RemoveUnitFlag(UnitFlags(e.action.unitFlag.flag));
+ target->ToUnit()->RemoveUnitFlag(UnitFlags(e.action.unitFlag.flag));
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_REMOVE_UNIT_FLAG. %s removed flag %u to UNIT_FIELD_FLAGS",
- (*itr)->GetGUID().ToString().c_str(), e.action.unitFlag.flag);
+ target->GetGUID().ToString().c_str(), e.action.unitFlag.flag);
}
else
{
- (*itr)->ToUnit()->RemoveUnitFlag2(UnitFlags2(e.action.unitFlag.flag));
+ target->ToUnit()->RemoveUnitFlag2(UnitFlags2(e.action.unitFlag.flag));
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_REMOVE_UNIT_FLAG. %s removed flag %u to UNIT_FIELD_FLAGS_2",
- (*itr)->GetGUID().ToString().c_str(), e.action.unitFlag.flag);
+ target->GetGUID().ToString().c_str(), e.action.unitFlag.flag);
}
}
}
-
- delete targets;
break;
}
case SMART_ACTION_AUTO_ATTACK:
@@ -978,33 +816,27 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
case SMART_ACTION_REMOVEAURASFROMSPELL:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (!IsUnit(*itr))
+ if (!IsUnit(target))
continue;
if (e.action.removeAura.spell)
{
if (e.action.removeAura.charges)
{
- if (Aura* aur = (*itr)->ToUnit()->GetAura(e.action.removeAura.spell))
+ if (Aura* aur = target->ToUnit()->GetAura(e.action.removeAura.spell))
aur->ModCharges(-static_cast<int32>(e.action.removeAura.charges), AURA_REMOVE_BY_EXPIRE);
}
else
- (*itr)->ToUnit()->RemoveAurasDueToSpell(e.action.removeAura.spell);
+ target->ToUnit()->RemoveAurasDueToSpell(e.action.removeAura.spell);
}
else
- (*itr)->ToUnit()->RemoveAllAuras();
+ target->ToUnit()->RemoveAllAuras();
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_REMOVEAURASFROMSPELL: %s, spell %u",
- (*itr)->GetGUID().ToString().c_str(), e.action.removeAura.spell);
+ target->GetGUID().ToString().c_str(), e.action.removeAura.spell);
}
-
- delete targets;
break;
}
case SMART_ACTION_FOLLOW:
@@ -1012,26 +844,23 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!IsSmart())
break;
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
+ if (targets.empty())
{
ENSURE_AI(SmartAI, me->AI())->StopFollow(false);
break;
}
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (IsUnit(*itr))
+ if (IsUnit(target))
{
float angle = e.action.follow.angle > 6 ? (e.action.follow.angle * M_PI / 180.0f) : e.action.follow.angle;
- ENSURE_AI(SmartAI, me->AI())->SetFollow((*itr)->ToUnit(), float(e.action.follow.dist) + 0.1f, angle, e.action.follow.credit, e.action.follow.entry, e.action.follow.creditType);
+ ENSURE_AI(SmartAI, me->AI())->SetFollow(target->ToUnit(), float(e.action.follow.dist) + 0.1f, angle, e.action.follow.credit, e.action.follow.entry, e.action.follow.creditType);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_FOLLOW: %s following target %s",
- me->GetGUID().ToString().c_str(), (*itr)->GetGUID().ToString().c_str());
+ me->GetGUID().ToString().c_str(), target->GetGUID().ToString().c_str());
break;
}
}
-
- delete targets;
break;
}
case SMART_ACTION_RANDOM_PHASE:
@@ -1039,28 +868,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!GetBaseObject())
break;
- uint32 phases[SMART_ACTION_PARAM_COUNT];
- phases[0] = e.action.randomPhase.phase1;
- phases[1] = e.action.randomPhase.phase2;
- phases[2] = e.action.randomPhase.phase3;
- phases[3] = e.action.randomPhase.phase4;
- phases[4] = e.action.randomPhase.phase5;
- phases[5] = e.action.randomPhase.phase6;
- uint32 temp[SMART_ACTION_PARAM_COUNT];
- uint32 count = 0;
- for (uint8 i = 0; i < SMART_ACTION_PARAM_COUNT; i++)
- {
- if (phases[i] > 0)
- {
- temp[count] = phases[i];
- ++count;
- }
- }
+ std::vector<uint32> phases;
+ std::copy_if(e.action.randomPhase.phases.begin(), e.action.randomPhase.phases.end(),
+ std::back_inserter(phases), [](uint32 phase) { return phase != 0; });
- if (count == 0)
- break;
-
- uint32 phase = temp[urand(0, count - 1)];
+ uint32 phase = Trinity::Containers::SelectRandomContainerElement(phases);
SetPhase(phase);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_RANDOM_PHASE: %s sets event phase to %u",
GetBaseObject()->GetGUID().ToString().c_str(), phase);
@@ -1093,26 +905,20 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
else // Specific target type
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (IsPlayer(*itr))
+ if (IsPlayer(target))
{
- (*itr)->ToPlayer()->KilledMonsterCredit(e.action.killedMonster.creature);
+ target->ToPlayer()->KilledMonsterCredit(e.action.killedMonster.creature);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_CALL_KILLEDMONSTER: %s, Killcredit: %u",
- (*itr)->GetGUID().ToString().c_str(), e.action.killedMonster.creature);
+ target->GetGUID().ToString().c_str(), e.action.killedMonster.creature);
}
- else if (IsUnit(*itr)) // Special handling for vehicles
- if (Vehicle* vehicle = (*itr)->ToUnit()->GetVehicleKit())
+ else if (IsUnit(target)) // Special handling for vehicles
+ if (Vehicle* vehicle = target->ToUnit()->GetVehicleKit())
for (SeatMap::iterator seatItr = vehicle->Seats.begin(); seatItr != vehicle->Seats.end(); ++seatItr)
- if (Player* player = ObjectAccessor::GetPlayer(*(*itr), seatItr->second.Passenger.Guid))
+ if (Player* player = ObjectAccessor::GetPlayer(*target, seatItr->second.Passenger.Guid))
player->KilledMonsterCredit(e.action.killedMonster.creature);
}
-
- delete targets;
}
break;
}
@@ -1165,29 +971,19 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
break;
}
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
+ if (targets.empty())
break;
- instance->SetGuidData(e.action.setInstanceData64.field, targets->front()->GetGUID());
+ instance->SetGuidData(e.action.setInstanceData64.field, targets.front()->GetGUID());
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_SET_INST_DATA64: Field: %u, data: %s",
- e.action.setInstanceData64.field, targets->front()->GetGUID().ToString().c_str());
-
- delete targets;
+ e.action.setInstanceData64.field, targets.front()->GetGUID().ToString().c_str());
break;
}
case SMART_ACTION_UPDATE_TEMPLATE:
{
- ObjectList* targets = GetTargets(e, unit);
-
- if (!targets)
- break;
-
- for (WorldObject* target : *targets)
+ for (WorldObject* target : targets)
if (IsCreature(target))
target->ToCreature()->UpdateEntry(e.action.updateTemplate.creature, target->ToCreature()->GetCreatureData(), e.action.updateTemplate.updateLevel != 0);
-
- delete targets;
break;
}
case SMART_ACTION_DIE:
@@ -1201,39 +997,31 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
case SMART_ACTION_SET_IN_COMBAT_WITH_ZONE:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsCreature(*itr))
+ for (WorldObject* target : targets)
+ {
+ if (IsCreature(target))
{
- (*itr)->ToCreature()->SetInCombatWithZone();
- TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_SET_IN_COMBAT_WITH_ZONE: Creature %s, target: %s", me->GetGUID().ToString().c_str(), (*itr)->GetGUID().ToString().c_str());
+ target->ToCreature()->SetInCombatWithZone();
+ TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_SET_IN_COMBAT_WITH_ZONE: Creature %s, target: %s", me->GetGUID().ToString().c_str(), target->GetGUID().ToString().c_str());
}
-
- delete targets;
+ }
break;
}
case SMART_ACTION_CALL_FOR_HELP:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsCreature(*itr))
+ for (WorldObject* target : targets)
+ {
+ if (IsCreature(target))
{
- (*itr)->ToCreature()->CallForHelp((float)e.action.callHelp.range);
+ target->ToCreature()->CallForHelp(float(e.action.callHelp.range));
if (e.action.callHelp.withEmote)
{
Trinity::BroadcastTextBuilder builder(me, CHAT_MSG_MONSTER_EMOTE, BROADCAST_TEXT_CALL_FOR_HELP, me->getGender());
sCreatureTextMgr->SendChatPacket(me, builder, CHAT_MSG_MONSTER_EMOTE);
}
- TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_CALL_FOR_HELP: Creature %s, target: %s", me->GetGUID().ToString().c_str(), (*itr)->GetGUID().ToString().c_str());
+ TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_CALL_FOR_HELP: Creature %s, target: %s", me->GetGUID().ToString().c_str(), target->GetGUID().ToString().c_str());
}
-
- delete targets;
+ }
break;
}
case SMART_ACTION_SET_SHEATH:
@@ -1248,78 +1036,53 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
case SMART_ACTION_FORCE_DESPAWN:
{
- ObjectList* targets = GetTargets(e, unit);
-
- if (!targets)
- break;
-
// there should be at least a world update tick before despawn, to avoid breaking linked actions
int32 const respawnDelay = std::max<int32>(e.action.forceDespawn.delay, 1);
- for (WorldObject* target : *targets)
+ for (WorldObject* target : targets)
{
- if (Creature* creatureTarget = target->ToCreature())
+ if (Creature* creature = target->ToCreature())
{
- if (SmartAI* smartAI = CAST_AI(SmartAI, creatureTarget->AI()))
+ if (SmartAI* smartAI = CAST_AI(SmartAI, creature->AI()))
{
smartAI->SetDespawnTime(respawnDelay);
smartAI->StartDespawn();
}
else
- creatureTarget->DespawnOrUnsummon(respawnDelay);
+ creature->DespawnOrUnsummon(respawnDelay);
}
- else if (GameObject* goTarget = target->ToGameObject())
- goTarget->SetRespawnTime(respawnDelay);
+ else if (GameObject* go = target->ToGameObject())
+ go->SetRespawnTime(respawnDelay);
}
-
- delete targets;
break;
}
case SMART_ACTION_SET_INGAME_PHASE_ID:
{
- ObjectList* targets = GetTargets(e, unit);
-
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
if (e.action.ingamePhaseId.apply == 1)
- PhasingHandler::AddPhase(*itr, e.action.ingamePhaseId.id, true);
+ PhasingHandler::AddPhase(target, e.action.ingamePhaseId.id, true);
else
- PhasingHandler::RemovePhase(*itr, e.action.ingamePhaseId.id, true);
+ PhasingHandler::RemovePhase(target, e.action.ingamePhaseId.id, true);
}
-
- delete targets;
break;
}
case SMART_ACTION_SET_INGAME_PHASE_GROUP:
{
- ObjectList* targets = GetTargets(e, unit);
-
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
if (e.action.ingamePhaseGroup.apply == 1)
- PhasingHandler::AddPhaseGroup(*itr, e.action.ingamePhaseGroup.groupId, true);
+ PhasingHandler::AddPhaseGroup(target, e.action.ingamePhaseGroup.groupId, true);
else
- PhasingHandler::RemovePhaseGroup(*itr, e.action.ingamePhaseGroup.groupId, true);
+ PhasingHandler::RemovePhaseGroup(target, e.action.ingamePhaseGroup.groupId, true);
}
-
- delete targets;
break;
}
case SMART_ACTION_MOUNT_TO_ENTRY_OR_MODEL:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (!IsUnit(*itr))
+ if (!IsUnit(target))
continue;
if (e.action.morphOrMount.creature || e.action.morphOrMount.model)
@@ -1327,110 +1090,78 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (e.action.morphOrMount.creature > 0)
{
if (CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(e.action.morphOrMount.creature))
- (*itr)->ToUnit()->Mount(ObjectMgr::ChooseDisplayId(cInfo)->CreatureDisplayID);
+ target->ToUnit()->Mount(ObjectMgr::ChooseDisplayId(cInfo)->CreatureDisplayID);
}
else
- (*itr)->ToUnit()->Mount(e.action.morphOrMount.model);
+ target->ToUnit()->Mount(e.action.morphOrMount.model);
}
else
- (*itr)->ToUnit()->Dismount();
+ target->ToUnit()->Dismount();
}
-
- delete targets;
break;
}
case SMART_ACTION_SET_INVINCIBILITY_HP_LEVEL:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (IsCreature(*itr))
+ if (IsCreature(target))
{
- SmartAI* ai = CAST_AI(SmartAI, (*itr)->ToCreature()->AI());
+ SmartAI* ai = CAST_AI(SmartAI, target->ToCreature()->AI());
if (!ai)
continue;
if (e.action.invincHP.percent)
- ai->SetInvincibilityHpLevel((*itr)->ToCreature()->CountPctFromMaxHealth(e.action.invincHP.percent));
+ ai->SetInvincibilityHpLevel(target->ToCreature()->CountPctFromMaxHealth(e.action.invincHP.percent));
else
ai->SetInvincibilityHpLevel(e.action.invincHP.minHP);
}
}
-
- delete targets;
break;
}
case SMART_ACTION_SET_DATA:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (IsCreature(*itr))
- (*itr)->ToCreature()->AI()->SetData(e.action.setData.field, e.action.setData.data);
- else if (IsGameObject(*itr))
- (*itr)->ToGameObject()->AI()->SetData(e.action.setData.field, e.action.setData.data);
+ if (IsCreature(target))
+ target->ToCreature()->AI()->SetData(e.action.setData.field, e.action.setData.data);
+ else if (IsGameObject(target))
+ target->ToGameObject()->AI()->SetData(e.action.setData.field, e.action.setData.data);
}
-
- delete targets;
break;
}
case SMART_ACTION_MOVE_OFFSET:
{
- if (ObjectList* targets = GetTargets(e, unit))
+ for (WorldObject* target : targets)
{
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- {
- if (!IsCreature(*itr))
- continue;
+ if (!IsCreature(target))
+ continue;
- if (!(e.event.event_flags & SMART_EVENT_FLAG_WHILE_CHARMED) && IsCharmedCreature(*itr))
- continue;
+ if (!(e.event.event_flags & SMART_EVENT_FLAG_WHILE_CHARMED) && IsCharmedCreature(target))
+ continue;
- Position pos = (*itr)->GetPosition();
+ Position pos = target->GetPosition();
- // Use forward/backward/left/right cartesian plane movement
- float x, y, z, o;
- o = pos.GetOrientation();
- x = pos.GetPositionX() + (std::cos(o - (M_PI / 2))*e.target.x) + (std::cos(o)*e.target.y);
- y = pos.GetPositionY() + (std::sin(o - (M_PI / 2))*e.target.x) + (std::sin(o)*e.target.y);
- z = pos.GetPositionZ() + e.target.z;
- (*itr)->ToCreature()->GetMotionMaster()->MovePoint(SMART_RANDOM_POINT, x, y, z);
- }
-
- delete targets;
+ // Use forward/backward/left/right cartesian plane movement
+ float x, y, z, o;
+ o = pos.GetOrientation();
+ x = pos.GetPositionX() + (std::cos(o - (M_PI / 2))*e.target.x) + (std::cos(o)*e.target.y);
+ y = pos.GetPositionY() + (std::sin(o - (M_PI / 2))*e.target.x) + (std::sin(o)*e.target.y);
+ z = pos.GetPositionZ() + e.target.z;
+ target->ToCreature()->GetMotionMaster()->MovePoint(SMART_RANDOM_POINT, x, y, z);
}
-
break;
}
case SMART_ACTION_SET_VISIBILITY:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsUnit(*itr))
- (*itr)->ToUnit()->SetVisible(e.action.visibility.state ? true : false);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsUnit(target))
+ target->ToUnit()->SetVisible(e.action.visibility.state ? true : false);
break;
}
case SMART_ACTION_SET_ACTIVE:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- (*itr)->setActive(e.action.active.state ? true : false);
-
- delete targets;
+ for (WorldObject* target : targets)
+ target->setActive(e.action.active.state ? true : false);
break;
}
case SMART_ACTION_ATTACK_START:
@@ -1438,15 +1169,12 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!me)
break;
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
+ if (targets.empty())
break;
// attack random target
- if (Unit * target = Trinity::Containers::SelectRandomContainerElement(*targets)->ToUnit())
+ if (Unit * target = Trinity::Containers::SelectRandomContainerElement(targets)->ToUnit())
me->AI()->AttackStart(target);
-
- delete targets;
break;
}
case SMART_ACTION_SUMMON_CREATURE:
@@ -1455,24 +1183,17 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!summoner)
break;
- ObjectList* targets = GetTargets(e, unit);
-
- if (targets)
+ float x, y, z, o;
+ for (WorldObject* target : targets)
{
- float x, y, z, o;
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- {
- (*itr)->GetPosition(x, y, z, o);
- x += e.target.x;
- y += e.target.y;
- z += e.target.z;
- o += e.target.o;
- if (Creature* summon = summoner->SummonCreature(e.action.summonCreature.creature, x, y, z, o, (TempSummonType)e.action.summonCreature.type, e.action.summonCreature.duration))
- if (e.action.summonCreature.attackInvoker)
- summon->AI()->AttackStart((*itr)->ToUnit());
- }
-
- delete targets;
+ target->GetPosition(x, y, z, o);
+ x += e.target.x;
+ y += e.target.y;
+ z += e.target.z;
+ o += e.target.o;
+ if (Creature* summon = summoner->SummonCreature(e.action.summonCreature.creature, x, y, z, o, (TempSummonType)e.action.summonCreature.type, e.action.summonCreature.duration))
+ if (e.action.summonCreature.attackInvoker)
+ summon->AI()->AttackStart(target->ToUnit());
}
if (e.GetTargetType() != SMART_TARGET_POSITION)
@@ -1489,20 +1210,10 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!summoner)
break;
- ObjectList* targets = GetTargets(e, unit);
- if (targets)
+ for (WorldObject* target : targets)
{
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- {
- // allow gameobjects to summon gameobjects
- //if (!IsUnit(*itr))
- // continue;
-
- Position pos = (*itr)->GetPositionWithOffset(Position(e.target.x, e.target.y, e.target.z, e.target.o));
- summoner->SummonGameObject(e.action.summonGO.entry, pos, QuaternionData::fromEulerAnglesZYX(pos.GetOrientation(), 0.f, 0.f), e.action.summonGO.despawnTime);
- }
-
- delete targets;
+ Position pos = target->GetPositionWithOffset(Position(e.target.x, e.target.y, e.target.z, e.target.o));
+ summoner->SummonGameObject(e.action.summonGO.entry, pos, QuaternionData::fromEulerAnglesZYX(pos.GetOrientation(), 0.f, 0.f), e.action.summonGO.despawnTime);
}
if (e.GetTargetType() != SMART_TARGET_POSITION)
@@ -1513,19 +1224,13 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
case SMART_ACTION_KILL_UNIT:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (!IsUnit(*itr))
+ if (!IsUnit(target))
continue;
- (*itr)->ToUnit()->KillSelf();
+ target->ToUnit()->KillSelf();
}
-
- delete targets;
break;
}
case SMART_ACTION_INSTALL_AI_TEMPLATE:
@@ -1535,59 +1240,40 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
case SMART_ACTION_ADD_ITEM:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (!IsPlayer(*itr))
+ if (!IsPlayer(target))
continue;
- (*itr)->ToPlayer()->AddItem(e.action.item.entry, e.action.item.count);
+ target->ToPlayer()->AddItem(e.action.item.entry, e.action.item.count);
}
-
- delete targets;
break;
}
case SMART_ACTION_REMOVE_ITEM:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (!IsPlayer(*itr))
+ if (!IsPlayer(target))
continue;
- (*itr)->ToPlayer()->DestroyItemCount(e.action.item.entry, e.action.item.count, true);
+ target->ToPlayer()->DestroyItemCount(e.action.item.entry, e.action.item.count, true);
}
-
- delete targets;
break;
}
case SMART_ACTION_STORE_TARGET_LIST:
{
- ObjectList* targets = GetTargets(e, unit);
StoreTargetList(targets, e.action.storeTargets.id);
break;
}
case SMART_ACTION_TELEPORT:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (IsPlayer(*itr))
- (*itr)->ToPlayer()->TeleportTo(e.action.teleport.mapID, e.target.x, e.target.y, e.target.z, e.target.o);
- else if (IsCreature(*itr))
- (*itr)->ToCreature()->NearTeleportTo(e.target.x, e.target.y, e.target.z, e.target.o);
+ if (IsPlayer(target))
+ target->ToPlayer()->TeleportTo(e.action.teleport.mapID, e.target.x, e.target.y, e.target.z, e.target.o);
+ else if (IsCreature(target))
+ target->ToCreature()->NearTeleportTo(e.target.x, e.target.y, e.target.z, e.target.o);
}
-
- delete targets;
break;
}
case SMART_ACTION_SET_DISABLE_GRAVITY:
@@ -1624,31 +1310,28 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
case SMART_ACTION_SET_COUNTER:
{
- if (ObjectList* targets = GetTargets(e, unit))
+ if (!targets.empty())
{
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (IsCreature(*itr))
+ if (IsCreature(target))
{
- if (SmartAI* ai = CAST_AI(SmartAI, (*itr)->ToCreature()->AI()))
+ if (SmartAI* ai = CAST_AI(SmartAI, target->ToCreature()->AI()))
ai->GetScript()->StoreCounter(e.action.setCounter.counterId, e.action.setCounter.value, e.action.setCounter.reset);
else
TC_LOG_ERROR("sql.sql", "SmartScript: Action target for SMART_ACTION_SET_COUNTER is not using SmartAI, skipping");
}
- else if (IsGameObject(*itr))
+ else if (IsGameObject(target))
{
- if (SmartGameObjectAI* ai = CAST_AI(SmartGameObjectAI, (*itr)->ToGameObject()->AI()))
+ if (SmartGameObjectAI* ai = CAST_AI(SmartGameObjectAI, target->ToGameObject()->AI()))
ai->GetScript()->StoreCounter(e.action.setCounter.counterId, e.action.setCounter.value, e.action.setCounter.reset);
else
TC_LOG_ERROR("sql.sql", "SmartScript: Action target for SMART_ACTION_SET_COUNTER is not using SmartGameObjectAI, skipping");
}
}
-
- delete targets;
}
else
StoreCounter(e.action.setCounter.counterId, e.action.setCounter.value, e.action.setCounter.reset);
-
break;
}
case SMART_ACTION_WP_START:
@@ -1660,22 +1343,13 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
uint32 entry = e.action.wpStart.pathID;
bool repeat = e.action.wpStart.repeat != 0;
- // ensure that SMART_ESCORT_TARGETS contains at least one player reference
- bool stored = false;
- ObjectList* targets = GetTargets(e, unit);
- if (targets)
+ for (WorldObject* target : targets)
{
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ if (IsPlayer(target))
{
- if (IsPlayer(*itr))
- {
- stored = true;
- StoreTargetList(targets, SMART_ESCORT_TARGETS);
- break;
- }
+ StoreTargetList(targets, SMART_ESCORT_TARGETS);
+ break;
}
- if (!stored)
- delete targets;
}
me->SetReactState((ReactStates)e.action.wpStart.reactState);
@@ -1724,31 +1398,19 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
me->SetFacingTo((me->GetTransport() ? me->GetTransportHomePosition() : me->GetHomePosition()).GetOrientation());
else if (e.GetTargetType() == SMART_TARGET_POSITION)
me->SetFacingTo(e.target.o);
- else if (ObjectList* targets = GetTargets(e, unit))
- {
- if (!targets->empty())
- me->SetFacingToObject(*targets->begin());
-
- delete targets;
- }
-
+ else if (!targets.empty())
+ me->SetFacingToObject(targets.front());
break;
}
case SMART_ACTION_PLAYMOVIE:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (!IsPlayer(*itr))
+ if (!IsPlayer(target))
continue;
- (*itr)->ToPlayer()->SendMovieStart(e.action.movie.entry);
+ target->ToPlayer()->SendMovieStart(e.action.movie.entry);
}
-
- delete targets;
break;
}
case SMART_ACTION_MOVE_TO_POS:
@@ -1765,12 +1427,9 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
e.GetTargetType() == SMART_TARGET_OWNER_OR_SUMMONER || e.GetTargetType() == SMART_TARGET_ACTION_INVOKER ||
e.GetTargetType() == SMART_TARGET_CLOSEST_ENEMY || e.GetTargetType() == SMART_TARGET_CLOSEST_FRIENDLY)*/
{
- if (ObjectList * targets = GetTargets(e, unit))
- {
- // we want to move to random element
- target = Trinity::Containers::SelectRandomContainerElement(*targets);
- delete targets;
- }
+ // we want to move to random element
+ if (!targets.empty())
+ target = Trinity::Containers::SelectRandomContainerElement(targets);
}
if (!target)
@@ -1794,82 +1453,60 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
case SMART_ACTION_RESPAWN_TARGET:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (IsCreature(*itr))
- (*itr)->ToCreature()->Respawn();
- else if (IsGameObject(*itr))
+ if (IsCreature(target))
+ target->ToCreature()->Respawn();
+ else if (IsGameObject(target))
{
// do not modify respawndelay of already spawned gameobjects
- if ((*itr)->ToGameObject()->isSpawnedByDefault())
- (*itr)->ToGameObject()->Respawn();
+ if (target->ToGameObject()->isSpawnedByDefault())
+ target->ToGameObject()->Respawn();
else
- (*itr)->ToGameObject()->SetRespawnTime(e.action.RespawnTarget.goRespawnTime);
+ target->ToGameObject()->SetRespawnTime(e.action.RespawnTarget.goRespawnTime);
}
}
-
- delete targets;
break;
}
case SMART_ACTION_CLOSE_GOSSIP:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsPlayer(*itr))
- (*itr)->ToPlayer()->PlayerTalkClass->SendCloseGossip();
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsPlayer(target))
+ target->ToPlayer()->PlayerTalkClass->SendCloseGossip();
break;
}
case SMART_ACTION_EQUIP:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (Creature* npc = (*itr)->ToCreature())
+ if (Creature* npc = target->ToCreature())
{
- EquipmentItem slot[3];
- int8 equipId = (int8)e.action.equip.entry;
- if (equipId)
+ std::array<EquipmentItem, MAX_EQUIPMENT_ITEMS> slot;
+ if (int8 equipId = static_cast<int8>(e.action.equip.entry))
{
- EquipmentInfo const* einfo = sObjectMgr->GetEquipmentInfo(npc->GetEntry(), equipId);
- if (!einfo)
+ EquipmentInfo const* eInfo = sObjectMgr->GetEquipmentInfo(npc->GetEntry(), equipId);
+ if (!eInfo)
{
TC_LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_EQUIP uses non-existent equipment info id %u for creature %u", equipId, npc->GetEntry());
break;
}
npc->SetCurrentEquipmentId(equipId);
- slot[0] = einfo->Items[0];
- slot[1] = einfo->Items[1];
- slot[2] = einfo->Items[2];
+
+ std::copy(std::begin(eInfo->Items), std::end(eInfo->Items), std::begin(slot));
}
else
{
- slot[0].ItemId = e.action.equip.slot1;
- slot[1].ItemId = e.action.equip.slot2;
- slot[2].ItemId = e.action.equip.slot3;
+ slot[0].ItemId = e.action.equip.slots[0];
+ slot[1].ItemId = e.action.equip.slots[1];
+ slot[2].ItemId = e.action.equip.slots[2];
}
- if (!e.action.equip.mask || (e.action.equip.mask & 1))
- npc->SetVirtualItem(0, slot[0].ItemId, slot[0].AppearanceModId, slot[0].ItemVisual);
- if (!e.action.equip.mask || (e.action.equip.mask & 2))
- npc->SetVirtualItem(1, slot[1].ItemId, slot[1].AppearanceModId, slot[1].ItemVisual);
- if (!e.action.equip.mask || (e.action.equip.mask & 4))
- npc->SetVirtualItem(2, slot[2].ItemId, slot[2].AppearanceModId, slot[2].ItemVisual);
+
+ for (uint32 i = 0; i < MAX_EQUIPMENT_ITEMS; ++i)
+ if (!e.action.equip.mask || (e.action.equip.mask & (1 << i)))
+ npc->SetVirtualItem(0, slot[i].ItemId, slot[i].AppearanceModId, slot[i].ItemVisual);
}
}
-
- delete targets;
break;
}
case SMART_ACTION_CREATE_TIMED_EVENT:
@@ -1913,35 +1550,29 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
break;
case SMART_ACTION_OVERRIDE_SCRIPT_BASE_OBJECT:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (IsCreature(*itr))
+ if (IsCreature(target))
{
if (!meOrigGUID && me)
meOrigGUID = me->GetGUID();
if (!goOrigGUID && go)
goOrigGUID = go->GetGUID();
go = nullptr;
- me = (*itr)->ToCreature();
+ me = target->ToCreature();
break;
}
- else if (IsGameObject(*itr))
+ else if (IsGameObject(target))
{
if (!meOrigGUID && me)
meOrigGUID = me->GetGUID();
if (!goOrigGUID && go)
goOrigGUID = go->GetGUID();
- go = (*itr)->ToGameObject();
+ go = target->ToGameObject();
me = nullptr;
break;
}
}
-
- delete targets;
break;
}
case SMART_ACTION_RESET_SCRIPT_BASE_OBJECT:
@@ -1959,17 +1590,12 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
float attackDistance = float(e.action.setRangedMovement.distance);
float attackAngle = float(e.action.setRangedMovement.angle) / 180.0f * float(M_PI);
- ObjectList* targets = GetTargets(e, unit);
- if (targets)
- {
- for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (Creature* target = (*itr)->ToCreature())
- if (IsSmart(target) && target->GetVictim())
- if (ENSURE_AI(SmartAI, target->AI())->CanCombatMove())
- target->GetMotionMaster()->MoveChase(target->GetVictim(), attackDistance, attackAngle);
+ for (WorldObject* target : targets)
+ if (Creature* creature = target->ToCreature())
+ if (IsSmart(creature) && creature->GetVictim())
+ if (ENSURE_AI(SmartAI, creature->AI())->CanCombatMove())
+ creature->GetMotionMaster()->MoveChase(creature->GetVictim(), attackDistance, attackAngle);
- delete targets;
- }
break;
}
case SMART_ACTION_CALL_TIMED_ACTIONLIST:
@@ -1980,433 +1606,292 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
break;
}
- if (ObjectList* targets = GetTargets(e, unit))
+ for (WorldObject* target : targets)
{
- for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ if (Creature* creature = target->ToCreature())
{
- if (Creature* target = (*itr)->ToCreature())
- {
- if (IsSmart(target))
- ENSURE_AI(SmartAI, target->AI())->SetScript9(e, e.action.timedActionList.id, GetLastInvoker());
- }
- else if (GameObject* goTarget = (*itr)->ToGameObject())
- {
- if (IsSmartGO(goTarget))
- ENSURE_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, e.action.timedActionList.id, GetLastInvoker());
- }
+ if (IsSmart(creature))
+ ENSURE_AI(SmartAI, creature->AI())->SetScript9(e, e.action.timedActionList.id, GetLastInvoker());
+ }
+ else if (GameObject* go = target->ToGameObject())
+ {
+ if (IsSmartGO(go))
+ ENSURE_AI(SmartGameObjectAI, go->AI())->SetScript9(e, e.action.timedActionList.id, GetLastInvoker());
}
-
- delete targets;
}
break;
}
case SMART_ACTION_SET_NPC_FLAG:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsCreature(*itr))
- (*itr)->ToUnit()->SetNpcFlags(NPCFlags(e.action.unitFlag.flag));
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsCreature(target))
+ target->ToUnit()->SetNpcFlags(NPCFlags(e.action.unitFlag.flag));
break;
}
case SMART_ACTION_ADD_NPC_FLAG:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsCreature(*itr))
- (*itr)->ToUnit()->AddNpcFlag(NPCFlags(e.action.unitFlag.flag));
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsCreature(target))
+ target->ToUnit()->AddNpcFlag(NPCFlags(e.action.unitFlag.flag));
break;
}
case SMART_ACTION_REMOVE_NPC_FLAG:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsCreature(*itr))
- (*itr)->ToUnit()->RemoveNpcFlag(NPCFlags(e.action.unitFlag.flag));
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsCreature(target))
+ target->ToUnit()->RemoveNpcFlag(NPCFlags(e.action.unitFlag.flag));
break;
}
case SMART_ACTION_CROSS_CAST:
{
- ObjectList* casters = GetTargets(CreateSmartEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, 0, 0, 0, SMART_ACTION_NONE, 0, 0, 0, 0, 0, 0, (SMARTAI_TARGETS)e.action.crossCast.targetType, e.action.crossCast.targetParam1, e.action.crossCast.targetParam2, e.action.crossCast.targetParam3, 0), unit);
- if (!casters)
+ if (targets.empty())
break;
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- {
- delete casters; // casters already validated, delete now
- break;
- }
+ ObjectVector casters;
+ GetTargets(casters, CreateSmartEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, 0, 0, 0, SMART_ACTION_NONE, 0, 0, 0, 0, 0, 0, (SMARTAI_TARGETS)e.action.crossCast.targetType, e.action.crossCast.targetParam1, e.action.crossCast.targetParam2, e.action.crossCast.targetParam3, 0), unit);
- for (ObjectList::const_iterator itr = casters->begin(); itr != casters->end(); ++itr)
+ for (WorldObject* caster : casters)
{
- if (!IsUnit(*itr))
+ if (!IsUnit(caster))
continue;
- Unit* targetUnit = (*itr)->ToUnit();
+ Unit* casterUnit = caster->ToUnit();
bool interruptedSpell = false;
- for (ObjectList::const_iterator it = targets->begin(); it != targets->end(); ++it)
+ for (WorldObject* target : targets)
{
- if (!IsUnit(*it))
+ if (!IsUnit(target))
continue;
- if (!(e.action.crossCast.castFlags & SMARTCAST_AURA_NOT_PRESENT) || !(*it)->ToUnit()->HasAura(e.action.crossCast.spell))
+ if (!(e.action.crossCast.castFlags & SMARTCAST_AURA_NOT_PRESENT) || !target->ToUnit()->HasAura(e.action.crossCast.spell))
{
if (!interruptedSpell && e.action.crossCast.castFlags & SMARTCAST_INTERRUPT_PREVIOUS)
{
- targetUnit->InterruptNonMeleeSpells(false);
+ casterUnit->InterruptNonMeleeSpells(false);
interruptedSpell = true;
}
- targetUnit->CastSpell((*it)->ToUnit(), e.action.crossCast.spell, (e.action.crossCast.castFlags & SMARTCAST_TRIGGERED) != 0);
+ casterUnit->CastSpell(target->ToUnit(), e.action.crossCast.spell, (e.action.crossCast.castFlags & SMARTCAST_TRIGGERED) != 0);
}
else
- TC_LOG_DEBUG("scripts.ai", "Spell %u not cast because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (%s) already has the aura", e.action.crossCast.spell, (*it)->GetGUID().ToString().c_str());
+ TC_LOG_DEBUG("scripts.ai", "Spell %u not cast because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (%s) already has the aura", e.action.crossCast.spell, target->GetGUID().ToString().c_str());
}
}
-
- delete targets;
- delete casters;
break;
}
case SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST:
{
- uint32 actions[SMART_ACTION_PARAM_COUNT];
- actions[0] = e.action.randTimedActionList.entry1;
- actions[1] = e.action.randTimedActionList.entry2;
- actions[2] = e.action.randTimedActionList.entry3;
- actions[3] = e.action.randTimedActionList.entry4;
- actions[4] = e.action.randTimedActionList.entry5;
- actions[5] = e.action.randTimedActionList.entry6;
- uint32 temp[SMART_ACTION_PARAM_COUNT];
- uint32 count = 0;
- for (uint8 i = 0; i < SMART_ACTION_PARAM_COUNT; i++)
- {
- if (actions[i] > 0)
- {
- temp[count] = actions[i];
- ++count;
- }
- }
+ std::vector<uint32> actionLists;
+ std::copy_if(e.action.randTimedActionList.actionLists.begin(), e.action.randTimedActionList.actionLists.end(),
+ std::back_inserter(actionLists), [](uint32 actionList) { return actionList != 0; });
- if (count == 0)
- break;
-
- uint32 id = temp[urand(0, count - 1)];
+ uint32 id = Trinity::Containers::SelectRandomContainerElement(actionLists);
if (e.GetTargetType() == SMART_TARGET_NONE)
{
TC_LOG_ERROR("sql.sql", "SmartScript: Entry " SI64FMTD " SourceType %u Event %u Action %u is using TARGET_NONE(0) for Script9 target. Please correct target_type in database.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType());
break;
}
- ObjectList* targets = GetTargets(e, unit);
- if (targets)
+ for (WorldObject* target : targets)
{
- for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ if (Creature* creature = target->ToCreature())
{
- if (Creature* target = (*itr)->ToCreature())
- {
- if (IsSmart(target))
- ENSURE_AI(SmartAI, target->AI())->SetScript9(e, id, GetLastInvoker());
- }
- else if (GameObject* goTarget = (*itr)->ToGameObject())
- {
- if (IsSmartGO(goTarget))
- ENSURE_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, id, GetLastInvoker());
- }
+ if (IsSmart(creature))
+ ENSURE_AI(SmartAI, creature->AI())->SetScript9(e, id, GetLastInvoker());
+ }
+ else if (GameObject* go = target->ToGameObject())
+ {
+ if (IsSmartGO(go))
+ ENSURE_AI(SmartGameObjectAI, go->AI())->SetScript9(e, id, GetLastInvoker());
}
-
- delete targets;
}
break;
}
case SMART_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST:
{
- uint32 id = urand(e.action.randTimedActionList.entry1, e.action.randTimedActionList.entry2);
+ uint32 id = urand(e.action.randTimedActionList.actionLists[0], e.action.randTimedActionList.actionLists[1]);
if (e.GetTargetType() == SMART_TARGET_NONE)
{
TC_LOG_ERROR("sql.sql", "SmartScript: Entry " SI64FMTD " SourceType %u Event %u Action %u is using TARGET_NONE(0) for Script9 target. Please correct target_type in database.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType());
break;
}
- ObjectList* targets = GetTargets(e, unit);
- if (targets)
+ for (WorldObject* target : targets)
{
- for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ if (Creature* creature = target->ToCreature())
{
- if (Creature* target = (*itr)->ToCreature())
- {
- if (IsSmart(target))
- ENSURE_AI(SmartAI, target->AI())->SetScript9(e, id, GetLastInvoker());
- }
- else if (GameObject* goTarget = (*itr)->ToGameObject())
- {
- if (IsSmartGO(goTarget))
- ENSURE_AI(SmartGameObjectAI, goTarget->AI())->SetScript9(e, id, GetLastInvoker());
- }
+ if (IsSmart(creature))
+ ENSURE_AI(SmartAI, creature->AI())->SetScript9(e, id, GetLastInvoker());
+ }
+ else if (GameObject* go = target->ToGameObject())
+ {
+ if (IsSmartGO(go))
+ ENSURE_AI(SmartGameObjectAI, go->AI())->SetScript9(e, id, GetLastInvoker());
}
-
- delete targets;
}
break;
}
case SMART_ACTION_ACTIVATE_TAXI:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsPlayer(*itr))
- (*itr)->ToPlayer()->ActivateTaxiPathTo(e.action.taxi.id);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsPlayer(target))
+ target->ToPlayer()->ActivateTaxiPathTo(e.action.taxi.id);
break;
}
case SMART_ACTION_RANDOM_MOVE:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
bool foundTarget = false;
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (IsCreature((*itr)))
+ if (IsCreature((target)))
{
foundTarget = true;
if (e.action.moveRandom.distance)
- (*itr)->ToCreature()->GetMotionMaster()->MoveRandom((float)e.action.moveRandom.distance);
+ target->ToCreature()->GetMotionMaster()->MoveRandom(float(e.action.moveRandom.distance));
else
- (*itr)->ToCreature()->GetMotionMaster()->MoveIdle();
+ target->ToCreature()->GetMotionMaster()->MoveIdle();
}
}
if (!foundTarget && me && IsCreature(me))
{
if (e.action.moveRandom.distance)
- me->GetMotionMaster()->MoveRandom((float)e.action.moveRandom.distance);
+ me->GetMotionMaster()->MoveRandom(float(e.action.moveRandom.distance));
else
me->GetMotionMaster()->MoveIdle();
}
-
- delete targets;
break;
}
case SMART_ACTION_SET_UNIT_FIELD_BYTES_1:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsUnit(*itr))
+ for (WorldObject* target : targets)
+ if (IsUnit(target))
{
switch (e.action.setunitByte.type)
{
case 0:
- (*itr)->ToUnit()->SetStandState(UnitStandStateType(e.action.setunitByte.byte1));
+ target->ToUnit()->SetStandState(UnitStandStateType(e.action.setunitByte.byte1));
break;
case 1:
// pet talent points
break;
case 2:
- (*itr)->ToUnit()->AddVisFlags(UnitVisFlags(e.action.setunitByte.byte1));
+ target->ToUnit()->AddVisFlags(UnitVisFlags(e.action.setunitByte.byte1));
break;
case 3:
// this is totally wrong to maintain compatibility with existing scripts
// TODO: fix with animtier overhaul
- (*itr)->ToUnit()->SetAnimTier(UnitBytes1_Flags(*(*itr)->ToUnit()->m_unitData->AnimTier | e.action.setunitByte.byte1), false);
+ target->ToUnit()->SetAnimTier(UnitBytes1_Flags(target->ToUnit()->m_unitData->AnimTier | e.action.setunitByte.byte1), false);
break;
}
}
-
- delete targets;
break;
}
case SMART_ACTION_REMOVE_UNIT_FIELD_BYTES_1:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsUnit(*itr))
+ for (WorldObject* target : targets)
+ if (IsUnit(target))
{
switch (e.action.setunitByte.type)
{
case 0:
- (*itr)->ToUnit()->SetStandState(UNIT_STAND_STATE_STAND);
+ target->ToUnit()->SetStandState(UNIT_STAND_STATE_STAND);
break;
case 1:
// pet talent points
break;
case 2:
- (*itr)->ToUnit()->RemoveVisFlags(UnitVisFlags(e.action.setunitByte.byte1));
+ target->ToUnit()->RemoveVisFlags(UnitVisFlags(e.action.setunitByte.byte1));
break;
case 3:
- (*itr)->ToUnit()->SetAnimTier(UnitBytes1_Flags(*(*itr)->ToUnit()->m_unitData->AnimTier & ~e.action.setunitByte.byte1), false);
+ target->ToUnit()->SetAnimTier(UnitBytes1_Flags(target->ToUnit()->m_unitData->AnimTier & ~e.action.setunitByte.byte1), false);
break;
}
}
-
- delete targets;
break;
}
case SMART_ACTION_INTERRUPT_SPELL:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsUnit(*itr))
- (*itr)->ToUnit()->InterruptNonMeleeSpells(e.action.interruptSpellCasting.withDelayed != 0, e.action.interruptSpellCasting.spell_id, e.action.interruptSpellCasting.withInstant != 0);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsUnit(target))
+ target->ToUnit()->InterruptNonMeleeSpells(e.action.interruptSpellCasting.withDelayed != 0, e.action.interruptSpellCasting.spell_id, e.action.interruptSpellCasting.withInstant != 0);
break;
}
case SMART_ACTION_SEND_GO_CUSTOM_ANIM:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsGameObject(*itr))
- (*itr)->ToGameObject()->SendCustomAnim(e.action.sendGoCustomAnim.anim);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsGameObject(target))
+ target->ToGameObject()->SendCustomAnim(e.action.sendGoCustomAnim.anim);
break;
}
case SMART_ACTION_SET_DYNAMIC_FLAG:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
+ for (WorldObject* target : targets)
+ target->SetDynamicFlags(e.action.unitFlag.flag);
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- (*itr)->SetDynamicFlags(e.action.unitFlag.flag);
-
- delete targets;
break;
}
case SMART_ACTION_ADD_DYNAMIC_FLAG:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- (*itr)->AddDynamicFlag(e.action.unitFlag.flag);
+ for (WorldObject* target : targets)
+ target->AddDynamicFlag(e.action.unitFlag.flag);
- delete targets;
break;
}
case SMART_ACTION_REMOVE_DYNAMIC_FLAG:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- (*itr)->RemoveDynamicFlag(e.action.unitFlag.flag);
+ for (WorldObject* target : targets)
+ target->RemoveDynamicFlag(e.action.unitFlag.flag);
- delete targets;
break;
}
case SMART_ACTION_JUMP_TO_POS:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- {
- if (Creature* creature = (*itr)->ToCreature())
- creature->GetMotionMaster()->MoveJump(e.target.x, e.target.y, e.target.z, 0.0f, (float)e.action.jump.speedxy, (float)e.action.jump.speedz); // @todo add optional jump orientation support?
- }
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (Creature* creature = target->ToCreature())
+ creature->GetMotionMaster()->MoveJump(e.target.x, e.target.y, e.target.z, 0.0f, float(e.action.jump.speedxy), float(e.action.jump.speedz)); // @todo add optional jump orientation support?
break;
}
case SMART_ACTION_GO_SET_LOOT_STATE:
{
- ObjectList* targets = GetTargets(e, unit);
-
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsGameObject(*itr))
- (*itr)->ToGameObject()->SetLootState((LootState)e.action.setGoLootState.state);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsGameObject(target))
+ target->ToGameObject()->SetLootState((LootState)e.action.setGoLootState.state);
break;
}
case SMART_ACTION_GO_SET_GO_STATE:
{
- ObjectList* targets = GetTargets(e, unit);
-
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsGameObject(*itr))
- (*itr)->ToGameObject()->SetGoState((GOState)e.action.goState.state);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsGameObject(target))
+ target->ToGameObject()->SetGoState((GOState)e.action.goState.state);
break;
}
case SMART_ACTION_SEND_TARGET_TO_TARGET:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- ObjectList* storedTargets = GetTargetList(e.action.sendTargetToTarget.id);
+ ObjectVector const* storedTargets = GetStoredTargetVector(e.action.sendTargetToTarget.id);
if (!storedTargets)
- {
- delete targets;
break;
- }
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (IsCreature(*itr))
+ if (IsCreature(target))
{
- if (SmartAI* ai = CAST_AI(SmartAI, (*itr)->ToCreature()->AI()))
- ai->GetScript()->StoreTargetList(new ObjectList(*storedTargets), e.action.sendTargetToTarget.id); // store a copy of target list
+ if (SmartAI* ai = CAST_AI(SmartAI, target->ToCreature()->AI()))
+ ai->GetScript()->StoreTargetList(ObjectVector(*storedTargets), e.action.sendTargetToTarget.id); // store a copy of target list
else
TC_LOG_ERROR("sql.sql", "SmartScript: Action target for SMART_ACTION_SEND_TARGET_TO_TARGET is not using SmartAI, skipping");
}
- else if (IsGameObject(*itr))
+ else if (IsGameObject(target))
{
- if (SmartGameObjectAI* ai = CAST_AI(SmartGameObjectAI, (*itr)->ToGameObject()->AI()))
- ai->GetScript()->StoreTargetList(new ObjectList(*storedTargets), e.action.sendTargetToTarget.id); // store a copy of target list
+ if (SmartGameObjectAI* ai = CAST_AI(SmartGameObjectAI, target->ToGameObject()->AI()))
+ ai->GetScript()->StoreTargetList(ObjectVector(*storedTargets), e.action.sendTargetToTarget.id); // store a copy of target list
else
TC_LOG_ERROR("sql.sql", "SmartScript: Action target for SMART_ACTION_SEND_TARGET_TO_TARGET is not using SmartGameObjectAI, skipping");
}
}
-
- delete targets;
break;
}
case SMART_ACTION_SEND_GOSSIP_MENU:
@@ -2417,19 +1902,15 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SEND_GOSSIP_MENU: gossipMenuId %d, gossipNpcTextId %d",
e.action.sendGossipMenu.gossipMenuId, e.action.sendGossipMenu.gossipNpcTextId);
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
// override default gossip
if (me)
ENSURE_AI(SmartAI, me->AI())->SetGossipReturn(true);
else if (go)
ENSURE_AI(SmartGameObjectAI, go->AI())->SetGossipReturn(true);
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (Player* player = (*itr)->ToPlayer())
+ if (Player* player = target->ToPlayer())
{
if (e.action.sendGossipMenu.gossipMenuId)
player->PrepareGossipMenu(GetBaseObject(), e.action.sendGossipMenu.gossipMenuId, true);
@@ -2439,24 +1920,18 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
player->PlayerTalkClass->SendGossipMenu(e.action.sendGossipMenu.gossipNpcTextId, GetBaseObject()->GetGUID());
}
}
-
- delete targets;
break;
}
case SMART_ACTION_SET_HOME_POS:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* target : targets)
{
- if (IsCreature(*itr))
+ if (IsCreature(target))
{
if (e.GetTargetType() == SMART_TARGET_SELF)
- (*itr)->ToCreature()->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
+ target->ToCreature()->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
else if (e.GetTargetType() == SMART_TARGET_POSITION)
- (*itr)->ToCreature()->SetHomePosition(e.target.x, e.target.y, e.target.z, e.target.o);
+ target->ToCreature()->SetHomePosition(e.target.x, e.target.y, e.target.z, e.target.o);
else if (e.GetTargetType() == SMART_TARGET_CREATURE_RANGE || e.GetTargetType() == SMART_TARGET_CREATURE_GUID ||
e.GetTargetType() == SMART_TARGET_CREATURE_DISTANCE || e.GetTargetType() == SMART_TARGET_GAMEOBJECT_RANGE ||
e.GetTargetType() == SMART_TARGET_GAMEOBJECT_GUID || e.GetTargetType() == SMART_TARGET_GAMEOBJECT_DISTANCE ||
@@ -2464,79 +1939,48 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
e.GetTargetType() == SMART_TARGET_OWNER_OR_SUMMONER || e.GetTargetType() == SMART_TARGET_ACTION_INVOKER ||
e.GetTargetType() == SMART_TARGET_CLOSEST_ENEMY || e.GetTargetType() == SMART_TARGET_CLOSEST_FRIENDLY)
{
- (*itr)->ToCreature()->SetHomePosition((*itr)->GetPositionX(), (*itr)->GetPositionY(), (*itr)->GetPositionZ(), (*itr)->GetOrientation());
+ target->ToCreature()->SetHomePosition(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation());
}
else
TC_LOG_ERROR("sql.sql", "SmartScript: Action target for SMART_ACTION_SET_HOME_POS is invalid, skipping");
}
}
-
- delete targets;
break;
}
case SMART_ACTION_SET_HEALTH_REGEN:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsCreature(*itr))
- (*itr)->ToCreature()->setRegeneratingHealth(e.action.setHealthRegen.regenHealth != 0);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsCreature(target))
+ target->ToCreature()->setRegeneratingHealth(e.action.setHealthRegen.regenHealth != 0);
break;
}
case SMART_ACTION_SET_ROOT:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsCreature(*itr))
- (*itr)->ToCreature()->SetControlled(e.action.setRoot.root != 0, UNIT_STATE_ROOT);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsCreature(target))
+ target->ToCreature()->SetControlled(e.action.setRoot.root != 0, UNIT_STATE_ROOT);
break;
}
case SMART_ACTION_SET_GO_FLAG:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsGameObject(*itr))
- (*itr)->ToGameObject()->SetFlags(GameObjectFlags(e.action.goFlag.flag));
+ for (WorldObject* target : targets)
+ if (IsGameObject(target))
+ target->ToGameObject()->SetFlags(GameObjectFlags(e.action.goFlag.flag));
- delete targets;
break;
}
case SMART_ACTION_ADD_GO_FLAG:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsGameObject(*itr))
- (*itr)->ToGameObject()->AddFlag(GameObjectFlags(e.action.goFlag.flag));
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsGameObject(target))
+ target->ToGameObject()->AddFlag(GameObjectFlags(e.action.goFlag.flag));
break;
}
case SMART_ACTION_REMOVE_GO_FLAG:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsGameObject(*itr))
- (*itr)->ToGameObject()->RemoveFlag(GameObjectFlags(e.action.goFlag.flag));
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsGameObject(target))
+ target->ToGameObject()->RemoveFlag(GameObjectFlags(e.action.goFlag.flag));
break;
}
case SMART_ACTION_SUMMON_CREATURE_GROUP:
@@ -2544,46 +1988,30 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
std::list<TempSummon*> summonList;
GetBaseObject()->SummonCreatureGroup(e.action.creatureGroup.group, &summonList);
- for (std::list<TempSummon*>::const_iterator itr = summonList.begin(); itr != summonList.end(); ++itr)
+ for (TempSummon* summon : summonList)
if (unit && e.action.creatureGroup.attackInvoker)
- (*itr)->AI()->AttackStart(unit);
-
+ summon->AI()->AttackStart(unit);
break;
}
case SMART_ACTION_SET_POWER:
{
- ObjectList* targets = GetTargets(e, unit);
-
- if (targets)
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsUnit(*itr))
- (*itr)->ToUnit()->SetPower(Powers(e.action.power.powerType), e.action.power.newPower);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsUnit(target))
+ target->ToUnit()->SetPower(Powers(e.action.power.powerType), e.action.power.newPower);
break;
}
case SMART_ACTION_ADD_POWER:
{
- ObjectList* targets = GetTargets(e, unit);
-
- if (targets)
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsUnit(*itr))
- (*itr)->ToUnit()->SetPower(Powers(e.action.power.powerType), (*itr)->ToUnit()->GetPower(Powers(e.action.power.powerType)) + e.action.power.newPower);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsUnit(target))
+ target->ToUnit()->SetPower(Powers(e.action.power.powerType), target->ToUnit()->GetPower(Powers(e.action.power.powerType)) + e.action.power.newPower);
break;
}
case SMART_ACTION_REMOVE_POWER:
{
- ObjectList* targets = GetTargets(e, unit);
-
- if (targets)
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsUnit(*itr))
- (*itr)->ToUnit()->SetPower(Powers(e.action.power.powerType), (*itr)->ToUnit()->GetPower(Powers(e.action.power.powerType)) - e.action.power.newPower);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsUnit(target))
+ target->ToUnit()->SetPower(Powers(e.action.power.powerType), target->ToUnit()->GetPower(Powers(e.action.power.powerType)) - e.action.power.newPower);
break;
}
case SMART_ACTION_GAME_EVENT_STOP:
@@ -2610,59 +2038,44 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
case SMART_ACTION_START_CLOSEST_WAYPOINT:
{
- uint32 waypoints[SMART_ACTION_PARAM_COUNT];
- waypoints[0] = e.action.closestWaypointFromList.wp1;
- waypoints[1] = e.action.closestWaypointFromList.wp2;
- waypoints[2] = e.action.closestWaypointFromList.wp3;
- waypoints[3] = e.action.closestWaypointFromList.wp4;
- waypoints[4] = e.action.closestWaypointFromList.wp5;
- waypoints[5] = e.action.closestWaypointFromList.wp6;
+ std::vector<uint32> waypoints;
+ std::copy_if(e.action.closestWaypointFromList.wps.begin(), e.action.closestWaypointFromList.wps.end(),
+ std::back_inserter(waypoints), [](uint32 wp) { return wp != 0; });
+
float distanceToClosest = std::numeric_limits<float>::max();
WayPoint* closestWp = nullptr;
- ObjectList* targets = GetTargets(e, unit);
- if (targets)
+ for (WorldObject* target : targets)
{
- for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ if (Creature* creature = target->ToCreature())
{
- if (Creature* target = (*itr)->ToCreature())
+ if (IsSmart(creature))
{
- if (IsSmart(target))
+ for (uint32 wp : waypoints)
{
- for (uint8 i = 0; i < SMART_ACTION_PARAM_COUNT; i++)
- {
- if (!waypoints[i])
- continue;
-
- WPPath* path = sSmartWaypointMgr->GetPath(waypoints[i]);
-
- if (!path || path->empty())
- continue;
+ WPPath* path = sSmartWaypointMgr->GetPath(wp);
+ if (!path || path->empty())
+ continue;
- WPPath::const_iterator itrWp = path->find(0);
-
- if (itrWp != path->end())
+ auto itrWp = path->find(0);
+ if (itrWp != path->end())
+ {
+ if (WayPoint* wp = itrWp->second)
{
- if (WayPoint* wp = itrWp->second)
+ float distToThisPath = creature->GetDistance(wp->x, wp->y, wp->z);
+ if (distToThisPath < distanceToClosest)
{
- float distToThisPath = target->GetDistance(wp->x, wp->y, wp->z);
-
- if (distToThisPath < distanceToClosest)
- {
- distanceToClosest = distToThisPath;
- closestWp = wp;
- }
+ distanceToClosest = distToThisPath;
+ closestWp = wp;
}
}
}
-
- if (closestWp)
- CAST_AI(SmartAI, target->AI())->StartPath(false, closestWp->id, true);
}
+
+ if (closestWp)
+ CAST_AI(SmartAI, creature->AI())->StartPath(false, closestWp->id, true);
}
}
-
- delete targets;
}
break;
}
@@ -2673,38 +2086,26 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
std::back_inserter(sounds), [](uint32 sound) { return sound != 0; });
bool onlySelf = e.action.randomSound.onlySelf != 0;
-
- if (ObjectList* targets = GetTargets(e, unit))
+ for (WorldObject* const target : targets)
{
- for (WorldObject* const obj : *targets)
+ if (IsUnit(target))
{
- if (IsUnit(obj))
- {
- uint32 sound = Trinity::Containers::SelectRandomContainerElement(sounds);
- obj->PlayDirectSound(sound, onlySelf ? obj->ToPlayer() : nullptr);
- TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_RANDOM_SOUND: target: %s (%s), sound: %u, onlyself: %s",
- obj->GetName().c_str(), obj->GetGUID().ToString().c_str(), sound, onlySelf ? "true" : "false");
- }
+ uint32 sound = Trinity::Containers::SelectRandomContainerElement(sounds);
+ target->PlayDirectSound(sound, onlySelf ? target->ToPlayer() : nullptr);
+ TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_RANDOM_SOUND: target: %s (%s), sound: %u, onlyself: %s",
+ target->GetName().c_str(), target->GetGUID().ToString().c_str(), sound, onlySelf ? "true" : "false");
}
-
- delete targets;
- break;
}
+ break;
}
/* fallthrough */
case SMART_ACTION_SET_CORPSE_DELAY:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* const target : targets)
{
- if (IsCreature(*itr))
- (*itr)->ToCreature()->SetCorpseDelay(e.action.corpseDelay.timer);
+ if (IsCreature(target))
+ target->ToCreature()->SetCorpseDelay(e.action.corpseDelay.timer);
}
-
- delete targets;
break;
}
case SMART_ACTION_DISABLE_EVADE:
@@ -2717,67 +2118,37 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
case SMART_ACTION_REMOVE_AURAS_BY_TYPE: // can be used to exit vehicle for example
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsUnit(*itr))
- (*itr)->ToUnit()->RemoveAurasByType((AuraType)e.action.auraType.type);
-
- delete targets;
+ for (WorldObject* const target : targets)
+ if (IsUnit(target))
+ target->ToUnit()->RemoveAurasByType((AuraType)e.action.auraType.type);
break;
}
case SMART_ACTION_SET_SIGHT_DIST:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsCreature(*itr))
- (*itr)->ToCreature()->m_SightDistance = e.action.sightDistance.dist;
-
- delete targets;
+ for (WorldObject* const target : targets)
+ if (IsCreature(target))
+ target->ToCreature()->m_SightDistance = e.action.sightDistance.dist;
break;
}
case SMART_ACTION_FLEE:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsCreature(*itr))
- (*itr)->ToCreature()->GetMotionMaster()->MoveFleeing(me, e.action.flee.fleeTime);
-
- delete targets;
+ for (WorldObject* const target : targets)
+ if (IsCreature(target))
+ target->ToCreature()->GetMotionMaster()->MoveFleeing(me, e.action.flee.fleeTime);
break;
}
case SMART_ACTION_ADD_THREAT:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsUnit(*itr))
- me->AddThreat((*itr)->ToUnit(), (float)e.action.threatPCT.threatINC - (float)e.action.threatPCT.threatDEC);
-
- delete targets;
+ for (WorldObject* const target : targets)
+ if (IsUnit(target))
+ me->AddThreat(target->ToUnit(), float(e.action.threatPCT.threatINC) - float(e.action.threatPCT.threatDEC));
break;
}
case SMART_ACTION_LOAD_EQUIPMENT:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsCreature(*itr))
- (*itr)->ToCreature()->LoadEquipment(e.action.loadEquipment.id, e.action.loadEquipment.force != 0);
-
- delete targets;
+ for (WorldObject* const target : targets)
+ if (IsCreature(target))
+ target->ToCreature()->LoadEquipment(e.action.loadEquipment.id, e.action.loadEquipment.force != 0);
break;
}
case SMART_ACTION_TRIGGER_RANDOM_TIMED_EVENT:
@@ -2789,53 +2160,39 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_REMOVE_ALL_GAMEOBJECTS:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsUnit(*itr))
- (*itr)->ToUnit()->RemoveAllGameObjects();
-
- delete targets;
+ for (WorldObject* const target : targets)
+ if (IsUnit(target))
+ target->ToUnit()->RemoveAllGameObjects();
break;
}
case SMART_ACTION_STOP_MOTION:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsUnit(*itr))
+ for (WorldObject* const target : targets)
+ {
+ if (IsUnit(target))
{
if (e.action.stopMotion.stopMovement)
- (*itr)->ToUnit()->StopMoving();
+ target->ToUnit()->StopMoving();
if (e.action.stopMotion.movementExpired)
- (*itr)->ToUnit()->GetMotionMaster()->MovementExpired();
+ target->ToUnit()->GetMotionMaster()->MovementExpired();
}
-
- delete targets;
+ }
break;
}
case SMART_ACTION_PLAY_ANIMKIT:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* const target : targets)
{
- if (IsCreature(*itr))
+ if (IsCreature(target))
{
if (e.action.animKit.type == 0)
- (*itr)->ToCreature()->PlayOneShotAnimKitId(e.action.animKit.animKit);
+ target->ToCreature()->PlayOneShotAnimKitId(e.action.animKit.animKit);
else if (e.action.animKit.type == 1)
- (*itr)->ToCreature()->SetAIAnimKitId(e.action.animKit.animKit);
+ target->ToCreature()->SetAIAnimKitId(e.action.animKit.animKit);
else if (e.action.animKit.type == 2)
- (*itr)->ToCreature()->SetMeleeAnimKitId(e.action.animKit.animKit);
+ target->ToCreature()->SetMeleeAnimKitId(e.action.animKit.animKit);
else if (e.action.animKit.type == 3)
- (*itr)->ToCreature()->SetMovementAnimKitId(e.action.animKit.animKit);
+ target->ToCreature()->SetMovementAnimKitId(e.action.animKit.animKit);
else
{
TC_LOG_ERROR("sql.sql", "SmartScript: Invalid type for SMART_ACTION_PLAY_ANIMKIT, skipping");
@@ -2843,75 +2200,54 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_PLAY_ANIMKIT: target: %s (%s), AnimKit: %u, Type: %u",
- (*itr)->GetName().c_str(), (*itr)->GetGUID().ToString().c_str(), e.action.animKit.animKit, e.action.animKit.type);
+ target->GetName().c_str(), target->GetGUID().ToString().c_str(), e.action.animKit.animKit, e.action.animKit.type);
}
}
- delete targets;
break;
}
case SMART_ACTION_SCENE_PLAY:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (WorldObject* target : *targets)
+ for (WorldObject* const target : targets)
if (Player* playerTarget = target->ToPlayer())
playerTarget->GetSceneMgr().PlayScene(e.action.scene.sceneId);
- delete targets;
break;
}
case SMART_ACTION_SCENE_CANCEL:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (WorldObject* target : *targets)
+ for (WorldObject* const target : targets)
if (Player* playerTarget = target->ToPlayer())
playerTarget->GetSceneMgr().CancelSceneBySceneId(e.action.scene.sceneId);
- delete targets;
break;
}
case SMART_ACTION_SET_MOVEMENT_SPEED:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
uint32 speedInteger = e.action.movementSpeed.speedInteger;
uint32 speedFraction = e.action.movementSpeed.speedFraction;
float speed = float(speedInteger) + float(speedFraction) / std::pow(10, std::floor(std::log10(float(speedFraction ? speedFraction : 1)) + 1));
- for (WorldObject* target : *targets)
+ for (WorldObject* const target : targets)
if (IsCreature(target))
me->SetSpeed(UnitMoveType(e.action.movementSpeed.movementType), speed);
- delete targets;
break;
}
case SMART_ACTION_PLAY_SPELL_VISUAL_KIT:
{
- ObjectList* targets = GetTargets(e, unit);
- if (!targets)
- break;
-
- for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ for (WorldObject* const target : targets)
{
- if (IsUnit(*itr))
+ if (IsUnit(target))
{
- (*itr)->ToUnit()->SendPlaySpellVisualKit(e.action.spellVisualKit.spellVisualKitId, e.action.spellVisualKit.kitType,
+ target->ToUnit()->SendPlaySpellVisualKit(e.action.spellVisualKit.spellVisualKitId, e.action.spellVisualKit.kitType,
e.action.spellVisualKit.duration);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_PLAY_SPELL_VISUAL_KIT: target: %s (%s), SpellVisualKit: %u",
- (*itr)->GetName().c_str(), (*itr)->GetGUID().ToString().c_str(), e.action.spellVisualKit.spellVisualKitId);
+ target->GetName().c_str(), target->GetGUID().ToString().c_str(), e.action.spellVisualKit.spellVisualKitId);
}
}
- delete targets;
break;
}
default:
@@ -2945,11 +2281,13 @@ void SmartScript::InstallTemplate(SmartScriptHolder const& e)
{
if (!GetBaseObject())
return;
- if (mTemplate)
+
+ if (mTemplate != SMARTAI_TEMPLATE_BASIC)
{
TC_LOG_ERROR("sql.sql", "SmartScript::InstallTemplate: Entry " SI64FMTD " SourceType %u AI Template can not be set more then once, skipped.", e.entryOrGuid, e.GetScriptType());
return;
}
+
mTemplate = (SMARTAI_TEMPLATE)e.action.installTtemplate.id;
switch ((SMARTAI_TEMPLATE)e.action.installTtemplate.id)
{
@@ -3051,7 +2389,7 @@ SmartScriptHolder SmartScript::CreateSmartEvent(SMART_EVENT e, uint32 event_flag
return script;
}
-ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*= nullptr*/)
+void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e, Unit* invoker /*= nullptr*/) const
{
Unit* scriptTrigger = nullptr;
if (invoker)
@@ -3060,29 +2398,27 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
scriptTrigger = tempLastInvoker;
WorldObject* baseObject = GetBaseObject();
-
- ObjectList* l = new ObjectList();
switch (e.GetTargetType())
{
case SMART_TARGET_SELF:
if (baseObject)
- l->push_back(baseObject);
+ targets.push_back(baseObject);
break;
case SMART_TARGET_VICTIM:
if (me)
if (Unit* victim = me->GetVictim())
- l->push_back(victim);
+ targets.push_back(victim);
break;
case SMART_TARGET_HOSTILE_SECOND_AGGRO:
if (me)
{
if (e.target.hostilRandom.powerType)
{
- if (Unit * u = me->AI()->SelectTarget(SELECT_TARGET_TOPAGGRO, 1, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType - 1), (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly != 0)))
- l->push_back(u);
+ if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_TOPAGGRO, 1, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType - 1), float(e.target.hostilRandom.maxDist), e.target.hostilRandom.playerOnly != 0)))
+ targets.push_back(u);
}
- else if (Unit * u = me->AI()->SelectTarget(SELECT_TARGET_TOPAGGRO, 1, (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly != 0))
- l->push_back(u);
+ else if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_TOPAGGRO, 1, float(e.target.hostilRandom.maxDist), e.target.hostilRandom.playerOnly != 0))
+ targets.push_back(u);
}
break;
case SMART_TARGET_HOSTILE_LAST_AGGRO:
@@ -3090,11 +2426,11 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
{
if (e.target.hostilRandom.powerType)
{
- if (Unit * u = me->AI()->SelectTarget(SELECT_TARGET_BOTTOMAGGRO, 0, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType - 1), (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly != 0)))
- l->push_back(u);
+ if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_BOTTOMAGGRO, 0, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType - 1), float(e.target.hostilRandom.maxDist), e.target.hostilRandom.playerOnly != 0)))
+ targets.push_back(u);
}
- else if (Unit * u = me->AI()->SelectTarget(SELECT_TARGET_BOTTOMAGGRO, 0, (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly != 0))
- l->push_back(u);
+ else if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_BOTTOMAGGRO, 0, float(e.target.hostilRandom.maxDist), e.target.hostilRandom.playerOnly != 0))
+ targets.push_back(u);
}
break;
case SMART_TARGET_HOSTILE_RANDOM:
@@ -3102,11 +2438,11 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
{
if (e.target.hostilRandom.powerType)
{
- if (Unit * u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType - 1), (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly != 0)))
- l->push_back(u);
+ if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType - 1), float(e.target.hostilRandom.maxDist), e.target.hostilRandom.playerOnly != 0)))
+ targets.push_back(u);
}
- else if (Unit * u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly != 0))
- l->push_back(u);
+ else if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 0, float(e.target.hostilRandom.maxDist), e.target.hostilRandom.playerOnly != 0))
+ targets.push_back(u);
}
break;
case SMART_TARGET_HOSTILE_RANDOM_NOT_TOP:
@@ -3114,27 +2450,27 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
{
if (e.target.hostilRandom.powerType)
{
- if (Unit * u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType - 1), (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly != 0)))
- l->push_back(u);
+ if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1, PowerUsersSelector(me, Powers(e.target.hostilRandom.powerType - 1), float(e.target.hostilRandom.maxDist), e.target.hostilRandom.playerOnly != 0)))
+ targets.push_back(u);
}
- else if (Unit * u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1, (float)e.target.hostilRandom.maxDist, e.target.hostilRandom.playerOnly != 0))
- l->push_back(u);
+ else if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1, float(e.target.hostilRandom.maxDist), e.target.hostilRandom.playerOnly != 0))
+ targets.push_back(u);
}
break;
case SMART_TARGET_FARTHEST:
if (me)
{
- if (Unit * u = me->AI()->SelectTarget(SELECT_TARGET_FARTHEST, 0, FarthestTargetSelector(me, (float)e.target.farthest.maxDist, e.target.farthest.playerOnly != 0, e.target.farthest.isInLos != 0)))
- l->push_back(u);
+ if (Unit* u = me->AI()->SelectTarget(SELECT_TARGET_FARTHEST, 0, FarthestTargetSelector(me, float(e.target.farthest.maxDist), e.target.farthest.playerOnly != 0, e.target.farthest.isInLos != 0)))
+ targets.push_back(u);
}
break;
case SMART_TARGET_ACTION_INVOKER:
if (scriptTrigger)
- l->push_back(scriptTrigger);
+ targets.push_back(scriptTrigger);
break;
case SMART_TARGET_ACTION_INVOKER_VEHICLE:
if (scriptTrigger && scriptTrigger->GetVehicle() && scriptTrigger->GetVehicle()->GetBase())
- l->push_back(scriptTrigger->GetVehicle()->GetBase());
+ targets.push_back(scriptTrigger->GetVehicle()->GetBase());
break;
case SMART_TARGET_INVOKER_PARTY:
if (scriptTrigger)
@@ -3146,90 +2482,86 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next())
if (Player* member = groupRef->GetSource())
if (member->IsInMap(player))
- l->push_back(member);
+ targets.push_back(member);
}
// We still add the player to the list if there is no group. If we do
// this even if there is a group (thus the else-check), it will add the
// same player to the list twice. We don't want that to happen.
else
- l->push_back(scriptTrigger);
+ targets.push_back(scriptTrigger);
}
}
break;
case SMART_TARGET_CREATURE_RANGE:
{
- // will always return a valid pointer, even if empty list
- ObjectList* units = GetWorldObjectsInDist((float)e.target.unitRange.maxDist);
- for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr)
+ ObjectVector units;
+ GetWorldObjectsInDist(units, static_cast<float>(e.target.unitRange.maxDist));
+
+ for (WorldObject* unit : units)
{
- if (!IsCreature(*itr))
+ if (!IsCreature(unit))
continue;
- if (me && me->GetGUID() == (*itr)->GetGUID())
+ if (me && me->GetGUID() == unit->GetGUID())
continue;
- if ((!e.target.unitRange.creature || (*itr)->ToCreature()->GetEntry() == e.target.unitRange.creature) && baseObject->IsInRange(*itr, float(e.target.unitRange.minDist), float(e.target.unitRange.maxDist)))
- l->push_back(*itr);
+ if ((!e.target.unitRange.creature || unit->ToCreature()->GetEntry() == e.target.unitRange.creature) && baseObject->IsInRange(unit, float(e.target.unitRange.minDist), float(e.target.unitRange.maxDist)))
+ targets.push_back(unit);
}
-
- delete units;
break;
}
case SMART_TARGET_CREATURE_DISTANCE:
{
- // will always return a valid pointer, even if empty list
- ObjectList* units = GetWorldObjectsInDist((float)e.target.unitDistance.dist);
- for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr)
+ ObjectVector units;
+ GetWorldObjectsInDist(units, static_cast<float>(e.target.unitDistance.dist));
+
+ for (WorldObject* unit : units)
{
- if (!IsCreature(*itr))
+ if (!IsCreature(unit))
continue;
- if (me && me->GetGUID() == (*itr)->GetGUID())
+ if (me && me->GetGUID() == unit->GetGUID())
continue;
- if (!e.target.unitDistance.creature || (*itr)->ToCreature()->GetEntry() == e.target.unitDistance.creature)
- l->push_back(*itr);
+ if (!e.target.unitDistance.creature || unit->ToCreature()->GetEntry() == e.target.unitDistance.creature)
+ targets.push_back(unit);
}
-
- delete units;
break;
}
case SMART_TARGET_GAMEOBJECT_DISTANCE:
{
- // will always return a valid pointer, even if empty list
- ObjectList* units = GetWorldObjectsInDist((float)e.target.goDistance.dist);
- for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr)
+ ObjectVector units;
+ GetWorldObjectsInDist(units, static_cast<float>(e.target.goDistance.dist));
+
+ for (WorldObject* unit : units)
{
- if (!IsGameObject(*itr))
+ if (!IsGameObject(unit))
continue;
- if (go && go->GetGUID() == (*itr)->GetGUID())
+ if (go && go->GetGUID() == unit->GetGUID())
continue;
- if (!e.target.goDistance.entry || (*itr)->ToGameObject()->GetEntry() == e.target.goDistance.entry)
- l->push_back(*itr);
+ if (!e.target.goDistance.entry || unit->ToGameObject()->GetEntry() == e.target.goDistance.entry)
+ targets.push_back(unit);
}
-
- delete units;
break;
}
case SMART_TARGET_GAMEOBJECT_RANGE:
{
- // will always return a valid pointer, even if empty list
- ObjectList* units = GetWorldObjectsInDist((float)e.target.goRange.maxDist);
- for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr)
+ ObjectVector units;
+ GetWorldObjectsInDist(units, static_cast<float>(e.target.goRange.maxDist));
+
+ for (WorldObject* unit : units)
{
- if (!IsGameObject(*itr))
+ if (!IsGameObject(unit))
continue;
- if (go && go->GetGUID() == (*itr)->GetGUID())
+ if (go && go->GetGUID() == unit->GetGUID())
continue;
- if ((!e.target.goRange.entry && (*itr)->ToGameObject()->GetEntry() == e.target.goRange.entry) && baseObject->IsInRange(*itr, float(e.target.goRange.minDist), float(e.target.goRange.maxDist)))
- l->push_back(*itr);
+ if ((!e.target.goRange.entry && unit->ToGameObject()->GetEntry() == e.target.goRange.entry) && baseObject->IsInRange(unit, float(e.target.goRange.minDist), float(e.target.goRange.maxDist)))
+ targets.push_back(unit);
}
-
- delete units;
break;
}
case SMART_TARGET_CREATURE_GUID:
@@ -3242,7 +2574,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
if (Creature* target = FindCreatureNear(scriptTrigger ? scriptTrigger : baseObject, e.target.unitGUID.dbGuid))
if (!e.target.unitGUID.entry || target->GetEntry() == e.target.unitGUID.entry)
- l->push_back(target);
+ targets.push_back(target);
break;
}
case SMART_TARGET_GAMEOBJECT_GUID:
@@ -3255,60 +2587,53 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
if (GameObject* target = FindGameObjectNear(scriptTrigger ? scriptTrigger : baseObject, e.target.goGUID.dbGuid))
if (!e.target.goGUID.entry || target->GetEntry() == e.target.goGUID.entry)
- l->push_back(target);
+ targets.push_back(target);
break;
}
case SMART_TARGET_PLAYER_RANGE:
{
- // will always return a valid pointer, even if empty list
- ObjectList* units = GetWorldObjectsInDist((float)e.target.playerRange.maxDist);
- if (!units->empty() && baseObject)
- for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr)
- if (IsPlayer(*itr) && baseObject->IsInRange(*itr, (float)e.target.playerRange.minDist, (float)e.target.playerRange.maxDist))
- l->push_back(*itr);
+ ObjectVector units;
+ GetWorldObjectsInDist(units, static_cast<float>(e.target.playerRange.maxDist));
- delete units;
+ if (!units.empty() && baseObject)
+ for (WorldObject* unit : units)
+ if (IsPlayer(unit) && baseObject->IsInRange(unit, float(e.target.playerRange.minDist), float(e.target.playerRange.maxDist)))
+ targets.push_back(unit);
break;
}
case SMART_TARGET_PLAYER_DISTANCE:
{
- // will always return a valid pointer, even if empty list
- ObjectList* units = GetWorldObjectsInDist((float)e.target.playerDistance.dist);
- for (ObjectList::const_iterator itr = units->begin(); itr != units->end(); ++itr)
- if (IsPlayer(*itr))
- l->push_back(*itr);
+ ObjectVector units;
+ GetWorldObjectsInDist(units, static_cast<float>(e.target.playerDistance.dist));
- delete units;
+ for (WorldObject* unit : units)
+ if (IsPlayer(unit))
+ targets.push_back(unit);
break;
}
case SMART_TARGET_STORED:
{
- ObjectListMap::iterator itr = mTargetStorage->find(e.target.stored.id);
- if (itr != mTargetStorage->end())
- {
- ObjectList* objectList = itr->second->GetObjectList();
- l->assign(objectList->begin(), objectList->end());
- }
-
+ if (ObjectVector const* stored = GetStoredTargetVector(e.target.stored.id))
+ targets.assign(stored->begin(), stored->end());
break;
}
case SMART_TARGET_CLOSEST_CREATURE:
{
if (Creature* target = baseObject->FindNearestCreature(e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100), !e.target.closest.dead))
- l->push_back(target);
+ targets.push_back(target);
break;
}
case SMART_TARGET_CLOSEST_GAMEOBJECT:
{
if (GameObject* target = baseObject->FindNearestGameObject(e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100)))
- l->push_back(target);
+ targets.push_back(target);
break;
}
case SMART_TARGET_CLOSEST_PLAYER:
{
- if (WorldObject * obj = GetBaseObject())
- if (Player * target = obj->SelectNearestPlayer(float(e.target.playerDistance.dist)))
- l->push_back(target);
+ if (WorldObject* obj = GetBaseObject())
+ if (Player* target = obj->SelectNearestPlayer(float(e.target.playerDistance.dist)))
+ targets.push_back(target);
break;
}
case SMART_TARGET_OWNER_OR_SUMMONER:
@@ -3326,22 +2651,22 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
charmerOrOwnerGuid = me->GetCreatorGUID();
if (Unit* owner = ObjectAccessor::GetUnit(*me, charmerOrOwnerGuid))
- l->push_back(owner);
+ targets.push_back(owner);
}
else if (go)
{
- if (Unit * owner = ObjectAccessor::GetUnit(*go, go->GetOwnerGUID()))
- l->push_back(owner);
+ if (Unit* owner = ObjectAccessor::GetUnit(*go, go->GetOwnerGUID()))
+ targets.push_back(owner);
}
// Get owner of owner
- if (e.target.owner.useCharmerOrOwner && !l->empty())
+ if (e.target.owner.useCharmerOrOwner && !targets.empty())
{
- Unit* owner = l->front()->ToUnit();
- l->clear();
+ Unit* owner = targets.front()->ToUnit();
+ targets.clear();
- if (Unit * base = ObjectAccessor::GetUnit(*owner, owner->GetCharmerOrOwnerGUID()))
- l->push_back(base);
+ if (Unit* base = ObjectAccessor::GetUnit(*owner, owner->GetCharmerOrOwnerGUID()))
+ targets.push_back(base);
}
break;
}
@@ -3349,11 +2674,11 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
{
if (me)
{
- ThreatContainer::StorageType threatList = me->getThreatManager().getThreatList();
- for (ThreatContainer::StorageType::const_iterator i = threatList.begin(); i != threatList.end(); ++i)
- if (Unit* temp = ObjectAccessor::GetUnit(*me, (*i)->getUnitGuid()))
- if (e.target.hostilRandom.maxDist == 0 || me->IsWithinCombatRange(temp, (float)e.target.hostilRandom.maxDist))
- l->push_back(temp);
+ ThreatContainer::StorageType const& threatList = me->getThreatManager().getThreatList();
+ for (HostileReference const* ref : threatList)
+ if (Unit* temp = ObjectAccessor::GetUnit(*me, ref->getUnitGuid()))
+ if (e.target.hostilRandom.maxDist == 0 || me->IsWithinCombatRange(temp, float(e.target.hostilRandom.maxDist)))
+ targets.push_back(temp);
}
break;
}
@@ -3361,14 +2686,14 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
{
if (me)
if (Unit* target = me->SelectNearestTarget(e.target.closestAttackable.maxDist, e.target.closestAttackable.playerOnly != 0))
- l->push_back(target);
+ targets.push_back(target);
break;
}
case SMART_TARGET_CLOSEST_FRIENDLY:
{
if (me)
if (Unit* target = DoFindClosestFriendlyInRange(e.target.closestFriendly.maxDist, e.target.closestFriendly.playerOnly != 0))
- l->push_back(target);
+ targets.push_back(target);
break;
}
case SMART_TARGET_LOOT_RECIPIENTS:
@@ -3380,12 +2705,12 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
for (GroupReference* it = lootGroup->GetFirstMember(); it != nullptr; it = it->next())
if (Player* recipient = it->GetSource())
if (recipient->IsInMap(me))
- l->push_back(recipient);
+ targets.push_back(recipient);
}
else
{
if (Player* recipient = me->GetLootRecipient())
- l->push_back(recipient);
+ targets.push_back(recipient);
}
}
break;
@@ -3395,7 +2720,7 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
if (me && me->IsVehicle())
{
if (Unit* target = me->GetVehicleKit()->GetPassenger(e.target.vehicle.seat))
- l->push_back(target);
+ targets.push_back(target);
}
break;
}
@@ -3404,27 +2729,17 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
default:
break;
}
-
- if (l->empty())
- {
- delete l;
- l = nullptr;
- }
-
- return l;
}
-ObjectList* SmartScript::GetWorldObjectsInDist(float dist)
+void SmartScript::GetWorldObjectsInDist(ObjectVector& targets, float dist) const
{
- ObjectList* targets = new ObjectList();
WorldObject* obj = GetBaseObject();
- if (obj)
- {
- Trinity::AllWorldObjectsInRange u_check(obj, dist);
- Trinity::WorldObjectListSearcher<Trinity::AllWorldObjectsInRange> searcher(obj, *targets, u_check);
- Cell::VisitAllObjects(obj, searcher, dist);
- }
- return targets;
+ if (!obj)
+ return;
+
+ Trinity::AllWorldObjectsInRange u_check(obj, dist);
+ Trinity::WorldObjectListSearcher<Trinity::AllWorldObjectsInRange> searcher(obj, targets, u_check);
+ Cell::VisitAllObjects(obj, searcher, dist);
}
void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob, std::string const& varString)
@@ -3547,26 +2862,26 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
if (!me || !me->IsInCombat())
return;
- std::list<Creature*> pList;
- DoFindFriendlyCC(pList, (float)e.event.friendlyCC.radius);
- if (pList.empty())
+ std::vector<Creature*> creatures;
+ DoFindFriendlyCC(creatures, float(e.event.friendlyCC.radius));
+ if (creatures.empty())
{
// if there are at least two same npcs, they will perform the same action immediately even if this is useless...
RecalcTimer(e, 1000, 3000);
return;
}
- ProcessTimedAction(e, e.event.friendlyCC.repeatMin, e.event.friendlyCC.repeatMax, Trinity::Containers::SelectRandomContainerElement(pList));
+ ProcessTimedAction(e, e.event.friendlyCC.repeatMin, e.event.friendlyCC.repeatMax, Trinity::Containers::SelectRandomContainerElement(creatures));
break;
}
case SMART_EVENT_FRIENDLY_MISSING_BUFF:
{
- std::list<Creature*> pList;
- DoFindFriendlyMissingBuff(pList, (float)e.event.missingBuff.radius, e.event.missingBuff.spell);
+ std::vector<Creature*> creatures;
+ DoFindFriendlyMissingBuff(creatures, float(e.event.missingBuff.radius), e.event.missingBuff.spell);
- if (pList.empty())
+ if (creatures.empty())
return;
- ProcessTimedAction(e, e.event.missingBuff.repeatMin, e.event.missingBuff.repeatMax, Trinity::Containers::SelectRandomContainerElement(pList));
+ ProcessTimedAction(e, e.event.missingBuff.repeatMin, e.event.missingBuff.repeatMax, Trinity::Containers::SelectRandomContainerElement(creatures));
break;
}
case SMART_EVENT_HAS_AURA:
@@ -3872,8 +3187,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
if (!me || !me->IsInCombat())
return;
- ObjectList* _targets = nullptr;
-
+ ObjectVector targets;
switch (e.GetTargetType())
{
case SMART_TARGET_CREATURE_RANGE:
@@ -3883,37 +3197,30 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
case SMART_TARGET_CLOSEST_PLAYER:
case SMART_TARGET_PLAYER_RANGE:
case SMART_TARGET_PLAYER_DISTANCE:
- _targets = GetTargets(e);
+ GetTargets(targets, e);
break;
default:
return;
}
- if (!_targets)
- return;
-
- Unit* target = nullptr;
-
- for (ObjectList::const_iterator itr = _targets->begin(); itr != _targets->end(); ++itr)
+ Unit* unitTarget = nullptr;
+ for (WorldObject* target : targets)
{
- if (IsUnit(*itr) && me->IsFriendlyTo((*itr)->ToUnit()) && (*itr)->ToUnit()->IsAlive() && (*itr)->ToUnit()->IsInCombat())
+ if (IsUnit(target) && me->IsFriendlyTo(target->ToUnit()) && target->ToUnit()->IsAlive() && target->ToUnit()->IsInCombat())
{
- uint32 healthPct = uint32((*itr)->ToUnit()->GetHealthPct());
-
+ uint32 healthPct = uint32(target->ToUnit()->GetHealthPct());
if (healthPct > e.event.friendlyHealthPct.maxHpPct || healthPct < e.event.friendlyHealthPct.minHpPct)
continue;
- target = (*itr)->ToUnit();
+ unitTarget = target->ToUnit();
break;
}
}
- delete _targets;
-
- if (!target)
+ if (!unitTarget)
return;
- ProcessTimedAction(e, e.event.friendlyHealthPct.repeatMin, e.event.friendlyHealthPct.repeatMax, target);
+ ProcessTimedAction(e, e.event.friendlyHealthPct.repeatMin, e.event.friendlyHealthPct.repeatMax, unitTarget);
break;
}
case SMART_EVENT_DISTANCE_CREATURE:
@@ -4143,7 +3450,7 @@ void SmartScript::RemoveStoredEvent(uint32 id)
}
}
-WorldObject* SmartScript::GetBaseObject()
+WorldObject* SmartScript::GetBaseObject() const
{
WorldObject* obj = nullptr;
if (me)
@@ -4396,7 +3703,7 @@ void SmartScript::OnMoveInLineOfSight(Unit* who)
}
// SmartScript end
-Unit* SmartScript::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff)
+Unit* SmartScript::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff) const
{
if (!me)
return nullptr;
@@ -4409,27 +3716,27 @@ Unit* SmartScript::DoSelectLowestHpFriendly(float range, uint32 MinHPDiff)
return unit;
}
-void SmartScript::DoFindFriendlyCC(std::list<Creature*>& _list, float range)
+void SmartScript::DoFindFriendlyCC(std::vector<Creature*>& creatures, float range) const
{
if (!me)
return;
Trinity::FriendlyCCedInRange u_check(me, range);
- Trinity::CreatureListSearcher<Trinity::FriendlyCCedInRange> searcher(me, _list, u_check);
+ Trinity::CreatureListSearcher<Trinity::FriendlyCCedInRange> searcher(me, creatures, u_check);
Cell::VisitGridObjects(me, searcher, range);
}
-void SmartScript::DoFindFriendlyMissingBuff(std::list<Creature*>& list, float range, uint32 spellid)
+void SmartScript::DoFindFriendlyMissingBuff(std::vector<Creature*>& creatures, float range, uint32 spellid) const
{
if (!me)
return;
Trinity::FriendlyMissingBuffInRange u_check(me, range, spellid);
- Trinity::CreatureListSearcher<Trinity::FriendlyMissingBuffInRange> searcher(me, list, u_check);
+ Trinity::CreatureListSearcher<Trinity::FriendlyMissingBuffInRange> searcher(me, creatures, u_check);
Cell::VisitGridObjects(me, searcher, range);
}
-Unit* SmartScript::DoFindClosestFriendlyInRange(float range, bool playerOnly)
+Unit* SmartScript::DoFindClosestFriendlyInRange(float range, bool playerOnly) const
{
if (!me)
return nullptr;
@@ -4470,7 +3777,7 @@ void SmartScript::SetScript9(SmartScriptHolder& e, uint32 entry)
}
}
-Unit* SmartScript::GetLastInvoker(Unit* invoker)
+Unit* SmartScript::GetLastInvoker(Unit* invoker) const
{
// Look for invoker only on map of base object... Prevents multithreaded crashes
if (WorldObject* baseObject = GetBaseObject())
diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h
index ab35932d4ac..44575845049 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.h
+++ b/src/server/game/AI/SmartScripts/SmartScript.h
@@ -43,20 +43,20 @@ class TC_GAME_API SmartScript
void ProcessEventsFor(SMART_EVENT e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, const SpellInfo* spell = nullptr, GameObject* gob = nullptr, std::string const& varString = "");
void ProcessEvent(SmartScriptHolder& e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, const SpellInfo* spell = nullptr, GameObject* gob = nullptr, std::string const& varString = "");
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, const SpellInfo* spell = nullptr, GameObject* gob = nullptr, std::string const& varString = "");
void ProcessTimedAction(SmartScriptHolder& e, uint32 const& min, uint32 const& max, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, const SpellInfo* spell = nullptr, GameObject* gob = nullptr, std::string const& varString = "");
- 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 phaseMask = 0);
+ 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 phaseMask = 0);
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 phaseMask = 0);
void SetPathId(uint32 id) { mPathId = id; }
uint32 GetPathId() const { return mPathId; }
- WorldObject* GetBaseObject();
+ WorldObject* GetBaseObject() const;
WorldObject* GetBaseObjectOrUnit(Unit* unit);
static bool IsUnit(WorldObject* obj);
static bool IsPlayer(WorldObject* obj);
@@ -67,16 +67,28 @@ class TC_GAME_API SmartScript
void OnUpdate(const uint32 diff);
void OnMoveInLineOfSight(Unit* who);
- Unit* DoSelectLowestHpFriendly(float range, uint32 MinHPDiff);
- void DoFindFriendlyCC(std::list<Creature*>& _list, float range);
- void DoFindFriendlyMissingBuff(std::list<Creature*>& list, float range, uint32 spellid);
- Unit* DoFindClosestFriendlyInRange(float range, bool playerOnly);
+ Unit* DoSelectLowestHpFriendly(float range, uint32 MinHPDiff) const;
+ 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;
bool IsSmart(Creature* c = NULL);
bool IsSmartGO(GameObject* g = NULL);
- void StoreTargetList(ObjectList* targets, uint32 id);
- ObjectList* GetTargetList(uint32 id);
+ void StoreTargetList(ObjectVector const& targets, uint32 id)
+ {
+ // insert or replace
+ _storedTargets.erase(id);
+ _storedTargets.emplace(id, ObjectGuidVector(GetBaseObject(), targets));
+ }
+
+ ObjectVector const* GetStoredTargetVector(uint32 id) const
+ {
+ auto itr = _storedTargets.find(id);
+ if (itr != _storedTargets.end())
+ return itr->second.GetObjectVector();
+ return nullptr;
+ }
void StoreCounter(uint32 id, uint32 value, uint32 reset);
uint32 GetCounterValue(uint32 id) const;
@@ -84,14 +96,12 @@ class TC_GAME_API SmartScript
GameObject* FindGameObjectNear(WorldObject* searchObject, ObjectGuid::LowType guid) const;
Creature* FindCreatureNear(WorldObject* searchObject, ObjectGuid::LowType guid) const;
- ObjectListMap* mTargetStorage;
-
void OnReset();
void ResetBaseObject();
//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;
@@ -137,6 +147,8 @@ class TC_GAME_API SmartScript
uint32 mTalkerEntry;
bool mUseTextTimer;
+ ObjectVectorMap _storedTargets;
+
SMARTAI_TEMPLATE mTemplate;
void InstallEvents();
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
index 7e660acf4a7..ec3cdbc9f19 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -1093,24 +1093,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 (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))
+ {
+ if (std::all_of(e.action.randomEmote.emotes.begin(), e.action.randomEmote.emotes.end(), [](uint32 emote) { return emote == 0; }))
+ {
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u does not have any non-zero emote",
+ e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
return false;
+ }
- if (e.action.randomEmote.emote5 && !IsEmoteValid(e, e.action.randomEmote.emote5))
+ 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; }))
+ {
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u does not have any non-zero action list",
+ e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
return false;
-
- if (e.action.randomEmote.emote6 && !IsEmoteValid(e, e.action.randomEmote.emote6))
+ }
+ 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; }))
+ {
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u does not have any non-zero waypoint id",
+ e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
return false;
+ }
break;
+ }
case SMART_ACTION_RANDOM_SOUND:
{
if (std::all_of(std::begin(e.action.randomSound.sounds), std::end(e.action.randomSound.sounds), [](uint32 sound) { return sound == 0; }))
@@ -1194,32 +1209,34 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
return false;
break;
case SMART_ACTION_RANDOM_PHASE:
+ {
+ if (std::all_of(e.action.randomPhase.phases.begin(), e.action.randomPhase.phases.end(), [](uint32 phase) { return phase == 0; }))
{
- 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)
- {
- TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u attempts to set invalid phase, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
- return false;
- }
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u 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; }))
+ {
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u attempts to set invalid phase, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
+ return false;
}
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)
{
- if (e.action.randomPhaseRange.phaseMin >= SMART_EVENT_PHASE_MAX ||
- e.action.randomPhaseRange.phaseMax >= SMART_EVENT_PHASE_MAX)
- {
- TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u 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;
+ TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u 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;
+ }
case SMART_ACTION_SUMMON_CREATURE:
{
if (!IsCreatureValid(e, e.action.summonCreature.creature))
@@ -1351,7 +1368,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
}
case SMART_ACTION_CALL_RANDOM_RANGE_TIMED_ACTIONLIST:
{
- if (!IsMinMaxValid(e, e.action.randTimedActionList.entry1, e.action.randTimedActionList.entry2))
+ if (!IsMinMaxValid(e, e.action.randTimedActionList.actionLists[0], e.action.randTimedActionList.actionLists[1]))
return false;
break;
}
@@ -1406,11 +1423,14 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
{
if (e.GetScriptType() == SMART_SCRIPT_TYPE_CREATURE)
{
- int8 equipId = (int8)e.action.equip.entry;
- if (equipId && !sObjectMgr->GetEquipmentInfo(e.entryOrGuid, equipId))
+ if (int8 equipId = static_cast<int8>(e.action.equip.entry))
{
- TC_LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_EQUIP uses non-existent equipment info id %u for creature " SI64FMTD ", skipped.", equipId, e.entryOrGuid);
- return false;
+ EquipmentInfo const* eInfo = sObjectMgr->GetEquipmentInfo(e.entryOrGuid, equipId);
+ if (!eInfo)
+ {
+ TC_LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_EQUIP uses non-existent equipment info id %u for creature " SI64FMTD ", skipped.", equipId, e.entryOrGuid);
+ return false;
+ }
}
}
break;
@@ -1513,7 +1533,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
break;
}
- case SMART_ACTION_START_CLOSEST_WAYPOINT:
case SMART_ACTION_FOLLOW:
case SMART_ACTION_SET_ORIENTATION:
case SMART_ACTION_STORE_TARGET_LIST:
@@ -1559,7 +1578,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:
@@ -1698,35 +1716,3 @@ CacheSpellContainerBounds SmartAIMgr::GetCreateItemSpellContainerBounds(uint32 i
{
return CreateItemSpellStore.equal_range(itemId);
}
-
-ObjectGuidList::ObjectGuidList(ObjectList* objectList, WorldObject* baseObject)
-{
- ASSERT(objectList != NULL);
- 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());
- }
-}
-
-ObjectList* ObjectGuidList::GetObjectList()
-{
- 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
- TC_LOG_DEBUG("scripts.ai", "SmartScript::mTargetStorage stores a guid to an invalid object: %s", itr->ToString().c_str());
- }
- }
-
- return m_objectList;
-}
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index efd361cfb15..c3eea9fbaf4 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -18,13 +18,15 @@
#ifndef TRINITY_SMARTSCRIPTMGR_H
#define TRINITY_SMARTSCRIPTMGR_H
+#include "Creature.h"
#include "Define.h"
+#include "ObjectAccessor.h"
#include "ObjectGuid.h"
+#include "UnitDefines.h"
#include <map>
#include <string>
#include <unordered_map>
-class WorldObject;
enum SpellEffIndex : uint8;
struct WayPoint
@@ -658,12 +660,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
@@ -756,12 +753,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
@@ -960,9 +952,7 @@ struct SmartAction
{
uint32 entry;
uint32 mask;
- uint32 slot1;
- uint32 slot2;
- uint32 slot3;
+ std::array<uint32, MAX_EQUIPMENT_ITEMS> slots;
} equip;
struct
@@ -996,12 +986,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
@@ -1111,12 +1096,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
@@ -1569,31 +1549,43 @@ struct SmartScriptHolder
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:
+ ObjectGuidVector(WorldObject* baseObject, ObjectVector const& objectVector) : _baseObject(baseObject), _objectVector(objectVector)
+ {
+ _guidVector.reserve(_objectVector.size());
+ for (WorldObject* obj : _objectVector)
+ _guidVector.push_back(obj->GetGUID());
+ }
-public:
- ObjectGuidList(ObjectList* objectList, WorldObject* baseObject);
+ ObjectVector const* GetObjectVector() const
+ {
+ UpdateObjects();
+ return &_objectVector;
+ }
- ObjectList* GetObjectList();
+ ~ObjectGuidVector() { }
- bool Equals(ObjectList* objectList)
- {
- return m_objectList == objectList;
- }
+ private:
+ WorldObject* const _baseObject;
+ mutable ObjectVector _objectVector;
- ~ObjectGuidList()
- {
- delete m_objectList;
- delete m_guidList;
- }
+ GuidVector _guidVector;
+
+ //sanitize vector using _guidVector
+ void UpdateObjects() const
+ {
+ _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 TC_GAME_API SmartWaypointMgr
{