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 d75d0ab0fd4..9a6e118351a 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -1318,8 +1318,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 54e472a56d3..9103f864e3d 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -568,7 +568,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma 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, uint32 spawnMask, uint32 phaseMask); |