diff options
author | pete318 <pete318@users.noreply.github.com> | 2016-02-03 12:34:38 +0000 |
---|---|---|
committer | pete318 <pete318@hotmail.com> | 2016-02-03 19:27:36 +0100 |
commit | fe2a0fda4464effeb2fb655da84a0460328b1aeb (patch) | |
tree | fa447c1d85892405369f18675ef3a4a5d7bab3b8 /src | |
parent | 4611125339be17e1227ad9b70f3a9f56b4bed338 (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.cpp | 32 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/Creature.h | 2 |
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); |