aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorpete318 <pete318@users.noreply.github.com>2016-02-03 12:34:38 +0000
committerpete318 <pete318@hotmail.com>2016-02-03 19:27:36 +0100
commitfe2a0fda4464effeb2fb655da84a0460328b1aeb (patch)
treefa447c1d85892405369f18675ef3a4a5d7bab3b8 /src
parent4611125339be17e1227ad9b70f3a9f56b4bed338 (diff)
Prevent duplicate spawns for same spawn ID
If there is an alive instance of the creature upon creature spawn, skip spawn entirely. If there are only dead instances, despawn them. A new dead corpse in the creatures home position will be respawned. Closes: #16462
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp32
-rw-r--r--src/server/game/Entities/Creature/Creature.h2
2 files changed, 32 insertions, 2 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 7558929296d..73b9e0580cf 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -1292,8 +1292,38 @@ bool Creature::CreateFromProto(ObjectGuid::LowType guidlow, uint32 entry, Creatu
return true;
}
-bool Creature::LoadCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap)
+bool Creature::LoadCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap, bool allowDuplicate)
{
+ if (!allowDuplicate)
+ {
+ // If an alive instance of this spawnId is already found, skip creation
+ // If only dead instance(s) exist, despawn them and spawn a new (maybe also dead) version
+ const auto creatureBounds = map->GetCreatureBySpawnIdStore().equal_range(spawnId);
+ std::vector <Creature*> despawnList;
+
+ if (creatureBounds.first != creatureBounds.second)
+ {
+ for (auto itr = creatureBounds.first; itr != creatureBounds.second; ++itr)
+ {
+ if (itr->second->IsAlive())
+ {
+ TC_LOG_DEBUG("maps", "Would have spawned %u but %s already exists", spawnId, creatureBounds.first->second->GetGUID().ToString().c_str());
+ return false;
+ }
+ else
+ {
+ despawnList.push_back(itr->second);
+ TC_LOG_DEBUG("maps", "Despawned dead instance of spawn %u (%s)", spawnId, itr->second->GetGUID().ToString().c_str());
+ }
+ }
+
+ for (Creature* despawnCreature : despawnList)
+ {
+ despawnCreature->AddObjectToRemoveList();
+ }
+ }
+ }
+
CreatureData const* data = sObjectMgr->GetCreatureData(spawnId);
if (!data)
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index d0b25971358..a2d8dda7a7c 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -535,7 +535,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject
void setDeathState(DeathState s) override; // override virtual Unit::setDeathState
bool LoadFromDB(ObjectGuid::LowType spawnId, Map* map) { return LoadCreatureFromDB(spawnId, map, false); }
- bool LoadCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap = true);
+ bool LoadCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap = true, bool allowDuplicate = false);
void SaveToDB();
// overriden in Pet
virtual void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask);