aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpete318 <pete318@users.noreply.github.com>2016-02-03 12:34:38 +0000
committerShauren <shauren.trinity@gmail.com>2016-04-02 17:51:03 +0200
commit2fe84d7471f8f5e521ca77825e63b9cff92ba1dc (patch)
tree625360ea6e70d6d5c394d6579155c070dfe31dba
parent0a8bab885ac7c1efd5f67619998502a3a8be4c62 (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 (cherry picked from commit fe2a0fda4464effeb2fb655da84a0460328b1aeb)
-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 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);