diff options
-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); |