aboutsummaryrefslogtreecommitdiff
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
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
-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);