aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Object/Object.cpp58
1 files changed, 40 insertions, 18 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 25132339840..fd868cfc649 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -24,6 +24,7 @@
#include "CombatLogPackets.h"
#include "Common.h"
#include "Creature.h"
+#include "CreatureGroups.h"
#include "DB2Stores.h"
#include "GameTime.h"
#include "GridNotifiersImpl.h"
@@ -1983,6 +1984,38 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
return summon;
}
+template <std::invocable<TempSummonData const&> SummonCreature>
+static void SummonCreatureGroup(uint32 summonerId, SummonerType summonerType, uint8 group, std::list<TempSummon*>* summoned, SummonCreature summonCreature)
+{
+ std::vector<TempSummonData> const* data = sObjectMgr->GetSummonGroup(summonerId, summonerType, group);
+ if (!data)
+ {
+ TC_LOG_WARN("scripts", "Summoner {} type {} tried to summon non-existing summon group {}.", summonerId, summonerType, group);
+ return;
+ }
+
+ std::vector<TempSummon*> summons;
+ summons.reserve(data->size());
+
+ for (TempSummonData const& tempSummonData : *data)
+ if (TempSummon* summon = summonCreature(tempSummonData))
+ summons.push_back(summon);
+
+ CreatureGroup* creatureGroup = new CreatureGroup(0);
+ for (TempSummon* summon : summons)
+ {
+ if (!summon->IsInWorld()) // evil script might despawn a summon
+ continue;
+
+ creatureGroup->AddMember(summon);
+ if (summoned)
+ summoned->push_back(summon);
+ }
+
+ if (creatureGroup->IsEmpty())
+ delete creatureGroup;
+}
+
/**
* Summons group of creatures.
*
@@ -1992,14 +2025,10 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
void Map::SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list /*= nullptr*/)
{
- std::vector<TempSummonData> const* data = sObjectMgr->GetSummonGroup(GetId(), SUMMONER_TYPE_MAP, group);
- if (!data)
- return;
-
- for (std::vector<TempSummonData>::const_iterator itr = data->begin(); itr != data->end(); ++itr)
- if (TempSummon* summon = SummonCreature(itr->entry, itr->pos, nullptr, itr->time))
- if (list)
- list->push_back(summon);
+ ::SummonCreatureGroup(GetId(), SUMMONER_TYPE_MAP, group, list, [&](TempSummonData const& tempSummonData)
+ {
+ return SummonCreature(tempSummonData.entry, tempSummonData.pos, nullptr, tempSummonData.time);
+ });
}
ZoneScript* WorldObject::FindZoneScript() const
@@ -2148,17 +2177,10 @@ void WorldObject::SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list
{
ASSERT((GetTypeId() == TYPEID_GAMEOBJECT || GetTypeId() == TYPEID_UNIT) && "Only GOs and creatures can summon npc groups!");
- std::vector<TempSummonData> const* data = sObjectMgr->GetSummonGroup(GetEntry(), GetTypeId() == TYPEID_GAMEOBJECT ? SUMMONER_TYPE_GAMEOBJECT : SUMMONER_TYPE_CREATURE, group);
- if (!data)
+ ::SummonCreatureGroup(GetEntry(), GetTypeId() == TYPEID_GAMEOBJECT ? SUMMONER_TYPE_GAMEOBJECT : SUMMONER_TYPE_CREATURE, group, list, [&](TempSummonData const& tempSummonData)
{
- TC_LOG_WARN("scripts", "{} ({}) tried to summon non-existing summon group {}.", GetName(), GetGUID().ToString(), group);
- return;
- }
-
- for (std::vector<TempSummonData>::const_iterator itr = data->begin(); itr != data->end(); ++itr)
- if (TempSummon* summon = SummonCreature(itr->entry, itr->pos, itr->type, Milliseconds(itr->time)))
- if (list)
- list->push_back(summon);
+ return SummonCreature(tempSummonData.entry, tempSummonData.pos, tempSummonData.type, tempSummonData.time);
+ });
}
Creature* WorldObject::FindNearestCreature(uint32 entry, float range, bool alive) const