Skip to content

Commit

Permalink
Core/AI: Do not expose internal storage of SummonList
Browse files Browse the repository at this point in the history
  • Loading branch information
xurxogr committed Mar 21, 2013
1 parent 64cffa1 commit d091097
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 72 deletions.
30 changes: 14 additions & 16 deletions src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,28 @@ struct TSpellSummary

void SummonList::DoZoneInCombat(uint32 entry)
{
for (iterator i = begin(); i != end();)
for (StorageType::iterator i = storage_.begin(); i != storage_.end();)
{
Creature* summon = Unit::GetCreature(*me, *i);
++i;
if (summon && summon->IsAIEnabled
&& (!entry || summon->GetEntry() == entry))
&& (!entry || summon->GetEntry() == entry))
{
summon->AI()->DoZoneInCombat();
}
}
}

void SummonList::DespawnEntry(uint32 entry)
{
for (iterator i = begin(); i != end();)
for (StorageType::iterator i = storage_.begin(); i != storage_.end();)
{
Creature* summon = Unit::GetCreature(*me, *i);
if (!summon)
erase(i++);
i = storage_.erase(i);
else if (summon->GetEntry() == entry)
{
erase(i++);
i = storage_.erase(i);
summon->DespawnOrUnsummon();
}
else
Expand All @@ -53,33 +55,29 @@ void SummonList::DespawnEntry(uint32 entry)

void SummonList::DespawnAll()
{
while (!empty())
while (!storage_.empty())
{
Creature* summon = Unit::GetCreature(*me, *begin());
if (!summon)
erase(begin());
else
{
erase(begin());
Creature* summon = Unit::GetCreature(*me, storage_.front());
storage_.pop_front();
if (summon)
summon->DespawnOrUnsummon();
}
}
}

void SummonList::RemoveNotExisting()
{
for (iterator i = begin(); i != end();)
for (StorageType::iterator i = storage_.begin(); i != storage_.end();)
{
if (Unit::GetCreature(*me, *i))
++i;
else
erase(i++);
i = storage_.erase(i);
}
}

bool SummonList::HasEntry(uint32 entry) const
{
for (const_iterator i = begin(); i != end(); ++i)
for (StorageType::const_iterator i = storage_.begin(); i != storage_.end(); ++i)
{
Creature* summon = Unit::GetCreature(*me, *i);
if (summon && summon->GetEntry() == entry)
Expand Down
100 changes: 78 additions & 22 deletions src/server/game/AI/ScriptedAI/ScriptedCreature.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,33 +30,89 @@

class InstanceScript;

class SummonList : public std::list<uint64>

This comment has been minimized.

Copy link
@Shauren

Shauren Mar 21, 2013

Member

Or, you could have just made inheritance private here :P

This comment has been minimized.

Copy link
@DDuarte

DDuarte Mar 22, 2013

Contributor

I heard somewhere that it is a VeryBadIdea™ to inherit from standard containers, since they do not have virtual destructors.

class SummonList
{
public:
explicit SummonList(Creature* creature) : me(creature) {}
void Summon(Creature* summon) { push_back(summon->GetGUID()); }
void Despawn(Creature* summon) { remove(summon->GetGUID()); }
void DespawnEntry(uint32 entry);
void DespawnAll();
public:
typedef std::list<uint64> StorageType;
typedef StorageType::iterator iterator;
typedef StorageType::const_iterator const_iterator;
typedef StorageType::size_type size_type;
typedef StorageType::value_type value_type;

explicit SummonList(Creature* creature)
: me(creature)
{ }

// And here we see a problem of original inheritance approach. People started
// to exploit presence of std::list members, so I have to provide wrappers

iterator begin()
{
return storage_.begin();
}

const_iterator begin() const
{
return storage_.begin();
}

template <class Predicate> void DoAction(int32 info, Predicate& predicate, uint16 max = 0)
iterator end()
{
return storage_.end();
}

const_iterator end() const
{
return storage_.end();
}

iterator erase(iterator i)
{
return storage_.erase(i);
}

bool empty() const
{
return storage_.empty();
}

size_type size() const
{
return storage_.size();
}

void Summon(Creature const* summon) { storage_.push_back(summon->GetGUID()); }
void Despawn(Creature const* summon) { storage_.remove(summon->GetGUID()); }
void DespawnEntry(uint32 entry);
void DespawnAll();

template <typename T>
void DespawnIf(T const &predicate)
{
storage_.remove_if(predicate);
}

template <class Predicate>
void DoAction(int32 info, Predicate& predicate, uint16 max = 0)
{
// We need to use a copy of SummonList here, otherwise original SummonList would be modified
StorageType listCopy = storage_;
Trinity::Containers::RandomResizeList<uint64, Predicate>(listCopy, predicate, max);
for (StorageType::iterator i = listCopy.begin(); i != listCopy.end(); )
{
// We need to use a copy of SummonList here, otherwise original SummonList would be modified
std::list<uint64> listCopy = *this;
Trinity::Containers::RandomResizeList<uint64, Predicate>(listCopy, predicate, max);
for (iterator i = listCopy.begin(); i != listCopy.end(); )
{
Creature* summon = Unit::GetCreature(*me, *i++);
if (summon && summon->IsAIEnabled)
summon->AI()->DoAction(info);
}
Creature* summon = Unit::GetCreature(*me, *i++);
if (summon && summon->IsAIEnabled)
summon->AI()->DoAction(info);
}
}

void DoZoneInCombat(uint32 entry = 0);
void RemoveNotExisting();
bool HasEntry(uint32 entry) const;
private:
Creature* me;
void DoZoneInCombat(uint32 entry = 0);
void RemoveNotExisting();
bool HasEntry(uint32 entry) const;

private:
Creature* me;
StorageType storage_;
};

class EntryCheckPredicate
Expand Down
35 changes: 19 additions & 16 deletions src/server/scripts/Kalimdor/zone_winterspring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ enum Dummies
struct DialogueEntry
{
int32 TextEntry; ///< To be said text entry
uint32 SayerEntry; ///< Entry of the mob who should say
int32 SayerEntry; ///< Entry of the mob who should say
uint32 SayTimer; ///< Time delay until next text of array is said (0 stops)
};

Expand Down Expand Up @@ -202,9 +202,9 @@ class DialogueHelper

protected:
/// Will be called when a dialogue step was done
virtual void JustDidDialogueStep(int32 entry) {}
virtual void JustDidDialogueStep(int32 /*entry*/) {}
/// Will be called to get a speaker, MUST be implemented if not used in instances
virtual Creature* GetSpeakerByEntry(uint32 entry) { return NULL; }
virtual Creature* GetSpeakerByEntry(uint32 /*entry*/) { return NULL; }

private:
void DoNextDialogueStep()
Expand All @@ -225,7 +225,7 @@ class DialogueHelper
if (sayerEntry && textEntry >= 0)
{
// Use Speaker if directly provided
if(Creature* speaker = GetSpeakerByEntry(sayerEntry))
if (Creature* speaker = GetSpeakerByEntry(sayerEntry))
speaker->AI()->Talk(textEntry);
}

Expand Down Expand Up @@ -281,11 +281,11 @@ static Position wingThicketLocations[] =
{5515.98f, -4903.43f, 846.30f, 4.58f}, // 0 right priestess summon loc
{5501.94f, -4920.20f, 848.69f, 6.15f}, // 1 left priestess summon loc
{5497.35f, -4906.49f, 850.83f, 2.76f}, // 2 guard of elune summon loc
{5518.38f, -4913.47f, 845.57f}, // 3 right priestess move loc
{5510.36f, -4921.17f, 846.33f}, // 4 left priestess move loc
{5511.31f, -4913.82f, 847.17f}, // 5 guard of elune move loc
{5518.51f, -4917.56f, 845.23f}, // 6 right priestess second move loc
{5514.40f, -4921.16f, 845.49f} // 7 left priestess second move loc
{5518.38f, -4913.47f, 845.57f, 0.00f}, // 3 right priestess move loc
{5510.36f, -4921.17f, 846.33f, 0.00f}, // 4 left priestess move loc
{5511.31f, -4913.82f, 847.17f, 0.00f}, // 5 guard of elune move loc
{5518.51f, -4917.56f, 845.23f, 0.00f}, // 6 right priestess second move loc
{5514.40f, -4921.16f, 845.49f, 0.00f} // 7 left priestess second move loc
};

/*#####
Expand Down Expand Up @@ -549,15 +549,18 @@ class npc_ranshalla : public CreatureScript
}
}

Creature* GetSpeakerByEntry(uint32 entry)
Creature* GetSpeakerByEntry(int32 entry)
{
switch (entry)
{
case NPC_RANSHALLA: return me;
case NPC_VOICE_ELUNE: return me->GetMap()->GetCreature(_voiceEluneGUID);
case NPC_PRIESTESS_DATA_1: return me->GetMap()->GetCreature(_firstPriestessGUID);
case NPC_PRIESTESS_DATA_2: return me->GetMap()->GetCreature(_secondPriestessGUID);

case NPC_RANSHALLA:
return me;
case NPC_VOICE_ELUNE:
return me->GetMap()->GetCreature(_voiceEluneGUID);
case NPC_PRIESTESS_DATA_1:
return me->GetMap()->GetCreature(_firstPriestessGUID);
case NPC_PRIESTESS_DATA_2:
return me->GetMap()->GetCreature(_secondPriestessGUID);
default:
return NULL;
}
Expand Down Expand Up @@ -597,7 +600,7 @@ class go_elune_fire : public GameObjectScript
{
public:
go_elune_fire() : GameObjectScript("go_elune_fire") { }
bool OnGossipHello(Player* player, GameObject* go)
bool OnGossipHello(Player* /*player*/, GameObject* go)
{
// Check if we are using the torches or the altar
bool isAltar = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ class boss_trollgore : public CreatureScript

void JustSummoned(Creature* summon)
{
lSummons.push_back(summon->GetGUID());
lSummons.Summon(summon);
if (summon->AI())
summon->AI()->AttackStart(me);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ class boss_professor_putricide : public CreatureScript
me->SetFacingToObject(face);
me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL);
Talk(SAY_TRANSFORM_2);
summons.remove_if(AbominationDespawner(me));
summons.DespawnIf(AbominationDespawner(me));
events.ScheduleEvent(EVENT_RESUME_ATTACK, 8500, 0, PHASE_COMBAT_3);
break;
default:
Expand Down
9 changes: 4 additions & 5 deletions src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,10 @@ class boss_sapphiron : public CreatureScript

struct boss_sapphironAI : public BossAI
{
boss_sapphironAI(Creature* creature) : BossAI(creature, BOSS_SAPPHIRON)
, _phase(PHASE_NULL)
{
_map = me->GetMap();
}
boss_sapphironAI(Creature* creature) :
BossAI(creature, BOSS_SAPPHIRON), _phase(PHASE_NULL),
_map(me->GetMap())
{ }

void InitializeAI()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ class boss_malygos : public CreatureScript
{
VehicleCheckPredicate pred;
summons.DoAction(ACTION_DELAYED_DESPAWN, pred);
summons.remove_if(pred);
summons.DespawnIf(pred);
summons.DespawnAll();
}
else if (_phase == PHASE_THREE)
Expand Down
11 changes: 5 additions & 6 deletions src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,6 @@ class boss_freya : public CreatureScript
void Reset()
{
_Reset();
summons.clear();
trioWaveCount = 0;
trioWaveController = 0;
waveCount = 0;
Expand Down Expand Up @@ -494,7 +493,7 @@ class boss_freya : public CreatureScript
{
for (uint8 n = 0; n < 3; ++n)
{
summons.remove(Elemental[n][i]->GetGUID());
summons.Despawn(Elemental[n][i]);
Elemental[n][i]->DespawnOrUnsummon(5000);
trioDefeated[i] = true;
Elemental[n][i]->CastSpell(me, SPELL_REMOVE_10STACK, true);
Expand Down Expand Up @@ -625,15 +624,15 @@ class boss_freya : public CreatureScript
case NPC_ANCIENT_WATER_SPIRIT:
case NPC_STORM_LASHER:
ElementalGUID[trioWaveController][trioWaveCount] = summoned->GetGUID();
summons.push_back(summoned->GetGUID());
summons.Summon(summoned);
++trioWaveController;
if (trioWaveController > 2)
trioWaveController = 0;
break;
case NPC_DETONATING_LASHER:
case NPC_ANCIENT_CONSERVATOR:
default:
summons.push_back(summoned->GetGUID());
summons.Summon(summoned);
break;
}

Expand All @@ -654,12 +653,12 @@ class boss_freya : public CreatureScript
summoned->CastSpell(me, SPELL_REMOVE_2STACK, true);
summoned->CastSpell(who, SPELL_DETONATE, true);
summoned->DespawnOrUnsummon(5000);
summons.remove(summoned->GetGUID());
summons.Despawn(summoned);
break;
case NPC_ANCIENT_CONSERVATOR:
summoned->CastSpell(me, SPELL_REMOVE_25STACK, true);
summoned->DespawnOrUnsummon(5000);
summons.remove(summoned->GetGUID());
summons.Despawn(summoned);
break;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/server/scripts/Northrend/Ulduar/Ulduar/boss_hodir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,7 @@ class npc_hodir_mage : public CreatureScript
void SummonedCreatureDespawn(Creature* summoned)
{
if (summoned->GetEntry() == NPC_TOASTY_FIRE)
summons.remove(summoned->GetGUID());
summons.Despawn(summoned);
}

void UpdateAI(uint32 diff)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ class boss_kologarn : public CreatureScript
summon->CastSpell(me, SPELL_FOCUSED_EYEBEAM_VISUAL_RIGHT, true);
break;
case NPC_RUBBLE:
summons.push_back(summon->GetGUID());
summons.Summon(summon);
// absence of break intended
default:
return;
Expand Down
4 changes: 2 additions & 2 deletions src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ class boss_ichoron : public CreatureScript
{
summoned->SetSpeed(MOVE_RUN, 0.3f);
summoned->GetMotionMaster()->MoveFollow(me, 0, 0);
m_waterElements.push_back(summoned->GetGUID());
m_waterElements.Summon(summoned);
instance->SetData64(DATA_ADD_TRASH_MOB, summoned->GetGUID());
}
}
Expand All @@ -315,7 +315,7 @@ class boss_ichoron : public CreatureScript
{
if (summoned)
{
m_waterElements.remove(summoned->GetGUID());
m_waterElements.Despawn(summoned);
instance->SetData64(DATA_DEL_TRASH_MOB, summoned->GetGUID());
}
}
Expand Down

0 comments on commit d091097

Please sign in to comment.