aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/DataStores/DBCEnums.h19
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTrigger.cpp14
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h13
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp12
-rw-r--r--src/server/game/Entities/Creature/Creature.h2
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp5
-rw-r--r--src/server/game/Events/GameEventMgr.cpp12
-rw-r--r--src/server/game/Globals/AreaTriggerDataStore.cpp23
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp138
-rw-r--r--src/server/game/Globals/ObjectMgr.h38
-rw-r--r--src/server/game/Grids/ObjectGridLoader.cpp52
-rw-r--r--src/server/game/Maps/Map.cpp269
-rw-r--r--src/server/game/Maps/Map.h42
-rw-r--r--src/server/game/Maps/MapManager.h7
-rw-r--r--src/server/game/Maps/SpawnData.h50
-rw-r--r--src/server/game/Maps/enuminfo_SpawnData.cpp2
-rw-r--r--src/server/game/Pools/PoolMgr.cpp10
-rw-r--r--src/server/scripts/Commands/cs_go.cpp34
-rw-r--r--src/server/scripts/Commands/cs_list.cpp30
-rw-r--r--src/server/scripts/Commands/cs_npc.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp4
21 files changed, 436 insertions, 342 deletions
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index 705ad1a0444..627e716137a 100644
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -668,25 +668,6 @@ enum DifficultyFlags
DIFFICULTY_FLAG_DISPLAY_MYTHIC = 0x80 // Controls icon displayed on minimap when inside the instance
};
-enum SpawnMask
-{
- SPAWNMASK_CONTINENT = (1 << DIFFICULTY_NONE), // any maps without spawn modes
-
- SPAWNMASK_DUNGEON_NORMAL = (1 << DIFFICULTY_NORMAL),
- SPAWNMASK_DUNGEON_HEROIC = (1 << DIFFICULTY_HEROIC),
- SPAWNMASK_DUNGEON_ALL = (SPAWNMASK_DUNGEON_NORMAL | SPAWNMASK_DUNGEON_HEROIC),
-
- SPAWNMASK_RAID_10MAN_NORMAL = (1 << DIFFICULTY_10_N),
- SPAWNMASK_RAID_25MAN_NORMAL = (1 << DIFFICULTY_25_N),
- SPAWNMASK_RAID_NORMAL_ALL = (SPAWNMASK_RAID_10MAN_NORMAL | SPAWNMASK_RAID_25MAN_NORMAL),
-
- SPAWNMASK_RAID_10MAN_HEROIC = (1 << DIFFICULTY_10_HC),
- SPAWNMASK_RAID_25MAN_HEROIC = (1 << DIFFICULTY_25_HC),
- SPAWNMASK_RAID_HEROIC_ALL = (SPAWNMASK_RAID_10MAN_HEROIC | SPAWNMASK_RAID_25MAN_HEROIC),
-
- SPAWNMASK_RAID_ALL = (SPAWNMASK_RAID_NORMAL_ALL | SPAWNMASK_RAID_HEROIC_ALL)
-};
-
enum class ExpectedStatType : uint8
{
CreatureHealth = 0,
diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp
index c52f9cbbadf..6fe0243d662 100644
--- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp
+++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp
@@ -61,6 +61,9 @@ void AreaTrigger::AddToWorld()
if (!IsInWorld())
{
GetMap()->GetObjectsStore().Insert<AreaTrigger>(GetGUID(), this);
+ if (_spawnId)
+ GetMap()->GetAreaTriggerBySpawnIdStore().insert(std::make_pair(_spawnId, this));
+
WorldObject::AddToWorld();
}
}
@@ -81,6 +84,9 @@ void AreaTrigger::RemoveFromWorld()
_ai->OnRemove();
WorldObject::RemoveFromWorld();
+
+ if (_spawnId)
+ Trinity::Containers::MultimapErasePair(GetMap()->GetAreaTriggerBySpawnIdStore(), _spawnId, this);
GetMap()->GetObjectsStore().Remove<AreaTrigger>(GetGUID());
}
}
@@ -248,7 +254,7 @@ bool AreaTrigger::LoadFromDB(ObjectGuid::LowType spawnId, Map* map, bool /*addTo
bool AreaTrigger::CreateServer(Map* map, AreaTriggerTemplate const* areaTriggerTemplate, AreaTriggerSpawn const& position)
{
SetMap(map);
- Relocate(position.Location);
+ Relocate(position.spawnPoint);
if (!IsPositionValid())
{
TC_LOG_ERROR("entities.areatrigger", "AreaTriggerServer (id %u) not created. Invalid coordinates (X: %f Y: %f)",
@@ -267,8 +273,8 @@ bool AreaTrigger::CreateServer(Map* map, AreaTriggerTemplate const* areaTriggerT
_shape = position.Shape;
_maxSearchRadius = _shape.GetMaxSearchRadius();
- if (position.PhaseUseFlags || position.PhaseId || position.PhaseGroup)
- PhasingHandler::InitDbPhaseShift(GetPhaseShift(), position.PhaseUseFlags, position.PhaseId, position.PhaseGroup);
+ if (position.phaseUseFlags || position.phaseId || position.phaseGroup)
+ PhasingHandler::InitDbPhaseShift(GetPhaseShift(), position.phaseUseFlags, position.phaseId, position.phaseGroup);
UpdateShape();
@@ -520,7 +526,7 @@ AreaTriggerTemplate const* AreaTrigger::GetTemplate() const
uint32 AreaTrigger::GetScriptId() const
{
if (_spawnId)
- return ASSERT_NOTNULL(sAreaTriggerDataStore->GetAreaTriggerSpawn(_spawnId))->ScriptId;
+ return ASSERT_NOTNULL(sAreaTriggerDataStore->GetAreaTriggerSpawn(_spawnId))->scriptId;
if (GetCreateProperties())
return GetCreateProperties()->ScriptId;
diff --git a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h
index 8630075ac42..0eb87f833d1 100644
--- a/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h
+++ b/src/server/game/Entities/AreaTrigger/AreaTriggerTemplate.h
@@ -21,7 +21,7 @@
#include "Define.h"
#include "ObjectGuid.h"
#include "Optional.h"
-#include "Position.h"
+#include "SpawnData.h"
#include <vector>
#define MAX_AREATRIGGER_ENTITY_DATA 6
@@ -234,18 +234,13 @@ public:
uint32 ScriptId;
};
-struct AreaTriggerSpawn
+struct AreaTriggerSpawn : SpawnData
{
- ObjectGuid::LowType SpawnId = 0;
+ AreaTriggerSpawn() : SpawnData(SPAWN_TYPE_AREATRIGGER) { }
+
AreaTriggerId Id;
- WorldLocation Location;
- uint32 PhaseId = 0;
- uint32 PhaseGroup = 0;
- uint8 PhaseUseFlags = 0;
AreaTriggerShapeInfo Shape;
-
- uint32 ScriptId = 0;
};
#endif
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index bc2963bb477..c2faf7070ae 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -1411,9 +1411,15 @@ void Creature::SaveToDB(uint32 mapid, std::vector<Difficulty> const& spawnDiffic
data.displayid = displayId;
data.equipmentId = GetCurrentEquipmentId();
if (!GetTransport())
- data.spawnPoint.WorldRelocate(this);
+ {
+ data.mapId = GetMapId();
+ data.spawnPoint.Relocate(this);
+ }
else
- data.spawnPoint.WorldRelocate(mapid, GetTransOffsetX(), GetTransOffsetY(), GetTransOffsetZ(), GetTransOffsetO());
+ {
+ data.mapId = mapid;
+ data.spawnPoint.Relocate(GetTransOffsetX(), GetTransOffsetY(), GetTransOffsetZ(), GetTransOffsetO());
+ }
data.spawntimesecs = m_respawnDelay;
// prevent add data integrity problems
data.spawndist = GetDefaultMovementType() == IDLE_MOTION_TYPE ? 0.0f : m_respawnradius;
@@ -1879,7 +1885,7 @@ bool Creature::hasInvolvedQuest(uint32 quest_id) const
CharacterDatabaseTransaction charTrans = CharacterDatabase.BeginTransaction();
- sMapMgr->DoForAllMapsWithMapId(data->spawnPoint.GetMapId(),
+ sMapMgr->DoForAllMapsWithMapId(data->mapId,
[spawnId, charTrans](Map* map) -> void
{
// despawn all active creatures, and remove their respawns
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index a3fc0223bb4..544f4464fd2 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -96,7 +96,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
void Update(uint32 time) override; // overwrited Unit::Update
void GetRespawnPosition(float &x, float &y, float &z, float* ori = nullptr, float* dist = nullptr) const;
- bool IsSpawnedOnTransport() const { return m_creatureData && m_creatureData->spawnPoint.GetMapId() != GetMapId(); }
+ bool IsSpawnedOnTransport() const { return m_creatureData && m_creatureData->mapId != GetMapId(); }
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
uint32 GetCorpseDelay() const { return m_corpseDelay; }
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 131f1eb1783..2481de2880f 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -1128,7 +1128,8 @@ void GameObject::SaveToDB(uint32 mapid, std::vector<Difficulty> const& spawnDiff
data.spawnId = m_spawnId;
ASSERT(data.spawnId == m_spawnId);
data.id = GetEntry();
- data.spawnPoint.WorldRelocate(this);
+ data.mapId = GetMapId();
+ data.spawnPoint.Relocate(this);
data.rotation = m_localRotation;
data.spawntimesecs = m_spawnedByDefault ? m_respawnDelayTime : -(int32)m_respawnDelayTime;
data.animprogress = GetGoAnimProgress();
@@ -1262,7 +1263,7 @@ bool GameObject::LoadFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap
CharacterDatabaseTransaction charTrans = CharacterDatabase.BeginTransaction();
- sMapMgr->DoForAllMapsWithMapId(data->spawnPoint.GetMapId(),
+ sMapMgr->DoForAllMapsWithMapId(data->mapId,
[spawnId, charTrans](Map* map) -> void
{
// despawn all active objects, and remove their respawns
diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp
index 4a09390301e..7e22c76f2f5 100644
--- a/src/server/game/Events/GameEventMgr.cpp
+++ b/src/server/game/Events/GameEventMgr.cpp
@@ -1167,7 +1167,7 @@ void GameEventMgr::UpdateEventNPCFlags(uint16 event_id)
for (NPCFlagList::iterator itr = mGameEventNPCFlags[event_id].begin(); itr != mGameEventNPCFlags[event_id].end(); ++itr)
// get the creature data from the low guid to get the entry, to be able to find out the whole guid
if (CreatureData const* data = sObjectMgr->GetCreatureData(itr->first))
- creaturesByMap[data->spawnPoint.GetMapId()].insert(itr->first);
+ creaturesByMap[data->mapId].insert(itr->first);
for (auto const& p : creaturesByMap)
{
@@ -1234,7 +1234,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
sObjectMgr->AddCreatureToGrid(*itr, data);
// Spawn if necessary (loaded grids only)
- Map* map = sMapMgr->CreateBaseMap(data->spawnPoint.GetMapId());
+ Map* map = sMapMgr->CreateBaseMap(data->mapId);
map->RemoveRespawnTime(SPAWN_TYPE_CREATURE, *itr);
// We use spawn coords to spawn
if (map && !map->Instanceable() && map->IsGridLoaded(data->spawnPoint))
@@ -1257,7 +1257,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id)
sObjectMgr->AddGameobjectToGrid(*itr, data);
// Spawn if necessary (loaded grids only)
// this base map checked as non-instanced and then only existed
- Map* map = sMapMgr->CreateBaseMap(data->spawnPoint.GetMapId());
+ Map* map = sMapMgr->CreateBaseMap(data->mapId);
map->RemoveRespawnTime(SPAWN_TYPE_GAMEOBJECT, *itr);
// We use current coords to unspawn, not spawn coords since creature can have changed grid
if (map && !map->Instanceable() && map->IsGridLoaded(data->spawnPoint))
@@ -1307,7 +1307,7 @@ void GameEventMgr::GameEventUnspawn(int16 event_id)
{
sObjectMgr->RemoveCreatureFromGrid(*itr, data);
- sMapMgr->DoForAllMapsWithMapId(data->spawnPoint.GetMapId(), [&itr](Map* map)
+ sMapMgr->DoForAllMapsWithMapId(data->mapId, [&itr](Map* map)
{
map->RemoveRespawnTime(SPAWN_TYPE_CREATURE, *itr);
auto creatureBounds = map->GetCreatureBySpawnIdStore().equal_range(*itr);
@@ -1338,7 +1338,7 @@ void GameEventMgr::GameEventUnspawn(int16 event_id)
{
sObjectMgr->RemoveGameobjectFromGrid(*itr, data);
- sMapMgr->DoForAllMapsWithMapId(data->spawnPoint.GetMapId(), [&itr](Map* map)
+ sMapMgr->DoForAllMapsWithMapId(data->mapId, [&itr](Map* map)
{
map->RemoveRespawnTime(SPAWN_TYPE_GAMEOBJECT, *itr);
auto gameobjectBounds = map->GetGameObjectBySpawnIdStore().equal_range(*itr);
@@ -1374,7 +1374,7 @@ void GameEventMgr::ChangeEquipOrModel(int16 event_id, bool activate)
continue;
// Update if spawned
- sMapMgr->DoForAllMapsWithMapId(data->spawnPoint.GetMapId(), [&itr, activate](Map* map)
+ sMapMgr->DoForAllMapsWithMapId(data->mapId, [&itr, activate](Map* map)
{
auto creatureBounds = map->GetCreatureBySpawnIdStore().equal_range(itr->first);
for (auto itr2 = creatureBounds.first; itr2 != creatureBounds.second; ++itr2)
diff --git a/src/server/game/Globals/AreaTriggerDataStore.cpp b/src/server/game/Globals/AreaTriggerDataStore.cpp
index 817f59d1284..5cfee1028b9 100644
--- a/src/server/game/Globals/AreaTriggerDataStore.cpp
+++ b/src/server/game/Globals/AreaTriggerDataStore.cpp
@@ -340,27 +340,26 @@ void AreaTriggerDataStore::LoadAreaTriggerSpawns()
continue;
}
- AreaTriggerSpawn spawn;
- spawn.SpawnId = spawnId;
+ AreaTriggerSpawn& spawn = _areaTriggerSpawnsBySpawnId[spawnId];
+ spawn.spawnId = spawnId;
+ spawn.mapId = location.GetMapId();
spawn.Id = areaTriggerid;
- spawn.Location.WorldRelocate(location);
+ spawn.spawnPoint.Relocate(location);
- spawn.PhaseUseFlags = fields[8].GetUInt8();
- spawn.PhaseId = fields[9].GetUInt32();
- spawn.PhaseGroup = fields[10].GetUInt32();
+ spawn.phaseUseFlags = fields[8].GetUInt8();
+ spawn.phaseId = fields[9].GetUInt32();
+ spawn.phaseGroup = fields[10].GetUInt32();
spawn.Shape.Type = static_cast<AreaTriggerTypes>(shape);
for (uint8 i = 0; i < MAX_AREATRIGGER_ENTITY_DATA; ++i)
spawn.Shape.DefaultDatas.Data[i] = fields[12 + i].GetFloat();
- spawn.ScriptId = sObjectMgr->GetScriptId(fields[18].GetString());
+ spawn.scriptId = sObjectMgr->GetScriptId(fields[18].GetString());
+ spawn.spawnGroupData = sObjectMgr->GetLegacySpawnGroup();
// Add the trigger to a map::cell map, which is later used by GridLoader to query
- CellCoord cellCoord = Trinity::ComputeCellCoord(spawn.Location.GetPositionX(), spawn.Location.GetPositionY());
- _areaTriggerSpawnsByLocation[{ spawn.Location.GetMapId(), cellCoord.GetId() }].insert(spawnId);
-
- // add the position to the map
- _areaTriggerSpawnsBySpawnId[spawnId] = spawn;
+ CellCoord cellCoord = Trinity::ComputeCellCoord(spawn.spawnPoint.GetPositionX(), spawn.spawnPoint.GetPositionY());
+ _areaTriggerSpawnsByLocation[{ spawn.mapId, cellCoord.GetId() }].insert(spawnId);
} while (templates->NextRow());
}
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 032573ed81a..f9e20a9a420 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -1757,8 +1757,8 @@ void ObjectMgr::LoadLinkedRespawn()
break;
}
- MapEntry const* const map = sMapStore.LookupEntry(master->spawnPoint.GetMapId());
- if (!map || !map->Instanceable() || (master->spawnPoint.GetMapId() != slave->spawnPoint.GetMapId()))
+ MapEntry const* const map = sMapStore.LookupEntry(master->mapId);
+ if (!map || !map->Instanceable() || (master->mapId != slave->mapId))
{
TC_LOG_ERROR("sql.sql", "LinkedRespawn: Creature '" UI64FMTD "' linking to Creature '" UI64FMTD "' on an unpermitted map.", guidLow, linkedGuidLow);
error = true;
@@ -1773,8 +1773,8 @@ void ObjectMgr::LoadLinkedRespawn()
break;
}
- guid = ObjectGuid::Create<HighGuid::Creature>(slave->spawnPoint.GetMapId(), slave->id, guidLow);
- linkedGuid = ObjectGuid::Create<HighGuid::Creature>(master->spawnPoint.GetMapId(), master->id, linkedGuidLow);
+ guid = ObjectGuid::Create<HighGuid::Creature>(slave->mapId, slave->id, guidLow);
+ linkedGuid = ObjectGuid::Create<HighGuid::Creature>(master->mapId, master->id, linkedGuidLow);
break;
}
case LINKED_RESPAWN_CREATURE_TO_GO:
@@ -1795,8 +1795,8 @@ void ObjectMgr::LoadLinkedRespawn()
break;
}
- MapEntry const* const map = sMapStore.LookupEntry(master->spawnPoint.GetMapId());
- if (!map || !map->Instanceable() || (master->spawnPoint.GetMapId() != slave->spawnPoint.GetMapId()))
+ MapEntry const* const map = sMapStore.LookupEntry(master->mapId);
+ if (!map || !map->Instanceable() || (master->mapId != slave->mapId))
{
TC_LOG_ERROR("sql.sql", "LinkedRespawn: Creature '" UI64FMTD "' linking to Gameobject '" UI64FMTD "' on an unpermitted map.", guidLow, linkedGuidLow);
error = true;
@@ -1811,8 +1811,8 @@ void ObjectMgr::LoadLinkedRespawn()
break;
}
- guid = ObjectGuid::Create<HighGuid::Creature>(slave->spawnPoint.GetMapId(), slave->id, guidLow);
- linkedGuid = ObjectGuid::Create<HighGuid::GameObject>(master->spawnPoint.GetMapId(), master->id, linkedGuidLow);
+ guid = ObjectGuid::Create<HighGuid::Creature>(slave->mapId, slave->id, guidLow);
+ linkedGuid = ObjectGuid::Create<HighGuid::GameObject>(master->mapId, master->id, linkedGuidLow);
break;
}
case LINKED_RESPAWN_GO_TO_GO:
@@ -1833,8 +1833,8 @@ void ObjectMgr::LoadLinkedRespawn()
break;
}
- MapEntry const* const map = sMapStore.LookupEntry(master->spawnPoint.GetMapId());
- if (!map || !map->Instanceable() || (master->spawnPoint.GetMapId() != slave->spawnPoint.GetMapId()))
+ MapEntry const* const map = sMapStore.LookupEntry(master->mapId);
+ if (!map || !map->Instanceable() || (master->mapId != slave->mapId))
{
TC_LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject '" UI64FMTD "' linking to Gameobject '" UI64FMTD "' on an unpermitted map.", guidLow, linkedGuidLow);
error = true;
@@ -1849,8 +1849,8 @@ void ObjectMgr::LoadLinkedRespawn()
break;
}
- guid = ObjectGuid::Create<HighGuid::GameObject>(slave->spawnPoint.GetMapId(), slave->id, guidLow);
- linkedGuid = ObjectGuid::Create<HighGuid::GameObject>(master->spawnPoint.GetMapId(), master->id, linkedGuidLow);
+ guid = ObjectGuid::Create<HighGuid::GameObject>(slave->mapId, slave->id, guidLow);
+ linkedGuid = ObjectGuid::Create<HighGuid::GameObject>(master->mapId, master->id, linkedGuidLow);
break;
}
case LINKED_RESPAWN_GO_TO_CREATURE:
@@ -1871,8 +1871,8 @@ void ObjectMgr::LoadLinkedRespawn()
break;
}
- MapEntry const* const map = sMapStore.LookupEntry(master->spawnPoint.GetMapId());
- if (!map || !map->Instanceable() || (master->spawnPoint.GetMapId() != slave->spawnPoint.GetMapId()))
+ MapEntry const* const map = sMapStore.LookupEntry(master->mapId);
+ if (!map || !map->Instanceable() || (master->mapId != slave->mapId))
{
TC_LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject '" UI64FMTD "' linking to Creature '" UI64FMTD "' on an unpermitted map.", guidLow, linkedGuidLow);
error = true;
@@ -1887,8 +1887,8 @@ void ObjectMgr::LoadLinkedRespawn()
break;
}
- guid = ObjectGuid::Create<HighGuid::GameObject>(slave->spawnPoint.GetMapId(), slave->id, guidLow);
- linkedGuid = ObjectGuid::Create<HighGuid::Creature>(master->spawnPoint.GetMapId(), master->id, linkedGuidLow);
+ guid = ObjectGuid::Create<HighGuid::GameObject>(slave->mapId, slave->id, guidLow);
+ linkedGuid = ObjectGuid::Create<HighGuid::Creature>(master->mapId, master->id, linkedGuidLow);
break;
}
}
@@ -1908,7 +1908,7 @@ bool ObjectMgr::SetCreatureLinkedRespawn(ObjectGuid::LowType guidLow, ObjectGuid
CreatureData const* master = GetCreatureData(guidLow);
ASSERT(master);
- ObjectGuid guid = ObjectGuid::Create<HighGuid::Creature>(master->spawnPoint.GetMapId(), master->id, guidLow);
+ ObjectGuid guid = ObjectGuid::Create<HighGuid::Creature>(master->mapId, master->id, guidLow);
if (!linkedGuidLow) // we're removing the linking
{
@@ -1927,8 +1927,8 @@ bool ObjectMgr::SetCreatureLinkedRespawn(ObjectGuid::LowType guidLow, ObjectGuid
return false;
}
- MapEntry const* map = sMapStore.LookupEntry(master->spawnPoint.GetMapId());
- if (!map || !map->Instanceable() || (master->spawnPoint.GetMapId() != slave->spawnPoint.GetMapId()))
+ MapEntry const* map = sMapStore.LookupEntry(master->mapId);
+ if (!map || !map->Instanceable() || (master->mapId != slave->mapId))
{
TC_LOG_ERROR("sql.sql", "Creature '" UI64FMTD "' linking to '" UI64FMTD "' on an unpermitted map.", guidLow, linkedGuidLow);
return false;
@@ -1941,7 +1941,7 @@ bool ObjectMgr::SetCreatureLinkedRespawn(ObjectGuid::LowType guidLow, ObjectGuid
return false;
}
- ObjectGuid linkedGuid = ObjectGuid::Create<HighGuid::Creature>(slave->spawnPoint.GetMapId(), slave->id, linkedGuidLow);
+ ObjectGuid linkedGuid = ObjectGuid::Create<HighGuid::Creature>(slave->mapId, slave->id, linkedGuidLow);
_linkedRespawnStore[guid] = linkedGuid;
WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_REP_LINKED_RESPAWN);
@@ -2117,7 +2117,8 @@ void ObjectMgr::LoadCreatures()
CreatureData& data = _creatureDataStore[guid];
data.spawnId = guid;
data.id = entry;
- data.spawnPoint.WorldRelocate(fields[2].GetUInt16(), fields[3].GetFloat(), fields[4].GetFloat(), fields[5].GetFloat(), fields[6].GetFloat());
+ data.mapId = fields[2].GetUInt16();
+ data.spawnPoint.Relocate(fields[3].GetFloat(), fields[4].GetFloat(), fields[5].GetFloat(), fields[6].GetFloat());
data.displayid = fields[7].GetUInt32();
data.equipmentId = fields[8].GetInt8();
data.spawntimesecs = fields[9].GetUInt32();
@@ -2126,7 +2127,7 @@ void ObjectMgr::LoadCreatures()
data.curhealth = fields[12].GetUInt32();
data.curmana = fields[13].GetUInt32();
data.movementType = fields[14].GetUInt8();
- data.spawnDifficulties = ParseSpawnDifficulties(fields[15].GetString(), "creature", guid, data.spawnPoint.GetMapId(), spawnMasks[data.spawnPoint.GetMapId()]);
+ data.spawnDifficulties = ParseSpawnDifficulties(fields[15].GetString(), "creature", guid, data.mapId, spawnMasks[data.mapId]);
int16 gameEvent = fields[16].GetInt8();
uint32 PoolId = fields[17].GetUInt32();
data.npcflag = fields[18].GetUInt64();
@@ -2139,12 +2140,12 @@ void ObjectMgr::LoadCreatures()
data.phaseGroup = fields[25].GetUInt32();
data.terrainSwapMap = fields[26].GetInt32();
data.scriptId = GetScriptId(fields[27].GetString());
- data.spawnGroupData = &_spawnGroupDataStore[IsTransportMap(data.spawnPoint.GetMapId()) ? 1 : 0]; // transport spawns default to compatibility group
+ data.spawnGroupData = IsTransportMap(data.mapId) ? GetLegacySpawnGroup() : GetDefaultSpawnGroup(); // transport spawns default to compatibility group
- MapEntry const* mapEntry = sMapStore.LookupEntry(data.spawnPoint.GetMapId());
+ MapEntry const* mapEntry = sMapStore.LookupEntry(data.mapId);
if (!mapEntry)
{
- TC_LOG_ERROR("sql.sql", "Table `creature` has creature (GUID: " UI64FMTD ") that spawned at nonexistent map (Id: %u), skipped.", guid, data.spawnPoint.GetMapId());
+ TC_LOG_ERROR("sql.sql", "Table `creature` has creature (GUID: " UI64FMTD ") that spawned at nonexistent map (Id: %u), skipped.", guid, data.mapId);
continue;
}
@@ -2152,16 +2153,16 @@ void ObjectMgr::LoadCreatures()
{
if (VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager())
{
- if (vmgr->isMapLoadingEnabled() && !IsTransportMap(data.spawnPoint.GetMapId()))
+ if (vmgr->isMapLoadingEnabled() && !IsTransportMap(data.mapId))
{
GridCoord gridCoord = Trinity::ComputeGridCoord(data.spawnPoint.GetPositionX(), data.spawnPoint.GetPositionY());
int gx = (MAX_NUMBER_OF_GRIDS - 1) - gridCoord.x_coord;
int gy = (MAX_NUMBER_OF_GRIDS - 1) - gridCoord.y_coord;
- VMAP::LoadResult result = vmgr->existsMap((sWorld->GetDataPath() + "vmaps").c_str(), data.spawnPoint.GetMapId(), gx, gy);
+ VMAP::LoadResult result = vmgr->existsMap((sWorld->GetDataPath() + "vmaps").c_str(), data.mapId, gx, gy);
if (result != VMAP::LoadResult::Success)
TC_LOG_ERROR("sql.sql", "Table `creature` has creature (GUID: " UI64FMTD " Entry: %u MapID: %u) spawned on a possible invalid position (%s)",
- guid, data.id, data.spawnPoint.GetMapId(), data.spawnPoint.ToString().c_str());
+ guid, data.id, data.mapId, data.spawnPoint.ToString().c_str());
}
}
}
@@ -2274,7 +2275,7 @@ void ObjectMgr::LoadCreatures()
TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: " UI64FMTD " Entry: %u) with `terrainSwapMap` %u does not exist, set to -1", guid, data.id, data.terrainSwapMap);
data.terrainSwapMap = -1;
}
- else if (terrainSwapEntry->ParentMapID != int16(data.spawnPoint.GetMapId()))
+ else if (terrainSwapEntry->ParentMapID != int16(data.mapId))
{
TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: " UI64FMTD " Entry: %u) with `terrainSwapMap` %u which cannot be used on spawn map, set to -1", guid, data.id, data.terrainSwapMap);
data.terrainSwapMap = -1;
@@ -2286,7 +2287,7 @@ void ObjectMgr::LoadCreatures()
uint32 zoneId = 0;
uint32 areaId = 0;
PhasingHandler::InitDbVisibleMapId(phaseShift, data.terrainSwapMap);
- sMapMgr->GetZoneAndAreaId(phaseShift, zoneId, areaId, data.spawnPoint);
+ sMapMgr->GetZoneAndAreaId(phaseShift, zoneId, areaId, data.mapId, data.spawnPoint);
WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_ZONE_AREA_DATA);
@@ -2311,7 +2312,7 @@ void ObjectMgr::AddCreatureToGrid(ObjectGuid::LowType guid, CreatureData const*
for (Difficulty difficulty : data->spawnDifficulties)
{
CellCoord cellCoord = Trinity::ComputeCellCoord(data->spawnPoint.GetPositionX(), data->spawnPoint.GetPositionY());
- CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->spawnPoint.GetMapId(), difficulty)][cellCoord.GetId()];
+ CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapId, difficulty)][cellCoord.GetId()];
cell_guids.creatures.insert(guid);
}
}
@@ -2321,7 +2322,7 @@ void ObjectMgr::RemoveCreatureFromGrid(ObjectGuid::LowType guid, CreatureData co
for (Difficulty difficulty : data->spawnDifficulties)
{
CellCoord cellCoord = Trinity::ComputeCellCoord(data->spawnPoint.GetPositionX(), data->spawnPoint.GetPositionY());
- CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->spawnPoint.GetMapId(), difficulty)][cellCoord.GetId()];
+ CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapId, difficulty)][cellCoord.GetId()];
cell_guids.creatures.erase(guid);
}
}
@@ -2340,7 +2341,8 @@ ObjectGuid::LowType ObjectMgr::AddGameObjectData(uint32 entry, uint32 mapId, Pos
GameObjectData& data = NewOrExistGameObjectData(spawnId);
data.spawnId = spawnId;
data.id = entry;
- data.spawnPoint.WorldRelocate(mapId,pos);
+ data.mapId = mapId;
+ data.spawnPoint.Relocate(pos);
data.rotation = rot;
data.spawntimesecs = spawntimedelay;
data.animprogress = 100;
@@ -2388,7 +2390,8 @@ ObjectGuid::LowType ObjectMgr::AddCreatureData(uint32 entry, uint32 mapId, Posit
CreatureData& data = NewOrExistCreatureData(spawnId);
data.spawnId = spawnId;
data.id = entry;
- data.spawnPoint.WorldRelocate(mapId, pos);
+ data.mapId = mapId;
+ data.spawnPoint.Relocate(pos);
data.displayid = 0;
data.equipmentId = 0;
data.spawntimesecs = spawntimedelay;
@@ -2486,18 +2489,19 @@ void ObjectMgr::LoadGameObjects()
data.spawnId = guid;
data.id = entry;
- data.spawnPoint.WorldRelocate(fields[2].GetUInt16(), fields[3].GetFloat(), fields[4].GetFloat(), fields[5].GetFloat(), fields[6].GetFloat());
+ data.mapId = fields[2].GetUInt16();
+ data.spawnPoint.Relocate(fields[3].GetFloat(), fields[4].GetFloat(), fields[5].GetFloat(), fields[6].GetFloat());
data.rotation.x = fields[7].GetFloat();
data.rotation.y = fields[8].GetFloat();
data.rotation.z = fields[9].GetFloat();
data.rotation.w = fields[10].GetFloat();
data.spawntimesecs = fields[11].GetInt32();
- data.spawnGroupData = &_spawnGroupDataStore[IsTransportMap(data.spawnPoint.GetMapId()) ? 1 : 0]; // transport spawns default to compatibility group
+ data.spawnGroupData = IsTransportMap(data.mapId) ? GetLegacySpawnGroup() : GetDefaultSpawnGroup(); // transport spawns default to compatibility group
- MapEntry const* mapEntry = sMapStore.LookupEntry(data.spawnPoint.GetMapId());
+ MapEntry const* mapEntry = sMapStore.LookupEntry(data.mapId);
if (!mapEntry)
{
- TC_LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: " UI64FMTD " Entry: %u) spawned on a non-existed map (Id: %u), skip", guid, data.id, data.spawnPoint.GetMapId());
+ TC_LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: " UI64FMTD " Entry: %u) spawned on a non-existed map (Id: %u), skip", guid, data.id, data.mapId);
continue;
}
@@ -2505,16 +2509,16 @@ void ObjectMgr::LoadGameObjects()
{
if (VMAP::IVMapManager* vmgr = VMAP::VMapFactory::createOrGetVMapManager())
{
- if (vmgr->isMapLoadingEnabled() && !IsTransportMap(data.spawnPoint.GetMapId()))
+ if (vmgr->isMapLoadingEnabled() && !IsTransportMap(data.mapId))
{
GridCoord gridCoord = Trinity::ComputeGridCoord(data.spawnPoint.GetPositionX(), data.spawnPoint.GetPositionY());
int gx = (MAX_NUMBER_OF_GRIDS - 1) - gridCoord.x_coord;
int gy = (MAX_NUMBER_OF_GRIDS - 1) - gridCoord.y_coord;
- VMAP::LoadResult result = vmgr->existsMap((sWorld->GetDataPath() + "vmaps").c_str(), data.spawnPoint.GetMapId(), gx, gy);
+ VMAP::LoadResult result = vmgr->existsMap((sWorld->GetDataPath() + "vmaps").c_str(), data.mapId, gx, gy);
if (result != VMAP::LoadResult::Success)
TC_LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: " UI64FMTD " Entry: %u MapID: %u) spawned on a possible invalid position (%s)",
- guid, data.id, data.spawnPoint.GetMapId(), data.spawnPoint.ToString().c_str());
+ guid, data.id, data.mapId, data.spawnPoint.ToString().c_str());
}
}
}
@@ -2538,7 +2542,7 @@ void ObjectMgr::LoadGameObjects()
}
data.goState = GOState(go_state);
- data.spawnDifficulties = ParseSpawnDifficulties(fields[14].GetString(), "gameobject", guid, data.spawnPoint.GetMapId(), spawnMasks[data.spawnPoint.GetMapId()]);
+ data.spawnDifficulties = ParseSpawnDifficulties(fields[14].GetString(), "gameobject", guid, data.mapId, spawnMasks[data.mapId]);
if (data.spawnDifficulties.empty())
{
TC_LOG_ERROR("sql.sql", "Table `creature` has creature (GUID: " UI64FMTD ") that is not spawned in any difficulty, skipped.", guid);
@@ -2597,7 +2601,7 @@ void ObjectMgr::LoadGameObjects()
TC_LOG_ERROR("sql.sql", "Table `gameobject` have gameobject (GUID: " UI64FMTD " Entry: %u) with `terrainSwapMap` %u does not exist, set to -1", guid, data.id, data.terrainSwapMap);
data.terrainSwapMap = -1;
}
- else if (terrainSwapEntry->ParentMapID != int16(data.spawnPoint.GetMapId()))
+ else if (terrainSwapEntry->ParentMapID != int16(data.mapId))
{
TC_LOG_ERROR("sql.sql", "Table `gameobject` have gameobject (GUID: " UI64FMTD " Entry: %u) with `terrainSwapMap` %u which cannot be used on spawn map, set to -1", guid, data.id, data.terrainSwapMap);
data.terrainSwapMap = -1;
@@ -2630,7 +2634,7 @@ void ObjectMgr::LoadGameObjects()
continue;
}
- if (!MapManager::IsValidMapCoord(data.spawnPoint))
+ if (!MapManager::IsValidMapCoord(data.mapId, data.spawnPoint))
{
TC_LOG_ERROR("sql.sql", "Table `gameobject` has gameobject (GUID: " UI64FMTD " Entry: %u) with invalid coordinates, skip", guid, data.id);
continue;
@@ -2647,7 +2651,7 @@ void ObjectMgr::LoadGameObjects()
uint32 zoneId = 0;
uint32 areaId = 0;
PhasingHandler::InitDbVisibleMapId(phaseShift, data.terrainSwapMap);
- sMapMgr->GetZoneAndAreaId(phaseShift, zoneId, areaId, data.spawnPoint);
+ sMapMgr->GetZoneAndAreaId(phaseShift, zoneId, areaId, data.mapId, data.spawnPoint);
WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_GAMEOBJECT_ZONE_AREA_DATA);
@@ -2743,19 +2747,15 @@ void ObjectMgr::LoadSpawnGroups()
{
Field* fields = result->Fetch();
uint32 groupId = fields[0].GetUInt32();
- SpawnObjectType spawnType;
+ SpawnObjectType spawnType = SpawnObjectType(fields[1].GetUInt8());
+ if (!SpawnData::TypeIsValid(spawnType))
{
- uint32 type = fields[1].GetUInt8();
- if (type >= SPAWN_TYPE_MAX)
- {
- TC_LOG_ERROR("sql.sql", "Spawn data with invalid type %u listed for spawn group %u. Skipped.", type, groupId);
- continue;
- }
- spawnType = SpawnObjectType(type);
+ TC_LOG_ERROR("sql.sql", "Spawn data with invalid type %u listed for spawn group %u. Skipped.", uint32(spawnType), groupId);
+ continue;
}
ObjectGuid::LowType spawnId = fields[2].GetUInt64();
- SpawnData const* data = GetSpawnData(spawnType, spawnId);
+ SpawnMetadata const* data = GetSpawnMetadata(spawnType, spawnId);
if (!data)
{
TC_LOG_ERROR("sql.sql", "Spawn data with ID (%u," UI64FMTD ") not found, but is listed as a member of spawn group %u!", uint32(spawnType), spawnId, groupId);
@@ -2776,13 +2776,13 @@ void ObjectMgr::LoadSpawnGroups()
{
SpawnGroupTemplateData& groupTemplate = it->second;
if (groupTemplate.mapId == SPAWNGROUP_MAP_UNSET)
- groupTemplate.mapId = data->spawnPoint.GetMapId();
- else if (groupTemplate.mapId != data->spawnPoint.GetMapId() && !(groupTemplate.flags & SPAWNGROUP_FLAG_SYSTEM))
+ groupTemplate.mapId = data->mapId;
+ else if (groupTemplate.mapId != data->mapId && !(groupTemplate.flags & SPAWNGROUP_FLAG_SYSTEM))
{
- TC_LOG_ERROR("sql.sql", "Spawn group %u has map ID %u, but spawn (%u," UI64FMTD ") has map id %u - spawn NOT added to group!", groupId, groupTemplate.mapId, uint32(spawnType), spawnId, data->spawnPoint.GetMapId());
+ TC_LOG_ERROR("sql.sql", "Spawn group %u has map ID %u, but spawn (%u," UI64FMTD ") has map id %u - spawn NOT added to group!", groupId, groupTemplate.mapId, uint32(spawnType), spawnId, data->mapId);
continue;
}
- const_cast<SpawnData*>(data)->spawnGroupData = &groupTemplate;
+ const_cast<SpawnMetadata*>(data)->spawnGroupData = &groupTemplate;
if (!(groupTemplate.flags & SPAWNGROUP_FLAG_SYSTEM))
_spawnGroupMapStore.emplace(groupId, data);
++numMembers;
@@ -2849,6 +2849,24 @@ void ObjectMgr::LoadInstanceSpawnGroups()
TC_LOG_INFO("server.loading", ">> Loaded %u instance spawn groups in %u ms", n, GetMSTimeDiffToNow(oldMSTime));
}
+SpawnData const* ObjectMgr::GetSpawnData(SpawnObjectType type, ObjectGuid::LowType spawnId) const
+{
+ if (!SpawnData::TypeHasData(type))
+ return nullptr;
+ switch (type)
+ {
+ case SPAWN_TYPE_CREATURE:
+ return GetCreatureData(spawnId);
+ case SPAWN_TYPE_GAMEOBJECT:
+ return GetGameObjectData(spawnId);
+ case SPAWN_TYPE_AREATRIGGER:
+ return sAreaTriggerDataStore->GetAreaTriggerSpawn(spawnId);
+ default:
+ ASSERT(false, "Invalid spawn object type %u", uint32(type));
+ return nullptr;
+ }
+}
+
void ObjectMgr::OnDeleteSpawnData(SpawnData const* data)
{
auto templateIt = _spawnGroupDataStore.find(data->spawnGroupData->groupId);
@@ -2872,7 +2890,7 @@ void ObjectMgr::AddGameobjectToGrid(ObjectGuid::LowType guid, GameObjectData con
for (Difficulty difficulty : data->spawnDifficulties)
{
CellCoord cellCoord = Trinity::ComputeCellCoord(data->spawnPoint.GetPositionX(), data->spawnPoint.GetPositionY());
- CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->spawnPoint.GetMapId(), difficulty)][cellCoord.GetId()];
+ CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapId, difficulty)][cellCoord.GetId()];
cell_guids.gameobjects.insert(guid);
}
}
@@ -2882,7 +2900,7 @@ void ObjectMgr::RemoveGameobjectFromGrid(ObjectGuid::LowType guid, GameObjectDat
for (Difficulty difficulty : data->spawnDifficulties)
{
CellCoord cellCoord = Trinity::ComputeCellCoord(data->spawnPoint.GetPositionX(), data->spawnPoint.GetPositionY());
- CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->spawnPoint.GetMapId(), difficulty)][cellCoord.GetId()];
+ CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(data->mapId, difficulty)][cellCoord.GetId()];
cell_guids.gameobjects.erase(guid);
}
}
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index db973b2fd56..0002cea5292 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -510,7 +510,7 @@ typedef std::unordered_map<ObjectGuid::LowType, GameObjectData> GameObjectDataCo
typedef std::unordered_map<ObjectGuid::LowType, GameObjectAddon> GameObjectAddonContainer;
typedef std::unordered_map<uint32, std::vector<uint32>> GameObjectQuestItemMap;
typedef std::unordered_map<uint32, SpawnGroupTemplateData> SpawnGroupDataContainer;
-typedef std::multimap<uint32, SpawnData const*> SpawnGroupLinkContainer;
+typedef std::multimap<uint32, SpawnMetadata const*> SpawnGroupLinkContainer;
typedef std::unordered_map<uint16, std::vector<InstanceSpawnGroupInfo>> InstanceSpawnGroupContainer;
typedef std::map<TempSummonGroupKey, std::vector<TempSummonData>> TempSummonDataContainer;
typedef std::unordered_map<uint32, CreatureLocale> CreatureLocaleContainer;
@@ -1430,9 +1430,10 @@ class TC_GAME_API ObjectMgr
ObjectGuid::LowType GenerateGameObjectSpawnId();
SpawnGroupTemplateData const* GetSpawnGroupData(uint32 groupId) const { auto it = _spawnGroupDataStore.find(groupId); return it != _spawnGroupDataStore.end() ? &it->second : nullptr; }
+ SpawnGroupTemplateData const* GetSpawnGroupData(SpawnObjectType type, ObjectGuid::LowType spawnId) const { SpawnMetadata const* data = GetSpawnMetadata(type, spawnId); return data ? data->spawnGroupData : nullptr; }
SpawnGroupTemplateData const* GetDefaultSpawnGroup() const { return &_spawnGroupDataStore.at(0); }
SpawnGroupTemplateData const* GetLegacySpawnGroup() const { return &_spawnGroupDataStore.at(1); }
- Trinity::IteratorPair<SpawnGroupLinkContainer::const_iterator> GetSpawnDataForGroup(uint32 groupId) const { return Trinity::Containers::MapEqualRange(_spawnGroupMapStore, groupId); }
+ Trinity::IteratorPair<SpawnGroupLinkContainer::const_iterator> GetSpawnMetadataForGroup(uint32 groupId) const { return Trinity::Containers::MapEqualRange(_spawnGroupMapStore, groupId); }
std::vector<InstanceSpawnGroupInfo> const* GetSpawnGroupsForInstance(uint32 instanceId) const { auto it = _instanceSpawnGroupStore.find(instanceId); return it != _instanceSpawnGroupStore.end() ? &it->second : nullptr; }
MailLevelReward const* GetMailLevelReward(uint8 level, uint8 race) const
@@ -1476,29 +1477,28 @@ class TC_GAME_API ObjectMgr
return nullptr;
}
- SpawnData const* GetSpawnData(SpawnObjectType type, ObjectGuid::LowType guid)
+ SpawnMetadata const* GetSpawnMetadata(SpawnObjectType type, ObjectGuid::LowType spawnId) const
{
- if (type == SPAWN_TYPE_CREATURE)
- return GetCreatureData(guid);
- else if (type == SPAWN_TYPE_GAMEOBJECT)
- return GetGameObjectData(guid);
+ if (SpawnData::TypeHasData(type))
+ return GetSpawnData(type, spawnId);
else
- ASSERT(false, "Invalid spawn object type %u", uint32(type));
- return nullptr;
+ return nullptr;
}
+
+ SpawnData const* GetSpawnData(SpawnObjectType type, ObjectGuid::LowType spawnId) const;
void OnDeleteSpawnData(SpawnData const* data);
CreatureDataContainer const& GetAllCreatureData() const { return _creatureDataStore; }
- CreatureData const* GetCreatureData(ObjectGuid::LowType guid) const
+ CreatureData const* GetCreatureData(ObjectGuid::LowType spawnId) const
{
- CreatureDataContainer::const_iterator itr = _creatureDataStore.find(guid);
+ CreatureDataContainer::const_iterator itr = _creatureDataStore.find(spawnId);
if (itr == _creatureDataStore.end()) return nullptr;
return &itr->second;
}
- CreatureData& NewOrExistCreatureData(ObjectGuid::LowType guid) { return _creatureDataStore[guid]; }
- void DeleteCreatureData(ObjectGuid::LowType guid);
- ObjectGuid GetLinkedRespawnGuid(ObjectGuid guid) const
+ CreatureData& NewOrExistCreatureData(ObjectGuid::LowType spawnId) { return _creatureDataStore[spawnId]; }
+ void DeleteCreatureData(ObjectGuid::LowType spawnId);
+ ObjectGuid GetLinkedRespawnGuid(ObjectGuid spawnId) const
{
- LinkedRespawnContainer::const_iterator itr = _linkedRespawnStore.find(guid);
+ LinkedRespawnContainer::const_iterator itr = _linkedRespawnStore.find(spawnId);
if (itr == _linkedRespawnStore.end()) return ObjectGuid::Empty;
return itr->second;
}
@@ -1509,14 +1509,14 @@ class TC_GAME_API ObjectMgr
return &itr->second;
}
GameObjectDataContainer const& GetAllGameObjectData() const { return _gameObjectDataStore; }
- GameObjectData const* GetGameObjectData(ObjectGuid::LowType guid) const
+ GameObjectData const* GetGameObjectData(ObjectGuid::LowType spawnId) const
{
- GameObjectDataContainer::const_iterator itr = _gameObjectDataStore.find(guid);
+ GameObjectDataContainer::const_iterator itr = _gameObjectDataStore.find(spawnId);
if (itr == _gameObjectDataStore.end()) return nullptr;
return &itr->second;
}
- GameObjectData& NewOrExistGameObjectData(ObjectGuid::LowType guid) { return _gameObjectDataStore[guid]; }
- void DeleteGameObjectData(ObjectGuid::LowType guid);
+ GameObjectData& NewOrExistGameObjectData(ObjectGuid::LowType spawnId) { return _gameObjectDataStore[spawnId]; }
+ void DeleteGameObjectData(ObjectGuid::LowType spawnId);
GameObjectLocale const* GetGameObjectLocale(uint32 entry) const
{
GameObjectLocaleContainer::const_iterator itr = _gameObjectLocaleStore.find(entry);
diff --git a/src/server/game/Grids/ObjectGridLoader.cpp b/src/server/game/Grids/ObjectGridLoader.cpp
index 00d590467a1..a718f455dab 100644
--- a/src/server/game/Grids/ObjectGridLoader.cpp
+++ b/src/server/game/Grids/ObjectGridLoader.cpp
@@ -124,51 +124,19 @@ void LoadHelper(CellGuidSet const& guid_set, CellCoord &cell, GridRefManager<T>
{
for (CellGuidSet::const_iterator i_guid = guid_set.begin(); i_guid != guid_set.end(); ++i_guid)
{
- T* obj = new T;
+ // Don't spawn at all if there's a respawn timer
+ ObjectGuid::LowType guid = *i_guid;
+ if (!map->ShouldBeSpawnedOnGridLoad<T>(guid))
+ continue;
- // Don't spawn at all if there's a respawn time
- if ((obj->GetTypeId() == TYPEID_UNIT && !map->GetCreatureRespawnTime(*i_guid)) ||
- (obj->GetTypeId() == TYPEID_GAMEOBJECT && !map->GetGORespawnTime(*i_guid)) ||
- (obj->GetTypeId() == TYPEID_AREATRIGGER))
+ T* obj = new T;
+ //TC_LOG_INFO("misc", "DEBUG: LoadHelper from table: %s for (guid: " UI64FMTD ") Loading", table, guid);
+ if (!obj->LoadFromDB(guid, map, false, false))
{
- ObjectGuid::LowType guid = *i_guid;
- //TC_LOG_INFO("misc", "DEBUG: LoadHelper from table: %s for (guid: %u) Loading", table, guid);
-
- if (obj->GetTypeId() == TYPEID_UNIT)
- {
- CreatureData const* cdata = sObjectMgr->GetCreatureData(guid);
- ASSERT(cdata, "Tried to load creature with spawnId " UI64FMTD ", but no such creature exists.", guid);
- SpawnGroupTemplateData const* const group = cdata->spawnGroupData;
- // If creature in manual spawn group, don't spawn here, unless group is already active.
- if (!(group->flags & SPAWNGROUP_FLAG_SYSTEM))
- if (!map->IsSpawnGroupActive(group->groupId))
- {
- delete obj;
- continue;
- }
- }
- else if (obj->GetTypeId() == TYPEID_GAMEOBJECT)
- {
- // If gameobject in manual spawn group, don't spawn here, unless group is already active.
- GameObjectData const* godata = sObjectMgr->GetGameObjectData(guid);
- ASSERT(godata, "Tried to load gameobject with spawnId " UI64FMTD ", but no such object exists.", guid);
- if (!(godata->spawnGroupData->flags & SPAWNGROUP_FLAG_SYSTEM))
- if (!map->IsSpawnGroupActive(godata->spawnGroupData->groupId))
- {
- delete obj;
- continue;
- }
- }
-
- if (!obj->LoadFromDB(guid, map, false, false))
- {
- delete obj;
- continue;
- }
- AddObjectHelper(cell, m, count, map, obj);
- }
- else
delete obj;
+ continue;
+ }
+ AddObjectHelper(cell, m, count, map, obj);
}
}
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 01e797e576b..32d371fe78d 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -3190,75 +3190,66 @@ bool Map::CheckRespawn(RespawnInfo* info)
return true;
}
-void Map::DoRespawn(SpawnObjectType type, ObjectGuid::LowType spawnId, uint32 gridId)
+void Map::Respawn(RespawnInfo* info, CharacterDatabaseTransaction dbTrans)
{
- if (!IsGridLoaded(gridId)) // if grid isn't loaded, this will be processed in grid load handler
- return;
+ info->respawnTime = GameTime::GetGameTime();
+ SaveRespawnInfoDB(*info, dbTrans);
+}
+size_t Map::DespawnAll(SpawnObjectType type, ObjectGuid::LowType spawnId)
+{
+ std::vector<WorldObject*> toUnload;
switch (type)
{
case SPAWN_TYPE_CREATURE:
- {
- Creature* obj = new Creature();
- if (!obj->LoadFromDB(spawnId, this, true, true))
- delete obj;
+ for (auto const& pair : Trinity::Containers::MapEqualRange(GetCreatureBySpawnIdStore(), spawnId))
+ toUnload.push_back(pair.second);
break;
- }
case SPAWN_TYPE_GAMEOBJECT:
- {
- GameObject* obj = new GameObject();
- if (!obj->LoadFromDB(spawnId, this, true))
- delete obj;
- break;
- }
+ for (auto const& pair : Trinity::Containers::MapEqualRange(GetGameObjectBySpawnIdStore(), spawnId))
+ toUnload.push_back(pair.second);
default:
- ASSERT(false, "Invalid spawn type %u (spawnid " UI64FMTD ") on map %u", uint32(type), spawnId, GetId());
+ break;
}
-}
-void Map::Respawn(RespawnInfo* info, CharacterDatabaseTransaction dbTrans)
-{
- if (!CheckRespawn(info))
- {
- if (info->respawnTime)
- {
- _respawnTimes.decrease(info->handle);
- SaveRespawnInfoDB(*info, dbTrans);
- }
- else
- DeleteRespawnInfo(info, dbTrans);
- return;
- }
+ for (WorldObject* o : toUnload)
+ AddObjectToRemoveList(o);
- // remove the actual respawn record first - since this deletes it, we save what we need
- SpawnObjectType const type = info->type;
- uint32 const gridId = info->gridId;
- ObjectGuid::LowType const spawnId = info->spawnId;
- DeleteRespawnInfo(info, dbTrans);
- DoRespawn(type, spawnId, gridId);
+ return toUnload.size();
}
bool Map::AddRespawnInfo(RespawnInfo const& info)
{
- ASSERT(info.spawnId, "Attempt to schedule respawn with zero spawnid (type %u)", uint32(info.type));
+ if (!info.spawnId)
+ {
+ TC_LOG_ERROR("maps", "Attempt to insert respawn info for zero spawn id (type %u)", uint32(info.type));
+ return false;
+ }
- RespawnInfoMap& bySpawnIdMap = GetRespawnMapForType(info.type);
+ RespawnInfoMap* bySpawnIdMap = GetRespawnMapForType(info.type);
+ if (!bySpawnIdMap)
+ return false;
- auto it = bySpawnIdMap.find(info.spawnId);
- if (it != bySpawnIdMap.end()) // spawnid already has a respawn scheduled
+ // check if we already have the maximum possible number of respawns scheduled
+ if (SpawnData::TypeHasData(info.type))
{
- RespawnInfo* const existing = it->second;
- if (info.respawnTime < existing->respawnTime) // delete existing in this case
- DeleteRespawnInfo(existing);
- else
- return false;
+ auto it = bySpawnIdMap->find(info.spawnId);
+ if (it != bySpawnIdMap->end()) // spawnid already has a respawn scheduled
+ {
+ RespawnInfo* const existing = it->second;
+ if (info.respawnTime <= existing->respawnTime) // delete existing in this case
+ DeleteRespawnInfo(existing);
+ else
+ return false;
+ }
+ ASSERT(bySpawnIdMap->find(info.spawnId) == bySpawnIdMap->end(), "Insertion of respawn info with id (%u," UI64FMTD ") into spawn id map failed - state desync.", uint32(info.type), info.spawnId);
}
+ else
+ ASSERT(false, "Invalid respawn info for spawn id (%u," UI64FMTD ") being inserted", uint32(info.type), info.spawnId);
- // if we get to this point, we should insert the respawninfo (there either was no prior entry, or it was deleted already)
RespawnInfo * ri = new RespawnInfo(info);
ri->handle = _respawnTimes.push(ri);
- bool success = bySpawnIdMap.emplace(ri->spawnId, ri).second;
- ASSERT(success, "Insertion of respawn info with id (%u," UI64FMTD ") into spawn id map failed - state desync.", uint32(ri->type), ri->spawnId);
+ bySpawnIdMap->emplace(ri->spawnId, ri);
return true;
}
@@ -3279,9 +3270,11 @@ void Map::GetRespawnInfo(std::vector<RespawnInfo*>& respawnData, SpawnObjectType
RespawnInfo* Map::GetRespawnInfo(SpawnObjectType type, ObjectGuid::LowType spawnId) const
{
- RespawnInfoMap const& map = GetRespawnMapForType(type);
- auto it = map.find(spawnId);
- if (it == map.end())
+ RespawnInfoMap const* map = GetRespawnMapForType(type);
+ if (!map)
+ return nullptr;
+ auto it = map->find(spawnId);
+ if (it == map->end())
return nullptr;
return it->second;
}
@@ -3301,8 +3294,14 @@ void Map::DeleteRespawnInfo(RespawnInfo* info, CharacterDatabaseTransaction dbTr
ASSERT(info);
// spawnid store
- size_t const n = GetRespawnMapForType(info->type).erase(info->spawnId);
- ASSERT(n == 1, "Respawn stores inconsistent for map %u, spawnid " UI64FMTD " (type %u)", GetId(), info->spawnId, uint32(info->type));
+ auto spawnMap = GetRespawnMapForType(info->type);
+ if (!spawnMap)
+ return;
+
+ auto range = spawnMap->equal_range(info->spawnId);
+ auto it = std::find_if(range.first, range.second, [info](RespawnInfoMap::value_type const& pair) { return (pair.second == info); });
+ ASSERT(it != range.second, "Respawn stores inconsistent for map %u, spawnid " UI64FMTD " (type %u)", GetId(), info->spawnId, uint32(info->type));
+ spawnMap->erase(it);
// respawn heap
_respawnTimes.erase(info->handle);
@@ -3319,6 +3318,32 @@ void Map::DeleteRespawnInfo(RespawnInfo* info, CharacterDatabaseTransaction dbTr
delete info;
}
+void Map::DoRespawn(SpawnObjectType type, ObjectGuid::LowType spawnId, uint32 gridId)
+{
+ if (!IsGridLoaded(gridId)) // if grid isn't loaded, this will be processed in grid load handler
+ return;
+
+ switch (type)
+ {
+ case SPAWN_TYPE_CREATURE:
+ {
+ Creature* obj = new Creature();
+ if (!obj->LoadFromDB(spawnId, this, true, true))
+ delete obj;
+ break;
+ }
+ case SPAWN_TYPE_GAMEOBJECT:
+ {
+ GameObject* obj = new GameObject();
+ if (!obj->LoadFromDB(spawnId, this, true))
+ delete obj;
+ break;
+ }
+ default:
+ ASSERT(false, "Invalid spawn type %u (spawnid " UI64FMTD ") on map %u", uint32(type), spawnId, GetId());
+ }
+}
+
void Map::ProcessRespawns()
{
time_t now = GameTime::GetGameTime();
@@ -3331,14 +3356,14 @@ void Map::ProcessRespawns()
{
// ok, respawn
_respawnTimes.pop();
- GetRespawnMapForType(next->type).erase(next->spawnId);
+ ASSERT_NOTNULL(GetRespawnMapForType(next->type))->erase(next->spawnId);
DoRespawn(next->type, next->spawnId, next->gridId);
delete next;
}
else if (!next->respawnTime) // just remove respawn entry without rescheduling
{
_respawnTimes.pop();
- GetRespawnMapForType(next->type).erase(next->spawnId);
+ ASSERT_NOTNULL(GetRespawnMapForType(next->type))->erase(next->spawnId);
delete next;
}
else // value changed, update heap position
@@ -3371,8 +3396,11 @@ void Map::ApplyDynamicModeRespawnScaling(WorldObject const* obj, ObjectGuid::Low
return;
}
- SpawnData const* data = sObjectMgr->GetSpawnData(type, spawnId);
- if (!data || !data->spawnGroupData || !(data->spawnGroupData->flags & SPAWNGROUP_FLAG_DYNAMIC_SPAWN_RATE))
+ SpawnMetadata const* data = sObjectMgr->GetSpawnMetadata(type, spawnId);
+ if (!data)
+ return;
+
+ if (!(data->spawnGroupData->flags & SPAWNGROUP_FLAG_DYNAMIC_SPAWN_RATE))
return;
auto it = _zonePlayerCountMap.find(obj->GetZoneId());
@@ -3391,6 +3419,23 @@ void Map::ApplyDynamicModeRespawnScaling(WorldObject const* obj, ObjectGuid::Low
respawnDelay = std::max<uint32>(ceil(respawnDelay * adjustFactor), timeMinimum);
}
+bool Map::ShouldBeSpawnedOnGridLoad(SpawnObjectType type, ObjectGuid::LowType spawnId) const
+{
+ ASSERT(SpawnData::TypeHasData(type));
+ // check if the object is on its respawn timer
+ if (GetRespawnTime(type, spawnId))
+ return false;
+
+ SpawnMetadata const* spawnData = ASSERT_NOTNULL(sObjectMgr->GetSpawnMetadata(type, spawnId));
+ // check if the object is part of a spawn group
+ SpawnGroupTemplateData const* spawnGroup = ASSERT_NOTNULL(spawnData->spawnGroupData);
+ if (!(spawnGroup->flags & SPAWNGROUP_FLAG_SYSTEM))
+ if (!IsSpawnGroupActive(spawnGroup->groupId))
+ return false;
+
+ return true;
+}
+
SpawnGroupTemplateData const* Map::GetSpawnGroupData(uint32 groupId) const
{
SpawnGroupTemplateData const* data = sObjectMgr->GetSpawnGroupData(groupId);
@@ -3409,31 +3454,44 @@ bool Map::SpawnGroupSpawn(uint32 groupId, bool ignoreRespawn, bool force, std::v
}
SetSpawnGroupActive(groupId, true); // start processing respawns for the group
- for (auto& pair : sObjectMgr->GetSpawnDataForGroup(groupId))
- {
- SpawnData const* data = pair.second;
- ASSERT(groupData->mapId == data->spawnPoint.GetMapId());
- // Check if there's already an instance spawned
- if (!force)
- if (WorldObject* obj = GetWorldObjectBySpawnId(data->type, data->spawnId))
- if ((data->type != SPAWN_TYPE_CREATURE) || obj->ToCreature()->IsAlive())
- continue;
- time_t respawnTime = GetRespawnTime(data->type, data->spawnId);
- if (respawnTime)
+ std::vector<SpawnData const*> toSpawn;
+ for (auto& pair : sObjectMgr->GetSpawnMetadataForGroup(groupId))
+ {
+ SpawnMetadata const* data = pair.second;
+ ASSERT(groupData->mapId == data->mapId);
+
+ auto respawnMap = GetRespawnMapForType(data->type);
+ if (!respawnMap)
+ continue;
+
+ if (force || ignoreRespawn)
+ RemoveRespawnTime(data->type, data->spawnId);
+
+ uint32 nRespawnTimers = respawnMap->count(data->spawnId);
+ if (SpawnData::TypeHasData(data->type))
{
- if (!force && !ignoreRespawn && (respawnTime > GameTime::GetGameTime()))
+ // has a respawn timer
+ if (nRespawnTimers)
continue;
- // we need to remove the respawn time, otherwise we'd end up double spawning
- RemoveRespawnTime(data->type, data->spawnId);
+ // has a spawn already active
+ if (!force)
+ if (WorldObject* obj = GetWorldObjectBySpawnId(data->type, data->spawnId))
+ if ((data->type != SPAWN_TYPE_CREATURE) || obj->ToCreature()->IsAlive())
+ continue;
+
+ toSpawn.push_back(ASSERT_NOTNULL(data->ToSpawnData()));
}
+ }
+ for (SpawnData const* data : toSpawn)
+ {
// don't spawn if the grid isn't loaded (will be handled in grid loader)
if (!IsGridLoaded(data->spawnPoint))
continue;
- // Everything OK, now do the actual (re)spawn
+ // now do the actual (re)spawn
switch (data->type)
{
case SPAWN_TYPE_CREATURE:
@@ -3454,6 +3512,15 @@ bool Map::SpawnGroupSpawn(uint32 groupId, bool ignoreRespawn, bool force, std::v
spawnedObjects->push_back(gameobject);
break;
}
+ case SPAWN_TYPE_AREATRIGGER:
+ {
+ AreaTrigger* areaTrigger = new AreaTrigger();
+ if (!areaTrigger->LoadFromDB(data->spawnId, this, true, false))
+ delete areaTrigger;
+ else if (spawnedObjects)
+ spawnedObjects->push_back(areaTrigger);
+ break;
+ }
default:
ASSERT(false, "Invalid spawn type %u with spawnId " UI64FMTD, uint32(data->type), data->spawnId);
return false;
@@ -3471,41 +3538,16 @@ bool Map::SpawnGroupDespawn(uint32 groupId, bool deleteRespawnTimes, size_t* cou
return false;
}
- std::vector<WorldObject*> toUnload; // unload after iterating, otherwise iterator invalidation
- for (auto const& pair : sObjectMgr->GetSpawnDataForGroup(groupId))
+ for (auto const& pair : sObjectMgr->GetSpawnMetadataForGroup(groupId))
{
- SpawnData const* data = pair.second;
- ASSERT(groupData->mapId == data->spawnPoint.GetMapId());
+ SpawnMetadata const* data = pair.second;
+ ASSERT(groupData->mapId == data->mapId);
if (deleteRespawnTimes)
RemoveRespawnTime(data->type, data->spawnId);
- switch (data->type)
- {
- case SPAWN_TYPE_CREATURE:
- {
- auto bounds = GetCreatureBySpawnIdStore().equal_range(data->spawnId);
- for (auto it = bounds.first; it != bounds.second; ++it)
- toUnload.emplace_back(it->second);
- break;
- }
- case SPAWN_TYPE_GAMEOBJECT:
- {
- auto bounds = GetGameObjectBySpawnIdStore().equal_range(data->spawnId);
- for (auto it = bounds.first; it != bounds.second; ++it)
- toUnload.emplace_back(it->second);
- break;
- }
- default:
- ASSERT(false, "Invalid spawn type %u in spawn data with spawnId " UI64FMTD ".", uint32(data->type), data->spawnId);
- return false;
- }
+ size_t c = DespawnAll(data->type, data->spawnId);
+ if (count)
+ *count += c;
}
-
- if (count)
- *count = toUnload.size();
-
- // now do the actual despawning
- for (WorldObject* obj : toUnload)
- obj->AddObjectToRemoveList();
SetSpawnGroupActive(groupId, false); // stop processing respawns for the group, too
return true;
}
@@ -4489,6 +4531,15 @@ GameObject* Map::GetGameObjectBySpawnId(ObjectGuid::LowType spawnId) const
return creatureItr != bounds.second ? creatureItr->second : bounds.first->second;
}
+AreaTrigger* Map::GetAreaTriggerBySpawnId(ObjectGuid::LowType spawnId) const
+{
+ auto const bounds = GetAreaTriggerBySpawnIdStore().equal_range(spawnId);
+ if (bounds.first == bounds.second)
+ return nullptr;
+
+ return bounds.first->second;
+}
+
void Map::UpdateIteratorBack(Player* player)
{
if (m_mapRefIter == player->GetMapRef())
@@ -4497,19 +4548,23 @@ void Map::UpdateIteratorBack(Player* player)
void Map::SaveRespawnTime(SpawnObjectType type, ObjectGuid::LowType spawnId, uint32 entry, time_t respawnTime, uint32 gridId, CharacterDatabaseTransaction dbTrans, bool startup)
{
- if (!spawnId)
+ SpawnMetadata const* data = sObjectMgr->GetSpawnMetadata(type, spawnId);
+ if (!data)
+ {
+ TC_LOG_ERROR("maps", "Map %u attempt to save respawn time for nonexistant spawnid (%u," UI64FMTD ").", GetId(), type, spawnId);
return;
+ }
if (!respawnTime)
{
// Delete only
- RemoveRespawnTime(type, spawnId, dbTrans);
+ RemoveRespawnTime(data->type, data->spawnId, dbTrans);
return;
}
RespawnInfo ri;
- ri.type = type;
- ri.spawnId = spawnId;
+ ri.type = data->type;
+ ri.spawnId = data->spawnId;
ri.entry = entry;
ri.respawnTime = respawnTime;
ri.gridId = gridId;
@@ -4549,7 +4604,7 @@ void Map::LoadRespawnTimes()
ObjectGuid::LowType spawnId = fields[1].GetUInt64();
time_t respawnTime = fields[2].GetInt64();
- if (type < SPAWN_TYPE_MAX)
+ if (SpawnData::TypeHasData(type))
{
if (SpawnData const* data = sObjectMgr->GetSpawnData(type, spawnId))
SaveRespawnTime(type, spawnId, data->id, time_t(respawnTime), Trinity::ComputeGridCoord(data->spawnPoint.GetPositionX(), data->spawnPoint.GetPositionY()).GetId(), nullptr, true);
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 96bb6c29aeb..4966358b2ee 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -453,6 +453,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
Transport* GetTransport(ObjectGuid const& guid);
Creature* GetCreatureBySpawnId(ObjectGuid::LowType spawnId) const;
GameObject* GetGameObjectBySpawnId(ObjectGuid::LowType spawnId) const;
+ AreaTrigger* GetAreaTriggerBySpawnId(ObjectGuid::LowType spawnId) const;
WorldObject* GetWorldObjectBySpawnId(SpawnObjectType type, ObjectGuid::LowType spawnId) const
{
switch (type)
@@ -461,6 +462,8 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
return reinterpret_cast<WorldObject*>(GetCreatureBySpawnId(spawnId));
case SPAWN_TYPE_GAMEOBJECT:
return reinterpret_cast<WorldObject*>(GetGameObjectBySpawnId(spawnId));
+ case SPAWN_TYPE_AREATRIGGER:
+ return reinterpret_cast<WorldObject*>(GetAreaTriggerBySpawnId(spawnId));
default:
return nullptr;
}
@@ -476,6 +479,10 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
GameObjectBySpawnIdContainer& GetGameObjectBySpawnIdStore() { return _gameobjectBySpawnIdStore; }
GameObjectBySpawnIdContainer const& GetGameObjectBySpawnIdStore() const { return _gameobjectBySpawnIdStore; }
+ typedef std::unordered_multimap<ObjectGuid::LowType, AreaTrigger*> AreaTriggerBySpawnIdContainer;
+ AreaTriggerBySpawnIdContainer& GetAreaTriggerBySpawnIdStore() { return _areaTriggerBySpawnIdStore; }
+ AreaTriggerBySpawnIdContainer const& GetAreaTriggerBySpawnIdStore() const { return _areaTriggerBySpawnIdStore; }
+
std::unordered_set<Corpse*> const* GetCorpsesInCell(uint32 cellId) const
{
auto itr = _corpsesByCell.find(cellId);
@@ -528,9 +535,12 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
time_t GetLinkedRespawnTime(ObjectGuid guid) const;
time_t GetRespawnTime(SpawnObjectType type, ObjectGuid::LowType spawnId) const
{
- auto const& map = GetRespawnMapForType(type);
- auto it = map.find(spawnId);
- return (it == map.end()) ? 0 : it->second->respawnTime;
+ if (auto map = GetRespawnMapForType(type))
+ {
+ auto it = map->find(spawnId);
+ return (it == map->end()) ? 0 : it->second->respawnTime;
+ }
+ return 0;
}
time_t GetCreatureRespawnTime(ObjectGuid::LowType spawnId) const { return GetRespawnTime(SPAWN_TYPE_CREATURE, spawnId); }
time_t GetGORespawnTime(ObjectGuid::LowType spawnId) const { return GetRespawnTime(SPAWN_TYPE_GAMEOBJECT, spawnId); }
@@ -541,6 +551,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
void SaveRespawnInfoDB(RespawnInfo const& info, CharacterDatabaseTransaction dbTrans = nullptr);
void LoadRespawnTimes();
void DeleteRespawnTimes() { UnloadAllRespawnInfos(); DeleteRespawnTimesInDB(GetId(), GetInstanceId()); }
+ static void DeleteRespawnTimesInDB(uint16 mapId, uint32 instanceId);
void LoadCorpseData();
void DeleteCorpseData();
@@ -549,8 +560,6 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
Corpse* ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia = false);
void RemoveOldCorpses();
- static void DeleteRespawnTimesInDB(uint16 mapId, uint32 instanceId);
-
void SendInitTransports(Player* player);
void SendRemoveTransports(Player* player);
void SendUpdateTransportVisibility(Player* player);
@@ -732,7 +741,6 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
// if return value is false and info->respawnTime is nonzero, it is guaranteed to be greater than time(NULL)
bool CheckRespawn(RespawnInfo* info);
void DoRespawn(SpawnObjectType type, ObjectGuid::LowType spawnId, uint32 gridId);
- void Respawn(RespawnInfo* info, CharacterDatabaseTransaction dbTrans = nullptr);
bool AddRespawnInfo(RespawnInfo const& info);
void UnloadAllRespawnInfos();
void DeleteRespawnInfo(RespawnInfo* info, CharacterDatabaseTransaction dbTrans = nullptr);
@@ -745,11 +753,16 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
if (RespawnInfo* info = GetRespawnInfo(type, spawnId))
Respawn(info, dbTrans);
}
+ void Respawn(RespawnInfo* info, CharacterDatabaseTransaction dbTrans = nullptr);
void RemoveRespawnTime(SpawnObjectType type, ObjectGuid::LowType spawnId, CharacterDatabaseTransaction dbTrans = nullptr)
{
if (RespawnInfo* info = GetRespawnInfo(type, spawnId))
DeleteRespawnInfo(info, dbTrans);
}
+ size_t DespawnAll(SpawnObjectType type, ObjectGuid::LowType spawnId);
+
+ bool ShouldBeSpawnedOnGridLoad(SpawnObjectType type, ObjectGuid::LowType spawnId) const;
+ template <typename T> bool ShouldBeSpawnedOnGridLoad(ObjectGuid::LowType spawnId) const { return ShouldBeSpawnedOnGridLoad(SpawnData::TypeFor<T>, spawnId); }
SpawnGroupTemplateData const* GetSpawnGroupData(uint32 groupId) const;
@@ -801,28 +814,32 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
RespawnListContainer _respawnTimes;
RespawnInfoMap _creatureRespawnTimesBySpawnId;
RespawnInfoMap _gameObjectRespawnTimesBySpawnId;
- RespawnInfoMap& GetRespawnMapForType(SpawnObjectType type)
+ RespawnInfoMap* GetRespawnMapForType(SpawnObjectType type)
{
switch (type)
{
default:
ASSERT(false);
case SPAWN_TYPE_CREATURE:
- return _creatureRespawnTimesBySpawnId;
+ return &_creatureRespawnTimesBySpawnId;
case SPAWN_TYPE_GAMEOBJECT:
- return _gameObjectRespawnTimesBySpawnId;
+ return &_gameObjectRespawnTimesBySpawnId;
+ case SPAWN_TYPE_AREATRIGGER:
+ return nullptr;
}
}
- RespawnInfoMap const& GetRespawnMapForType(SpawnObjectType type) const
+ RespawnInfoMap const* GetRespawnMapForType(SpawnObjectType type) const
{
switch (type)
{
default:
ASSERT(false);
case SPAWN_TYPE_CREATURE:
- return _creatureRespawnTimesBySpawnId;
+ return &_creatureRespawnTimesBySpawnId;
case SPAWN_TYPE_GAMEOBJECT:
- return _gameObjectRespawnTimesBySpawnId;
+ return &_gameObjectRespawnTimesBySpawnId;
+ case SPAWN_TYPE_AREATRIGGER:
+ return nullptr;
}
}
@@ -850,6 +867,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
MapStoredObjectTypesContainer _objectsStore;
CreatureBySpawnIdContainer _creatureBySpawnIdStore;
GameObjectBySpawnIdContainer _gameobjectBySpawnIdStore;
+ AreaTriggerBySpawnIdContainer _areaTriggerBySpawnIdStore;
std::unordered_map<uint32/*cellId*/, std::unordered_set<Corpse*>> _corpsesByCell;
std::unordered_map<ObjectGuid, Corpse*> _corpsesByPlayer;
std::unordered_set<Corpse*> _corpseBones;
diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h
index d74e87dd32c..04774ae0865 100644
--- a/src/server/game/Maps/MapManager.h
+++ b/src/server/game/Maps/MapManager.h
@@ -103,9 +103,14 @@ class TC_GAME_API MapManager
return IsValidMAP(mapid, false) && Trinity::IsValidMapCoord(x, y, z, o);
}
+ static bool IsValidMapCoord(uint32 mapid, Position const& pos)
+ {
+ return IsValidMapCoord(mapid, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation());
+ }
+
static bool IsValidMapCoord(WorldLocation const& loc)
{
- return IsValidMapCoord(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetOrientation());
+ return IsValidMapCoord(loc.GetMapId(), loc);
}
void DoDelayedMovesAndRemoves();
diff --git a/src/server/game/Maps/SpawnData.h b/src/server/game/Maps/SpawnData.h
index d1023ffbeb2..1b96a70ecc1 100644
--- a/src/server/game/Maps/SpawnData.h
+++ b/src/server/game/Maps/SpawnData.h
@@ -22,21 +22,30 @@
#include "Position.h"
#include <vector>
+class AreaTrigger;
+class Creature;
+class GameObject;
+class Pool;
+struct PoolTemplate;
+
// EnumUtils: DESCRIBE THIS
enum SpawnObjectType
{
SPAWN_TYPE_CREATURE = 0, // TITLE Creature
SPAWN_TYPE_GAMEOBJECT = 1, // TITLE Gameobject
-
- SPAWN_TYPE_MAX // SKIP
+ SPAWN_TYPE_AREATRIGGER = 2,// TITLE AreaTrigger
+ NUM_SPAWN_TYPES_WITH_DATA, // SKIP
+ NUM_SPAWN_TYPES = NUM_SPAWN_TYPES_WITH_DATA // SKIP
};
enum SpawnObjectTypeMask
{
SPAWN_TYPEMASK_CREATURE = (1 << SPAWN_TYPE_CREATURE),
SPAWN_TYPEMASK_GAMEOBJECT = (1 << SPAWN_TYPE_GAMEOBJECT),
+ SPAWN_TYPEMASK_AREATRIGGER = (1 << SPAWN_TYPE_AREATRIGGER),
- SPAWN_TYPEMASK_ALL = (1 << SPAWN_TYPE_MAX)-1
+ SPAWN_TYPEMASK_WITH_DATA = (1 << NUM_SPAWN_TYPES_WITH_DATA)-1,
+ SPAWN_TYPEMASK_ALL = (1 << NUM_SPAWN_TYPES)-1
};
enum SpawnGroupFlags
@@ -59,24 +68,49 @@ struct SpawnGroupTemplateData
SpawnGroupFlags flags;
};
-struct SpawnData
+namespace Trinity { namespace Impl {
+ template <typename T>
+ struct SpawnObjectTypeForImpl { static_assert(!std::is_same<T,T>::value, "This type does not have an associated spawn type!"); };
+ template <> struct SpawnObjectTypeForImpl<Creature> { static constexpr SpawnObjectType value = SPAWN_TYPE_CREATURE; };
+ template <> struct SpawnObjectTypeForImpl<GameObject> { static constexpr SpawnObjectType value = SPAWN_TYPE_GAMEOBJECT; };
+ template <> struct SpawnObjectTypeForImpl<AreaTrigger> { static constexpr SpawnObjectType value = SPAWN_TYPE_AREATRIGGER; };
+}}
+
+struct SpawnData;
+struct SpawnMetadata
{
+ static constexpr bool TypeInMask(SpawnObjectType type, SpawnObjectTypeMask mask) { return ((1 << type) & mask); }
+ static constexpr bool TypeHasData(SpawnObjectType type) { return (type < NUM_SPAWN_TYPES_WITH_DATA); }
+ static constexpr bool TypeIsValid(SpawnObjectType type) { return (type < NUM_SPAWN_TYPES); }
+ template <typename T>
+ static constexpr SpawnObjectType TypeFor = Trinity::Impl::SpawnObjectTypeForImpl<T>::value;
+
+ SpawnData const* ToSpawnData() const { return TypeHasData(type) ? reinterpret_cast<SpawnData const*>(this) : nullptr; }
+
SpawnObjectType const type;
uint64 spawnId = 0;
+ uint32 mapId = MAPID_INVALID;
+ bool dbData = true;
+ SpawnGroupTemplateData const* spawnGroupData = nullptr;
+
+ protected:
+ SpawnMetadata(SpawnObjectType t) : type(t) {}
+};
+
+struct SpawnData : public SpawnMetadata
+{
uint32 id = 0; // entry in respective _template table
- WorldLocation spawnPoint;
+ Position spawnPoint;
uint8 phaseUseFlags = 0;
uint32 phaseId = 0;
uint32 phaseGroup = 0;
int32 terrainSwapMap = -1;
int32 spawntimesecs = 0;
std::vector<Difficulty> spawnDifficulties;
- SpawnGroupTemplateData const* spawnGroupData = nullptr;
uint32 scriptId = 0;
- bool dbData = true;
protected:
- SpawnData(SpawnObjectType t) : type(t) {}
+ SpawnData(SpawnObjectType t) : SpawnMetadata(t) {}
};
enum LinkedRespawnType
diff --git a/src/server/game/Maps/enuminfo_SpawnData.cpp b/src/server/game/Maps/enuminfo_SpawnData.cpp
index 92226f25572..a4ff6770ed0 100644
--- a/src/server/game/Maps/enuminfo_SpawnData.cpp
+++ b/src/server/game/Maps/enuminfo_SpawnData.cpp
@@ -35,6 +35,7 @@ TC_API_EXPORT EnumText EnumUtils<SpawnObjectType>::ToString(SpawnObjectType valu
{
case SPAWN_TYPE_CREATURE: return { "SPAWN_TYPE_CREATURE", "Creature", "" };
case SPAWN_TYPE_GAMEOBJECT: return { "SPAWN_TYPE_GAMEOBJECT", "Gameobject", "" };
+ case SPAWN_TYPE_AREATRIGGER: return { "SPAWN_TYPE_AREATRIGGER", "AreaTrigger", "" };
default: throw std::out_of_range("value");
}
}
@@ -49,6 +50,7 @@ TC_API_EXPORT SpawnObjectType EnumUtils<SpawnObjectType>::FromIndex(size_t index
{
case 0: return SPAWN_TYPE_CREATURE;
case 1: return SPAWN_TYPE_GAMEOBJECT;
+ case 2: return SPAWN_TYPE_AREATRIGGER;
default: throw std::out_of_range("index");
}
}
diff --git a/src/server/game/Pools/PoolMgr.cpp b/src/server/game/Pools/PoolMgr.cpp
index 10af28c306d..d9402f7797a 100644
--- a/src/server/game/Pools/PoolMgr.cpp
+++ b/src/server/game/Pools/PoolMgr.cpp
@@ -177,7 +177,7 @@ void PoolGroup<Creature>::Despawn1Object(uint64 guid)
{
sObjectMgr->RemoveCreatureFromGrid(guid, data);
- Map* map = sMapMgr->FindMap(data->spawnPoint.GetMapId(), 0);
+ Map* map = sMapMgr->FindMap(data->mapId, 0);
if (map && !map->Instanceable())
{
auto creatureBounds = map->GetCreatureBySpawnIdStore().equal_range(guid);
@@ -202,7 +202,7 @@ void PoolGroup<GameObject>::Despawn1Object(uint64 guid)
{
sObjectMgr->RemoveGameobjectFromGrid(guid, data);
- Map* map = sMapMgr->FindMap(data->spawnPoint.GetMapId(), 0);
+ Map* map = sMapMgr->FindMap(data->mapId, 0);
if (map && !map->Instanceable())
{
auto gameobjectBounds = map->GetGameObjectBySpawnIdStore().equal_range(guid);
@@ -323,7 +323,7 @@ void PoolGroup<Creature>::Spawn1Object(PoolObject* obj)
sObjectMgr->AddCreatureToGrid(obj->guid, data);
// Spawn if necessary (loaded grids only)
- Map* map = sMapMgr->FindMap(data->spawnPoint.GetMapId(), 0);
+ Map* map = sMapMgr->FindMap(data->mapId, 0);
// We use spawn coords to spawn
if (map && !map->Instanceable() && map->IsGridLoaded(data->spawnPoint))
Creature::CreateCreatureFromDB(obj->guid, map);
@@ -339,7 +339,7 @@ void PoolGroup<GameObject>::Spawn1Object(PoolObject* obj)
sObjectMgr->AddGameobjectToGrid(obj->guid, data);
// Spawn if necessary (loaded grids only)
// this base map checked as non-instanced and then only existed
- Map* map = sMapMgr->FindMap(data->spawnPoint.GetMapId(), 0);
+ Map* map = sMapMgr->FindMap(data->mapId, 0);
// We use current coords to unspawn, not spawn coords since creature can have changed grid
if (map && !map->Instanceable() && map->IsGridLoaded(data->spawnPoint))
{
@@ -760,6 +760,8 @@ uint32 PoolMgr::IsPartOfAPool(SpawnObjectType type, ObjectGuid::LowType spawnId)
return IsPartOfAPool<Creature>(spawnId);
case SPAWN_TYPE_GAMEOBJECT:
return IsPartOfAPool<GameObject>(spawnId);
+ case SPAWN_TYPE_AREATRIGGER:
+ return 0;
default:
ASSERT(false, "Invalid spawn type %u passed to PoolMgr::IsPartOfPool (with spawnId " UI64FMTD ")", uint32(type), spawnId);
return 0;
diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp
index 98d599e2720..47e1c737849 100644
--- a/src/server/scripts/Commands/cs_go.cpp
+++ b/src/server/scripts/Commands/cs_go.cpp
@@ -85,13 +85,15 @@ public:
return commandTable;
}
- static bool DoTeleport(ChatHandler* handler, WorldLocation loc)
+ static bool DoTeleport(ChatHandler* handler, Position pos, uint32 mapId = MAPID_INVALID)
{
Player* player = handler->GetSession()->GetPlayer();
- if (!MapManager::IsValidMapCoord(loc) || sObjectMgr->IsTransportMap(loc.GetMapId()))
+ if (mapId == MAPID_INVALID)
+ mapId = player->GetMapId();
+ if (!MapManager::IsValidMapCoord(mapId, pos) || sObjectMgr->IsTransportMap(mapId))
{
- handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, loc.GetPositionX(), loc.GetPositionY(), loc.GetMapId());
+ handler->PSendSysMessage(LANG_INVALID_TARGET_COORD, pos.GetPositionX(), pos.GetPositionY(), mapId);
handler->SetSentErrorMessage(true);
return false;
}
@@ -102,7 +104,7 @@ public:
else
player->SaveRecallPosition(); // save only in non-flight case
- player->TeleportTo(loc);
+ player->TeleportTo({ mapId, pos });
return true;
}
@@ -116,7 +118,7 @@ public:
return false;
}
- return DoTeleport(handler, spawnpoint->spawnPoint);
+ return DoTeleport(handler, spawnpoint->spawnPoint, spawnpoint->mapId);
}
static bool HandleGoCreatureCIdCommand(ChatHandler* handler, Variant<Hyperlink<creature_entry>, uint32> cId)
@@ -143,7 +145,7 @@ public:
return false;
}
- return DoTeleport(handler, spawnpoint->spawnPoint);
+ return DoTeleport(handler, spawnpoint->spawnPoint, spawnpoint->mapId);
}
static bool HandleGoGameObjectSpawnIdCommand(ChatHandler* handler, uint32 spawnId)
@@ -156,7 +158,7 @@ public:
return false;
}
- return DoTeleport(handler, spawnpoint->spawnPoint);
+ return DoTeleport(handler, spawnpoint->spawnPoint, spawnpoint->mapId);
}
static bool HandleGoGameObjectGOIdCommand(ChatHandler* handler, uint32 goId)
@@ -183,7 +185,7 @@ public:
return false;
}
- return DoTeleport(handler, spawnpoint->spawnPoint);
+ return DoTeleport(handler, spawnpoint->spawnPoint, spawnpoint->mapId);
}
static bool HandleGoGraveyardCommand(ChatHandler* handler, uint32 gyId)
@@ -315,7 +317,7 @@ public:
handler->SetSentErrorMessage(true);
return false;
}
- return DoTeleport(handler, { node->ContinentID, { node->Pos.X, node->Pos.Y, node->Pos.Z } });
+ return DoTeleport(handler, { node->Pos.X, node->Pos.Y, node->Pos.Z }, node->ContinentID);
}
static bool HandleGoAreaTriggerCommand(ChatHandler* handler, Variant<Hyperlink<areatrigger>, uint32> areaTriggerId)
@@ -327,7 +329,7 @@ public:
handler->SetSentErrorMessage(true);
return false;
}
- return DoTeleport(handler, { uint32(at->ContinentID), { at->Pos.X, at->Pos.Y, at->Pos.Z } });
+ return DoTeleport(handler, { at->Pos.X, at->Pos.Y, at->Pos.Z }, at->ContinentID);
}
//teleport at coordinates
@@ -428,7 +430,7 @@ public:
z = std::max(map->GetStaticHeight(PhasingHandler::GetEmptyPhaseShift(), x, y, MAX_HEIGHT), map->GetWaterLevel(PhasingHandler::GetEmptyPhaseShift(), x, y));
}
- return DoTeleport(handler, { mapId, { x, y, *z, o.get_value_or(0.0f) } });
+ return DoTeleport(handler, { x, y, *z, o.get_value_or(0.0f) }, mapId);
}
template<typename T>
@@ -455,7 +457,7 @@ public:
static bool HandleGoOffsetCommand(ChatHandler* handler, float dX, Optional<float> dY, Optional<float> dZ, Optional<float> dO)
{
- WorldLocation loc = handler->GetSession()->GetPlayer()->GetWorldLocation();
+ Position loc = handler->GetSession()->GetPlayer()->GetPosition();
loc.RelocateOffset({ dX, dY.get_value_or(0.0f), dZ.get_value_or(0.0f), dO.get_value_or(0.0f) });
return DoTeleport(handler, loc);
@@ -620,9 +622,9 @@ public:
handler->PSendSysMessage(LANG_COMMAND_BOSS_MULTIPLE_SPAWNS, boss->Name.c_str(), boss->Entry);
for (CreatureData const* spawn : spawns)
{
- uint32 const mapId = spawn->spawnPoint.GetMapId();
+ uint32 const mapId = spawn->mapId;
MapEntry const* const map = ASSERT_NOTNULL(sMapStore.LookupEntry(mapId));
- handler->PSendSysMessage(LANG_COMMAND_BOSS_MULTIPLE_SPAWN_ETY, spawn->spawnId, mapId, map->MapName[handler->GetSessionDbcLocale()], spawn->spawnPoint.GetPosition().ToString().c_str());
+ handler->PSendSysMessage(LANG_COMMAND_BOSS_MULTIPLE_SPAWN_ETY, spawn->spawnId, mapId, map->MapName[handler->GetSessionDbcLocale()], spawn->spawnPoint.ToString().c_str());
}
handler->SetSentErrorMessage(true);
return false;
@@ -635,8 +637,8 @@ public:
player->SaveRecallPosition();
CreatureData const* const spawn = spawns.front();
- uint32 const mapId = spawn->spawnPoint.GetMapId();
- if (!player->TeleportTo(spawn->spawnPoint))
+ uint32 const mapId = spawn->mapId;
+ if (!player->TeleportTo({ mapId, spawn->spawnPoint }))
{
char const* const mapName = ASSERT_NOTNULL(sMapStore.LookupEntry(mapId))->MapName[handler->GetSessionDbcLocale()];
handler->PSendSysMessage(LANG_COMMAND_GO_BOSS_FAILED, spawn->spawnId, boss->Name.c_str(), boss->Entry, mapName);
diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp
index b0fdcd613d2..f0856c9a028 100644
--- a/src/server/scripts/Commands/cs_list.cpp
+++ b/src/server/scripts/Commands/cs_list.cpp
@@ -658,7 +658,7 @@ public:
for (auto const& pair : sObjectMgr->GetAllCreatureData())
{
SpawnData const& data = pair.second;
- if (data.spawnPoint.GetMapId() != mapId)
+ if (data.mapId != mapId)
continue;
CreatureTemplate const* cTemp = sObjectMgr->GetCreatureTemplate(data.id);
if (!cTemp)
@@ -669,7 +669,7 @@ public:
for (auto const& pair : sObjectMgr->GetAllGameObjectData())
{
SpawnData const& data = pair.second;
- if (data.spawnPoint.GetMapId() != mapId)
+ if (data.mapId != mapId)
continue;
GameObjectTemplate const* goTemp = sObjectMgr->GetGameObjectTemplate(data.id);
if (!goTemp)
@@ -711,25 +711,27 @@ public:
map->GetRespawnInfo(respawns, SpawnObjectTypeMask(1 << type));
for (RespawnInfo const* ri : respawns)
{
- SpawnData const* data = sObjectMgr->GetSpawnData(ri->type, ri->spawnId);
+ SpawnMetadata const* data = sObjectMgr->GetSpawnMetadata(ri->type, ri->spawnId);
if (!data)
continue;
- uint32 respawnZoneId = map->GetZoneId(PhasingHandler::GetEmptyPhaseShift(), data->spawnPoint);
- if (range)
+ uint32 respawnZoneId = 0;
+ if (SpawnData const* edata = data->ToSpawnData())
{
- if (!player->IsInDist(data->spawnPoint, range))
- continue;
- }
- else
- {
- if (zoneId != respawnZoneId)
- continue;
+ respawnZoneId = map->GetZoneId(PhasingHandler::GetEmptyPhaseShift(), edata->spawnPoint);
+ if (range)
+ {
+ if (!player->IsInDist(edata->spawnPoint, range))
+ continue;
+ }
+ else
+ {
+ if (zoneId != respawnZoneId)
+ continue;
+ }
}
-
uint32 gridY = ri->gridId / MAX_NUMBER_OF_GRIDS;
uint32 gridX = ri->gridId % MAX_NUMBER_OF_GRIDS;
-
std::string respawnTime = ri->respawnTime > GameTime::GetGameTime() ? secsToTimeString(uint64(ri->respawnTime - GameTime::GetGameTime()), true) : stringOverdue;
handler->PSendSysMessage(UI64FMTD " | %u | [%02u,%02u] | %s (%u) | %s%s", ri->spawnId, ri->entry, gridX, gridY, GetZoneName(respawnZoneId, locale), respawnZoneId, respawnTime.c_str(), map->IsSpawnGroupActive(data->spawnGroupData->groupId) ? "" : " (inactive)");
}
diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp
index 6530652fe71..db5531c9eef 100644
--- a/src/server/scripts/Commands/cs_npc.cpp
+++ b/src/server/scripts/Commands/cs_npc.cpp
@@ -804,7 +804,7 @@ public:
return false;
}
- if (player->GetMapId() != data->spawnPoint.GetMapId())
+ if (player->GetMapId() != data->mapId)
{
handler->PSendSysMessage(LANG_COMMAND_CREATUREATSAMEMAP, std::to_string(lowguid).c_str());
handler->SetSentErrorMessage(true);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
index f4a2e8b6adb..e109a1e793e 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
@@ -380,8 +380,8 @@ class instance_icecrown_citadel : public InstanceMapScript
break;
case NPC_ZAFOD_BOOMBOX:
if (GameObjectTemplate const* go = sObjectMgr->GetGameObjectTemplate(GO_THE_SKYBREAKER_A))
- if ((TeamInInstance == ALLIANCE && int32(data->spawnPoint.GetMapId()) == go->moTransport.SpawnMap) ||
- (TeamInInstance == HORDE && int32(data->spawnPoint.GetMapId()) != go->moTransport.SpawnMap))
+ if ((TeamInInstance == ALLIANCE && int32(data->mapId) == go->moTransport.SpawnMap) ||
+ (TeamInInstance == HORDE && int32(data->mapId) != go->moTransport.SpawnMap))
return entry;
return 0;
case NPC_IGB_MURADIN_BRONZEBEARD: