aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2017-06-03 05:21:06 -0300
committerariel- <ariel-@users.noreply.github.com>2017-06-03 05:21:06 -0300
commita97439e8d63c0a78bda8a6ed4801f122385936e3 (patch)
treeee876298488db54768067cba1fca74a5409fa13f /src
parentabac1b34bcb84d65ef857076321af3acd22a3c9b (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
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp20
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp1894
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.h52
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp95
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h100
5 files changed, 741 insertions, 1420 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index 8fffb309696..0ffc48cfdce 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -235,12 +235,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);
@@ -264,11 +264,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)
@@ -277,6 +277,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 2527be8e1c4..d10e589bb14 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -44,7 +44,6 @@ SmartScript::SmartScript()
trigger = nullptr;
mEventPhase = 0;
mPathId = 0;
- mTargetStorage = new ObjectListMap();
mTextTimer = 0;
mLastTextID = 0;
mUseTextTimer = false;
@@ -56,11 +55,6 @@ SmartScript::SmartScript()
SmartScript::~SmartScript()
{
- for (ObjectListMap::iterator itr = mTargetStorage->begin(); itr != mTargetStorage->end(); ++itr)
- delete itr->second;
-
- delete mTargetStorage;
- mCounterList.clear();
}
void SmartScript::OnReset()
@@ -95,7 +89,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)
{
- //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))
@@ -109,38 +103,35 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (Unit* tempInvoker = GetLastInvoker())
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: Invoker: %s (guidlow: %u)", tempInvoker->GetName().c_str(), tempInvoker->GetGUID().GetCounter());
+ 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)
@@ -160,107 +151,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 (GuidLow: %u), textGroupId: %u",
- (*itr)->GetName().c_str(), (*itr)->GetGUID().GetCounter(), 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 (GuidLow: %u), textGroupId: %u",
+ target->GetName().c_str(), target->GetGUID().GetCounter(), 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 (GuidLow: %u), emote: %u",
- (*itr)->GetName().c_str(), (*itr)->GetGUID().GetCounter(), e.action.emote.emote);
- }
+ target->ToUnit()->HandleEmoteCommand(e.action.emote.emote);
+ TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_PLAY_EMOTE: target: %s (GuidLow: %u), emote: %u",
+ target->GetName().c_str(), target->GetGUID().GetCounter(), 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 (GuidLow: %u), sound: %u, onlyself: %u",
- (*itr)->GetName().c_str(), (*itr)->GetGUID().GetCounter(), 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 (GuidLow: %u), sound: %u, onlyself: %u",
+ target->GetName().c_str(), target->GetGUID().GetCounter(), 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, GuidLow %u set faction to %u",
- (*itr)->GetEntry(), (*itr)->GetGUID().GetCounter(), 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, GuidLow %u set faction to %u",
+ target->GetEntry(), target->GetGUID().GetCounter(), 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, GuidLow %u set faction to %u",
- (*itr)->GetEntry(), (*itr)->GetGUID().GetCounter(), ci->faction);
- }
+ target->ToCreature()->SetFaction(ci->faction);
+ TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_FACTION: Creature entry %u, GuidLow %u set faction to %u",
+ target->GetEntry(), target->GetGUID().GetCounter(), 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)
@@ -271,143 +234,99 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(e.action.morphOrMount.creature))
{
uint32 displayId = ObjectMgr::ChooseDisplayId(ci);
- (*itr)->ToCreature()->SetDisplayId(displayId);
+ target->ToCreature()->SetDisplayId(displayId);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: Creature entry %u, GuidLow %u set displayid to %u",
- (*itr)->GetEntry(), (*itr)->GetGUID().GetCounter(), displayId);
+ target->GetEntry(), target->GetGUID().GetCounter(), displayId);
}
}
//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, GuidLow %u set displayid to %u",
- (*itr)->GetEntry(), (*itr)->GetGUID().GetCounter(), e.action.morphOrMount.model);
+ target->GetEntry(), target->GetGUID().GetCounter(), 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, GuidLow %u demorphs.",
- (*itr)->GetEntry(), (*itr)->GetGUID().GetCounter());
+ target->GetEntry(), target->GetGUID().GetCounter());
}
}
-
- 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 guidLow %u fails quest %u",
- (*itr)->GetGUID().GetCounter(), e.action.quest.quest);
+ target->GetGUID().GetCounter(), 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);
- TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_OFFER_QUEST: Player guidLow %u - offering quest %u", pTarget->GetGUID().GetCounter(), e.action.questOffer.questID);
+ TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_OFFER_QUEST: Player guidLow %u - offering quest %u", player->GetGUID().GetCounter(), e.action.questOffer.questID);
}
+ }
}
else
{
- (*itr)->ToPlayer()->AddQuestAndCheckCompletion(q, nullptr);
+ player->AddQuestAndCheckCompletion(q, nullptr);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_OFFER_QUEST: Player guidLow %u - quest %u added",
- pTarget->GetGUID().GetCounter(), e.action.questOffer.questID);
+ player->GetGUID().GetCounter(), 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 guidLow %u handle random emote %u",
- (*itr)->GetGUID().GetCounter(), emote);
+ target->GetGUID().GetCounter(), emote);
}
}
-
- delete targets;
break;
}
case SMART_ACTION_THREAT_ALL_PCT:
@@ -416,7 +335,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()))
{
@@ -432,71 +351,56 @@ 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 guidLow %u modify threat for unit %u, value %i",
- me->GetGUID().GetCounter(), (*itr)->GetGUID().GetCounter(), e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC);
+ me->GetGUID().GetCounter(), target->GetGUID().GetCounter(), 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: Player guidLow %u credited quest %u",
- (*itr)->GetGUID().GetCounter(), e.action.quest.quest);
+ target->GetGUID().GetCounter(), 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::RandomResizeList(*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)
@@ -517,32 +421,30 @@ 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);
int32 mana = me->GetPower(POWER_MANA);
- if (me->GetDistance(*itr) > spellInfo->GetMaxRange(true) ||
- me->GetDistance(*itr) < spellInfo->GetMinRange(true) ||
- !me->IsWithinLOSInMap(*itr) ||
+ if (me->GetDistance(target) > spellInfo->GetMaxRange(true) ||
+ me->GetDistance(target) < spellInfo->GetMinRange(true) ||
+ !me->IsWithinLOSInMap(target) ||
mana < spellInfo->CalcPowerCost(me, spellInfo->GetSchoolMask()))
- _allowMove = true;
+ 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: %u casts spell %u on target %u with castflags %u",
- (me ? me->GetGUID() : go->GetGUID()).GetTypeName(), me ? me->GetGUID().GetCounter() : go->GetGUID().GetCounter(), e.action.cast.spell, (*itr)->GetGUID().GetCounter(), e.action.cast.castFlags);
+ (me ? me->GetGUID() : go->GetGUID()).GetTypeName(), me ? me->GetGUID().GetCounter() : go->GetGUID().GetCounter(), e.action.cast.spell, target->GetGUID().GetCounter(), 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:
@@ -551,19 +453,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::RandomResizeList(*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);
@@ -577,149 +478,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 %u casts spell %u on target %u with castflags %u",
- tempLastInvoker->GetGUID().GetCounter(), e.action.cast.spell, (*itr)->GetGUID().GetCounter(), e.action.cast.castFlags);
+ tempLastInvoker->GetGUID().GetCounter(), e.action.cast.spell, target->GetGUID().GetCounter(), 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 unit %u",
- e.action.cast.spell, (*itr)->GetGUID().GetCounter());
+ e.action.cast.spell, target->GetGUID().GetCounter());
}
}
-
- 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. Gameobject %u (entry: %u) activated",
- (*itr)->GetGUID().GetCounter(), (*itr)->GetEntry());
+ target->GetGUID().GetCounter(), 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. Gameobject %u (entry: %u) reset",
- (*itr)->GetGUID().GetCounter(), (*itr)->GetEntry());
+ target->GetGUID().GetCounter(), 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()->SetUInt32Value(UNIT_NPC_EMOTESTATE, e.action.emote.emote);
+ target->ToUnit()->SetUInt32Value(UNIT_NPC_EMOTESTATE, e.action.emote.emote);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_EMOTE_STATE. Unit %u set emotestate to %u",
- (*itr)->GetGUID().GetCounter(), e.action.emote.emote);
+ target->GetGUID().GetCounter(), 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()->SetFlag(UNIT_FIELD_FLAGS, e.action.unitFlag.flag);
+ target->ToUnit()->SetFlag(UNIT_FIELD_FLAGS, e.action.unitFlag.flag);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_UNIT_FLAG. Unit %u added flag %u to UNIT_FIELD_FLAGS",
- (*itr)->GetGUID().GetCounter(), e.action.unitFlag.flag);
+ target->GetGUID().GetCounter(), e.action.unitFlag.flag);
}
else
{
- (*itr)->ToUnit()->SetFlag(UNIT_FIELD_FLAGS_2, e.action.unitFlag.flag);
+ target->ToUnit()->SetFlag(UNIT_FIELD_FLAGS_2, e.action.unitFlag.flag);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_UNIT_FLAG. Unit %u added flag %u to UNIT_FIELD_FLAGS_2",
- (*itr)->GetGUID().GetCounter(), e.action.unitFlag.flag);
+ target->GetGUID().GetCounter(), 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()->RemoveFlag(UNIT_FIELD_FLAGS, e.action.unitFlag.flag);
+ target->ToUnit()->RemoveFlag(UNIT_FIELD_FLAGS, e.action.unitFlag.flag);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_REMOVE_UNIT_FLAG. Unit %u removed flag %u to UNIT_FIELD_FLAGS",
- (*itr)->GetGUID().GetCounter(), e.action.unitFlag.flag);
+ target->GetGUID().GetCounter(), e.action.unitFlag.flag);
}
else
{
- (*itr)->ToUnit()->RemoveFlag(UNIT_FIELD_FLAGS_2, e.action.unitFlag.flag);
+ target->ToUnit()->RemoveFlag(UNIT_FIELD_FLAGS_2, e.action.unitFlag.flag);
TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_REMOVE_UNIT_FLAG. Unit %u removed flag %u to UNIT_FIELD_FLAGS_2",
- (*itr)->GetGUID().GetCounter(), e.action.unitFlag.flag);
+ target->GetGUID().GetCounter(), e.action.unitFlag.flag);
}
}
}
-
- delete targets;
break;
}
case SMART_ACTION_AUTO_ATTACK:
@@ -820,33 +683,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: Unit %u, spell %u",
- (*itr)->GetGUID().GetCounter(), e.action.removeAura.spell);
+ target->GetGUID().GetCounter(), e.action.removeAura.spell);
}
-
- delete targets;
break;
}
case SMART_ACTION_FOLLOW:
@@ -854,26 +711,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: Creature %u following target %u",
- me->GetGUID().GetCounter(), (*itr)->GetGUID().GetCounter());
+ me->GetGUID().GetCounter(), target->GetGUID().GetCounter());
break;
}
}
-
- delete targets;
break;
}
case SMART_ACTION_RANDOM_PHASE:
@@ -881,28 +735,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;
- }
- }
-
- if (count == 0)
- break;
+ 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; });
- 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: Creature %u sets event phase to %u",
GetBaseObject()->GetGUID().GetCounter(), phase);
@@ -935,26 +772,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: Player %u, Killcredit: %u",
- (*itr)->GetGUID().GetCounter(), e.action.killedMonster.creature);
+ target->GetGUID().GetCounter(), 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;
}
@@ -1007,29 +838,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:
@@ -1043,39 +864,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 %u, target: %u", me->GetGUID().GetCounter(), (*itr)->GetGUID().GetCounter());
+ target->ToCreature()->SetInCombatWithZone();
+ TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_SET_IN_COMBAT_WITH_ZONE: Creature %u, target: %u", me->GetGUID().GetCounter(), target->GetGUID().GetCounter());
}
-
- 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);
sCreatureTextMgr->SendChatPacket(me, builder, CHAT_MSG_MONSTER_EMOTE);
}
- TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_CALL_FOR_HELP: Creature %u, target: %u", me->GetGUID().GetCounter(), (*itr)->GetGUID().GetCounter());
+ TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_CALL_FOR_HELP: Creature %u, target: %u", me->GetGUID().GetCounter(), target->GetGUID().GetCounter());
}
-
- delete targets;
+ }
break;
}
case SMART_ACTION_SET_SHEATH:
@@ -1090,60 +903,42 @@ 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_MASK:
{
- 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))
- (*itr)->ToUnit()->SetPhaseMask(e.action.ingamePhaseMask.mask, true);
- else if (IsGameObject(*itr))
- (*itr)->ToGameObject()->SetPhaseMask(e.action.ingamePhaseMask.mask, true);
+ if (IsUnit(target))
+ target->ToUnit()->SetPhaseMask(e.action.ingamePhaseMask.mask, true);
+ else if (IsGameObject(target))
+ target->ToGameObject()->SetPhaseMask(e.action.ingamePhaseMask.mask, 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)
@@ -1151,110 +946,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));
+ target->ToUnit()->Mount(ObjectMgr::ChooseDisplayId(cInfo));
}
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 (!(e.event.event_flags & SMART_EVENT_FLAG_WHILE_CHARMED) && IsCharmedCreature(*itr))
- continue;
+ if (!IsCreature(target))
+ continue;
- Position pos = (*itr)->GetPosition();
+ if (!(e.event.event_flags & SMART_EVENT_FLAG_WHILE_CHARMED) && IsCharmedCreature(target))
+ continue;
- // 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);
- }
+ Position pos = target->GetPosition();
- 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:
@@ -1262,36 +1025,27 @@ 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:
{
- 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 = GetBaseObject()->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 = GetBaseObject()->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)
@@ -1307,21 +1061,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!GetBaseObject())
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));
- G3D::Quat rot = G3D::Matrix3::fromEulerAnglesZYX(pos.GetOrientation(), 0.f, 0.f);
- GetBaseObject()->SummonGameObject(e.action.summonGO.entry, pos, rot, e.action.summonGO.despawnTime);
- }
-
- delete targets;
+ Position pos = target->GetPositionWithOffset(Position(e.target.x, e.target.y, e.target.z, e.target.o));
+ G3D::Quat rot = G3D::Matrix3::fromEulerAnglesZYX(pos.GetOrientation(), 0.f, 0.f);
+ GetBaseObject()->SummonGameObject(e.action.summonGO.entry, pos, rot, e.action.summonGO.despawnTime);
}
if (e.GetTargetType() != SMART_TARGET_POSITION)
@@ -1333,19 +1077,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:
@@ -1355,59 +1093,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:
@@ -1444,31 +1163,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:
@@ -1480,22 +1196,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);
@@ -1541,35 +1248,22 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
break;
if (e.GetTargetType() == SMART_TARGET_SELF)
- me->SetFacingTo((me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && me->GetTransGUID() ?
- me->GetTransportHomePosition() : me->GetHomePosition()).GetOrientation());
+ me->SetFacingTo((me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && me->GetTransGUID() ? 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:
@@ -1587,12 +1281,9 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
e.GetTargetType() == SMART_TARGET_CLOSEST_ENEMY || e.GetTargetType() == SMART_TARGET_CLOSEST_FRIENDLY ||
e.GetTargetType() == SMART_TARGET_SELF || e.GetTargetType() == SMART_TARGET_STORED)*/
{
- 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)
@@ -1616,82 +1307,56 @@ 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())
{
- uint32 slot[3];
- int8 equipId = (int8)e.action.equip.entry;
- if (equipId)
+ std::array<uint32, 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->ItemEntry[0];
- slot[1] = einfo->ItemEntry[1];
- slot[2] = einfo->ItemEntry[2];
+
+ std::copy(std::begin(eInfo->ItemEntry), std::end(eInfo->ItemEntry), std::begin(slot));
}
else
- {
- slot[0] = e.action.equip.slot1;
- slot[1] = e.action.equip.slot2;
- slot[2] = e.action.equip.slot3;
- }
- if (!e.action.equip.mask || (e.action.equip.mask & 1))
- npc->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, slot[0]);
- if (!e.action.equip.mask || (e.action.equip.mask & 2))
- npc->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, slot[1]);
- if (!e.action.equip.mask || (e.action.equip.mask & 4))
- npc->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, slot[2]);
+ std::copy(std::begin(e.action.equip.slots), std::end(e.action.equip.slots), std::begin(slot));
+
+ for (uint32 i = 0; i < MAX_EQUIPMENT_ITEMS; ++i)
+ if (!e.action.equip.mask || (e.action.equip.mask & (1 << i)))
+ npc->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i, slot[i]);
}
}
-
- delete targets;
break;
}
case SMART_ACTION_CREATE_TIMED_EVENT:
@@ -1735,35 +1400,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:
@@ -1781,17 +1440,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:
@@ -1802,402 +1456,258 @@ 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()->SetUInt32Value(UNIT_NPC_FLAGS, e.action.unitFlag.flag);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsCreature(target))
+ target->ToUnit()->SetUInt32Value(UNIT_NPC_FLAGS, 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()->SetFlag(UNIT_NPC_FLAGS, e.action.unitFlag.flag);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsCreature(target))
+ target->ToUnit()->SetFlag(UNIT_NPC_FLAGS, 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()->RemoveFlag(UNIT_NPC_FLAGS, e.action.unitFlag.flag);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsCreature(target))
+ target->ToUnit()->RemoveFlag(UNIT_NPC_FLAGS, e.action.unitFlag.flag);
break;
}
case SMART_ACTION_CROSS_CAST:
{
- ObjectList* casters = GetTargets(CreateEvent(SMART_EVENT_UPDATE_IC, 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, CreateEvent(SMART_EVENT_UPDATE_IC, 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 %d 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 %d 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))
- (*itr)->ToUnit()->SetByteFlag(UNIT_FIELD_BYTES_1, e.action.setunitByte.type, e.action.setunitByte.byte1);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsUnit(target))
+ target->ToUnit()->SetByteFlag(UNIT_FIELD_BYTES_1, e.action.setunitByte.type, e.action.setunitByte.byte1);
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))
- (*itr)->ToUnit()->RemoveByteFlag(UNIT_FIELD_BYTES_1, e.action.delunitByte.type, e.action.delunitByte.byte1);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsUnit(target))
+ target->ToUnit()->RemoveByteFlag(UNIT_FIELD_BYTES_1, e.action.delunitByte.type, e.action.delunitByte.byte1);
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 (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
- if (IsUnit(*itr))
- (*itr)->ToUnit()->SetUInt32Value(UNIT_DYNAMIC_FLAGS, e.action.unitFlag.flag);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsUnit(target))
+ target->ToUnit()->SetUInt32Value(UNIT_DYNAMIC_FLAGS, e.action.unitFlag.flag);
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)
- if (IsUnit(*itr))
- (*itr)->ToUnit()->SetFlag(UNIT_DYNAMIC_FLAGS, e.action.unitFlag.flag);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsUnit(target))
+ target->ToUnit()->SetFlag(UNIT_DYNAMIC_FLAGS, e.action.unitFlag.flag);
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)
- if (IsUnit(*itr))
- (*itr)->ToUnit()->RemoveFlag(UNIT_DYNAMIC_FLAGS, e.action.unitFlag.flag);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsUnit(target))
+ target->ToUnit()->RemoveFlag(UNIT_DYNAMIC_FLAGS, e.action.unitFlag.flag);
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:
@@ -2208,19 +1718,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);
@@ -2230,24 +1736,18 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
SendGossipMenuFor(player, 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 ||
@@ -2255,79 +1755,47 @@ 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()->SetUInt32Value(GAMEOBJECT_FLAGS, e.action.goFlag.flag);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsGameObject(target))
+ target->ToGameObject()->SetUInt32Value(GAMEOBJECT_FLAGS, e.action.goFlag.flag);
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()->SetFlag(GAMEOBJECT_FLAGS, e.action.goFlag.flag);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsGameObject(target))
+ target->ToGameObject()->SetFlag(GAMEOBJECT_FLAGS, 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(GAMEOBJECT_FLAGS, e.action.goFlag.flag);
-
- delete targets;
+ for (WorldObject* target : targets)
+ if (IsGameObject(target))
+ target->ToGameObject()->RemoveFlag(GAMEOBJECT_FLAGS, e.action.goFlag.flag);
break;
}
case SMART_ACTION_SUMMON_CREATURE_GROUP:
@@ -2335,46 +1803,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:
@@ -2401,59 +1853,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;
}
@@ -2464,37 +1901,25 @@ 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;
}
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:
@@ -2507,67 +1932,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:
@@ -2579,33 +1974,23 @@ 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;
}
default:
@@ -2639,11 +2024,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 %d 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)
{
@@ -2744,7 +2131,7 @@ SmartScriptHolder SmartScript::CreateEvent(SMART_EVENT e, uint32 event_flags, ui
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)
@@ -2753,29 +2140,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:
@@ -2783,11 +2168,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:
@@ -2795,11 +2180,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:
@@ -2807,27 +2192,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)
@@ -2839,90 +2224,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:
@@ -2935,7 +2316,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:
@@ -2948,60 +2329,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 = GetClosestCreatureWithEntry(baseObject, 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 = GetClosestGameObjectWithEntry(baseObject, 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);
+ targets.push_back(target);
break;
}
case SMART_TARGET_OWNER_OR_SUMMONER:
@@ -3019,22 +2393,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);
+ 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);
+ targets.push_back(base);
}
break;
}
@@ -3042,11 +2416,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;
}
@@ -3054,14 +2428,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:
@@ -3073,12 +2447,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;
@@ -3088,7 +2462,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;
}
@@ -3097,27 +2471,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);
- obj->VisitNearbyObject(dist, searcher);
- }
- return targets;
+ if (!obj)
+ return;
+
+ Trinity::AllWorldObjectsInRange u_check(obj, dist);
+ Trinity::WorldObjectListSearcher<Trinity::AllWorldObjectsInRange> searcher(obj, targets, u_check);
+ obj->VisitNearbyObject(dist, searcher);
}
void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob)
@@ -3240,26 +2604,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:
@@ -3565,8 +2929,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:
@@ -3576,37 +2939,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:
@@ -3974,7 +3330,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;
@@ -3987,27 +3343,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);
me->VisitNearbyObject(range, searcher);
}
-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);
me->VisitNearbyObject(range, searcher);
}
-Unit* SmartScript::DoFindClosestFriendlyInRange(float range, bool playerOnly)
+Unit* SmartScript::DoFindClosestFriendlyInRange(float range, bool playerOnly) const
{
if (!me)
return nullptr;
@@ -4048,7 +3404,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 5b3221cf3ea..ed077389e6e 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.h
+++ b/src/server/game/AI/SmartScripts/SmartScript.h
@@ -41,19 +41,19 @@ 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);
void ProcessEvent(SmartScriptHolder& e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, const SpellInfo* spell = nullptr, GameObject* gob = nullptr);
bool CheckTimer(SmartScriptHolder const& e) const;
- void RecalcTimer(SmartScriptHolder& e, uint32 min, uint32 max);
+ static void RecalcTimer(SmartScriptHolder& e, uint32 min, uint32 max);
void UpdateTimer(SmartScriptHolder& e, uint32 const diff);
- void InitTimer(SmartScriptHolder& e);
+ static void InitTimer(SmartScriptHolder& e);
void ProcessAction(SmartScriptHolder& e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, const SpellInfo* spell = nullptr, GameObject* gob = nullptr);
void ProcessTimedAction(SmartScriptHolder& e, uint32 const& min, uint32 const& max, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, const SpellInfo* spell = nullptr, GameObject* gob = nullptr);
- ObjectList* GetTargets(SmartScriptHolder const& e, Unit* invoker = nullptr);
- ObjectList* GetWorldObjectsInDist(float dist);
+ void GetTargets(ObjectVector& targets, SmartScriptHolder const& e, Unit* invoker = nullptr) const;
+ void GetWorldObjectsInDist(ObjectVector& objects, float dist) const;
void InstallTemplate(SmartScriptHolder const& e);
- SmartScriptHolder CreateEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, 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 CreateEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, 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, 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* obj = nullptr;
if (me)
@@ -97,26 +97,16 @@ 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;
- void StoreTargetList(ObjectList* targets, uint32 id)
+ void StoreTargetList(ObjectVector const& targets, uint32 id)
{
- if (!targets)
- return;
-
- if (mTargetStorage->find(id) != mTargetStorage->end())
- {
- // check if already stored
- if ((*mTargetStorage)[id]->Equals(targets))
- return;
-
- delete (*mTargetStorage)[id];
- }
-
- (*mTargetStorage)[id] = new ObjectGuidList(targets, GetBaseObject());
+ // insert or replace
+ _storedTargets.erase(id);
+ _storedTargets.emplace(id, ObjectGuidVector(GetBaseObject(), targets));
}
bool IsSmart(Creature* c = nullptr)
@@ -148,11 +138,11 @@ class TC_GAME_API SmartScript
return smart;
}
- ObjectList* GetTargetList(uint32 id)
+ ObjectVector const* GetStoredTargetVector(uint32 id) const
{
- ObjectListMap::iterator itr = mTargetStorage->find(id);
- if (itr != mTargetStorage->end())
- return (*itr).second->GetObjectList();
+ auto itr = _storedTargets.find(id);
+ if (itr != _storedTargets.end())
+ return itr->second.GetObjectVector();
return nullptr;
}
@@ -203,8 +193,6 @@ class TC_GAME_API SmartScript
return creatureItr != bounds.second ? creatureItr->second : bounds.first->second;
}
- ObjectListMap* mTargetStorage;
-
void OnReset();
void ResetBaseObject()
{
@@ -238,7 +226,7 @@ class TC_GAME_API SmartScript
//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;
@@ -288,6 +276,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 068ec95b6c9..139826f8efb 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -894,24 +894,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 %d 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 %d 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 %d 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(e.action.randomSound.sounds.begin(), e.action.randomSound.sounds.end(), [](uint32 sound) { return sound == 0; }))
@@ -995,32 +1010,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 %d 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 %d 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 %d 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 %d 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 %d 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))
@@ -1152,7 +1169,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;
}
@@ -1207,12 +1224,10 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
{
if (e.GetScriptType() == SMART_SCRIPT_TYPE_CREATURE)
{
- int8 equipId = (int8)e.action.equip.entry;
-
- if (equipId)
+ if (int8 equipId = static_cast<int8>(e.action.equip.entry))
{
- EquipmentInfo const* einfo = sObjectMgr->GetEquipmentInfo(e.entryOrGuid, equipId);
- if (!einfo)
+ EquipmentInfo const* eInfo = sObjectMgr->GetEquipmentInfo(e.entryOrGuid, equipId);
+ if (!eInfo)
{
TC_LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_EQUIP uses non-existent equipment info id %u for creature %u, skipped.", equipId, e.entryOrGuid);
return false;
@@ -1247,7 +1262,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:
@@ -1294,7 +1308,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:
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index 61f006aea86..c538dad9514 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -641,12 +641,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
@@ -739,12 +734,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
@@ -935,9 +925,7 @@ struct SmartAction
{
uint32 entry;
uint32 mask;
- uint32 slot1;
- uint32 slot2;
- uint32 slot3;
+ std::array<uint32, MAX_EQUIPMENT_ITEMS> slots;
} equip;
struct
@@ -971,12 +959,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
@@ -1086,12 +1069,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
@@ -1512,59 +1490,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:
- 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)
+ public:
+ ObjectGuidVector(WorldObject* baseObject, ObjectVector const& objectVector) : _baseObject(baseObject), _objectVector(objectVector)
{
- m_guidList->push_back((*itr)->GetGUID());
+ _guidVector.reserve(_objectVector.size());
+ for (WorldObject* obj : _objectVector)
+ _guidVector.push_back(obj->GetGUID());
}
- }
- ObjectList* GetObjectList()
- {
- if (m_baseObject)
+ ObjectVector const* GetObjectVector() const
{
- //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());
- }
+ UpdateObjects();
+ return &_objectVector;
}
- return m_objectList;
- }
+ ~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
{