aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2017-08-26 13:14:25 +0200
committerShauren <shauren.trinity@gmail.com>2020-08-23 17:00:59 +0200
commit27806eeac9d2588d2f7a3b8a0852d45b15a6a241 (patch)
tree21efaf592786e3c07fafdd1d7ff4b7bacf597081 /src
parent5d61618955ec3e0efe13fe01899b7dcf9fd13e56 (diff)
Core/Spawn: Move spawn group state management from sObjectMgr to the Map object, which makes it actually function as intended with instances. Woops.
(cherry picked from commit f279207d482b886fc8b049e94b46653325ec4d2d)
Diffstat (limited to 'src')
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp4
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp133
-rw-r--r--src/server/game/Globals/ObjectMgr.h4
-rw-r--r--src/server/game/Grids/ObjectGridLoader.cpp17
-rw-r--r--src/server/game/Instances/InstanceScript.cpp16
-rw-r--r--src/server/game/Maps/Map.cpp142
-rw-r--r--src/server/game/Maps/Map.h7
-rw-r--r--src/server/game/Maps/SpawnData.h1
-rw-r--r--src/server/scripts/Commands/cs_gobject.cpp2
-rw-r--r--src/server/scripts/Commands/cs_list.cpp4
-rw-r--r--src/server/scripts/Commands/cs_npc.cpp8
11 files changed, 182 insertions, 156 deletions
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index 94ebacb2ab2..23ab23b3860 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -2117,7 +2117,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
bool const force = ((e.action.groupSpawn.spawnflags & SMARTAI_SPAWN_FLAGS::SMARTAI_SPAWN_FLAG_FORCE_SPAWN) != 0);
// Instant spawn
- sObjectMgr->SpawnGroupSpawn(e.action.groupSpawn.groupId, GetBaseObject()->GetMap(), ignoreRespawn, force);
+ GetBaseObject()->GetMap()->SpawnGroupSpawn(e.action.groupSpawn.groupId, ignoreRespawn, force);
}
else
{
@@ -2159,7 +2159,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
bool const deleteRespawnTimes = ((e.action.groupSpawn.spawnflags & SMARTAI_SPAWN_FLAGS::SMARTAI_SPAWN_FLAG_NOSAVE_RESPAWN) != 0);
// Instant spawn
- sObjectMgr->SpawnGroupDespawn(e.action.groupSpawn.groupId, GetBaseObject()->GetMap(), deleteRespawnTimes);
+ GetBaseObject()->GetMap()->SpawnGroupDespawn(e.action.groupSpawn.groupId, deleteRespawnTimes);
}
else
{
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 0a64d4b2f4f..90dde6d7f78 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -2543,7 +2543,6 @@ void ObjectMgr::LoadSpawnGroupTemplates()
TC_LOG_ERROR("server.loading", "System spawn group %u (%s) has invalid manual spawn flag. Ignored.", groupId, group.name.c_str());
}
group.flags = SpawnGroupFlags(flags);
- group.isActive = !(group.flags & SPAWNGROUP_FLAG_MANUAL_SPAWN);
} while (result->NextRow());
}
@@ -2555,7 +2554,6 @@ void ObjectMgr::LoadSpawnGroupTemplates()
data.name = "Default Group";
data.mapId = 0;
data.flags = SPAWNGROUP_FLAG_SYSTEM;
- data.isActive = true;
}
if (_spawnGroupDataStore.find(1) == _spawnGroupDataStore.end())
{
@@ -2565,7 +2563,6 @@ void ObjectMgr::LoadSpawnGroupTemplates()
data.name = "Legacy Group";
data.mapId = 0;
data.flags = SpawnGroupFlags(SPAWNGROUP_FLAG_SYSTEM | SPAWNGROUP_FLAG_COMPATIBILITY_MODE);
- data.isActive = true;
}
if (result)
@@ -7106,136 +7103,6 @@ uint64 ObjectMgr::GenerateGameObjectSpawnId()
return _gameObjectSpawnId++;
}
-bool ObjectMgr::SpawnGroupSpawn(uint32 groupId, Map* map, bool ignoreRespawn, bool force, std::vector<WorldObject*>* spawnedObjects)
-{
- auto itr = _spawnGroupDataStore.find(groupId);
- if (itr == _spawnGroupDataStore.end() || itr->second.flags & SPAWNGROUP_FLAG_SYSTEM)
- {
- TC_LOG_ERROR("maps", "Tried to spawn non-existing (or system) spawn group %u. Blocked.", groupId);
- return false;
- }
-
- if (!map)
- {
- TC_LOG_ERROR("maps", "Tried to spawn creature group %u, but no map was supplied. Blocked.", groupId);
- return false;
- }
-
- if (itr->second.mapId != map->GetId())
- {
- TC_LOG_ERROR("maps", "Tried to spawn creature group %u, but supplied map is %u, creature group has map %u. Blocked.", groupId, map->GetId(), itr->second.mapId);
- return false;
- }
-
- for (auto& pair : GetSpawnDataForGroup(groupId))
- {
- SpawnData const* data = pair.second;
- ASSERT(itr->second.mapId == data->spawnPoint.GetMapId());
- // Check if there's already an instance spawned
- if (!force)
- if (WorldObject* obj = map->GetWorldObjectBySpawnId(data->type, data->spawnId))
- if ((data->type != SPAWN_TYPE_CREATURE) || obj->ToCreature()->IsAlive())
- continue;
-
- time_t respawnTime = map->GetRespawnTime(data->type, data->spawnId);
- if (respawnTime && respawnTime > time(NULL))
- {
- if (!force && !ignoreRespawn)
- continue;
-
- // we need to remove the respawn time, otherwise we'd end up double spawning
- map->RemoveRespawnTime(data->type, data->spawnId, false);
- }
-
- // don't spawn if the grid isn't loaded (will be handled in grid loader)
- if (!map->IsGridLoaded(data->spawnPoint))
- continue;
-
- // Everything OK, now do the actual (re)spawn
- switch (data->type)
- {
- case SPAWN_TYPE_CREATURE:
- {
- Creature* creature = new Creature();
- if (!creature->LoadFromDB(data->spawnId, map, true, force))
- delete creature;
- else if (spawnedObjects)
- spawnedObjects->push_back(creature);
- break;
- }
- case SPAWN_TYPE_GAMEOBJECT:
- {
- GameObject* gameobject = new GameObject();
- if (!gameobject->LoadFromDB(data->spawnId, map, true))
- delete gameobject;
- else if (spawnedObjects)
- spawnedObjects->push_back(gameobject);
- break;
- }
- default:
- ASSERT(false, "Invalid spawn type %u with spawnId " UI64FMTD, uint32(data->type), data->spawnId);
- return false;
- }
- }
- itr->second.isActive = true; // start processing respawns for the group
- return true;
-}
-
-bool ObjectMgr::SpawnGroupDespawn(uint32 groupId, Map* map, bool deleteRespawnTimes)
-{
- auto itr = _spawnGroupDataStore.find(groupId);
- if (itr == _spawnGroupDataStore.end() || itr->second.flags & SPAWNGROUP_FLAG_SYSTEM)
- {
- TC_LOG_ERROR("maps", "Tried to despawn non-existing (or system) spawn group %u. Blocked.", groupId);
- return false;
- }
-
- if (!map)
- {
- TC_LOG_ERROR("maps", "Tried to despawn creature group %u, but no map was supplied. Blocked.", groupId);
- return false;
- }
-
- if (itr->second.mapId != map->GetId())
- {
- TC_LOG_ERROR("maps", "Tried to despawn creature group %u, but supplied map is %u, creature group has map %u. Blocked.", groupId, map->GetId(), itr->second.mapId);
- return false;
- }
-
- std::vector<WorldObject*> toUnload; // unload after iterating, otherwise iterator invalidation
- for (auto const& pair : GetSpawnDataForGroup(groupId))
- {
- SpawnData const* data = pair.second;
- if (deleteRespawnTimes)
- map->RemoveRespawnTime(data->type, data->spawnId);
- switch (data->type)
- {
- case SPAWN_TYPE_CREATURE:
- {
- auto bounds = map->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 = map->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;
- }
- }
- // now do the actual despawning
- for (WorldObject* obj : toUnload)
- obj->AddObjectToRemoveList();
- itr->second.isActive = false; // stop processing respawns for the group, too
- return true;
-}
-
void ObjectMgr::LoadGameObjectLocales()
{
uint32 oldMSTime = getMSTime();
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index 181a191ba92..43778ad4298 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -1374,11 +1374,7 @@ class TC_GAME_API ObjectMgr
ObjectGuid::LowType GenerateCreatureSpawnId();
ObjectGuid::LowType GenerateGameObjectSpawnId();
- bool SpawnGroupSpawn(uint32 groupId, Map* map, bool ignoreRespawn = false, bool force = false, std::vector<WorldObject*>* spawnedObjects = nullptr);
- bool SpawnGroupDespawn(uint32 groupId, Map* map, bool deleteRespawnTimes = false);
SpawnGroupTemplateData const* GetSpawnGroupData(uint32 groupId) const { auto it = _spawnGroupDataStore.find(groupId); return it != _spawnGroupDataStore.end() ? &it->second : nullptr; }
- void SetSpawnGroupActive(uint32 groupId, bool state) { auto it = _spawnGroupDataStore.find(groupId); if (it != _spawnGroupDataStore.end()) it->second.isActive = state; }
- bool IsSpawnGroupActive(uint32 groupId) const { auto it = _spawnGroupDataStore.find(groupId); return (it != _spawnGroupDataStore.end()) && it->second.isActive; }
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); }
diff --git a/src/server/game/Grids/ObjectGridLoader.cpp b/src/server/game/Grids/ObjectGridLoader.cpp
index 7b2ead0e1cc..bf33abacea5 100644
--- a/src/server/game/Grids/ObjectGridLoader.cpp
+++ b/src/server/game/Grids/ObjectGridLoader.cpp
@@ -135,13 +135,18 @@ void LoadHelper(CellGuidSet const& guid_set, CellCoord &cell, GridRefManager<T>
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_MANUAL_SPAWN) && !group->isActive)
- continue;
+ if (!(group->flags & SPAWNGROUP_FLAG_SYSTEM))
+ if (!map->IsSpawnGroupActive(group->groupId))
+ {
+ delete obj;
+ continue;
+ }
// If script is blocking spawn, don't spawn but queue for a re-check in a little bit
if (!(group->flags & SPAWNGROUP_FLAG_COMPATIBILITY_MODE) && !sScriptMgr->CanSpawn(guid, cdata->id, cdata, map))
{
map->SaveRespawnTime(SPAWN_TYPE_CREATURE, guid, cdata->id, time(NULL) + urand(4,7), map->GetZoneId(PhasingHandler::GetEmptyPhaseShift(), cdata->spawnPoint), Trinity::ComputeGridCoord(cdata->spawnPoint.GetPositionX(), cdata->spawnPoint.GetPositionY()).GetId(), false);
+ delete obj;
continue;
}
}
@@ -150,8 +155,12 @@ void LoadHelper(CellGuidSet const& guid_set, CellCoord &cell, GridRefManager<T>
// 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_MANUAL_SPAWN) && !godata->spawnGroupData->isActive)
- continue;
+ if (!(godata->spawnGroupData->flags & SPAWNGROUP_FLAG_SYSTEM))
+ if (!map->IsSpawnGroupActive(godata->spawnGroupData->groupId))
+ {
+ delete obj;
+ continue;
+ }
}
if (!obj->LoadFromDB(guid, map, false, false))
diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp
index c3cccd75d63..e120f3457a0 100644
--- a/src/server/game/Instances/InstanceScript.cpp
+++ b/src/server/game/Instances/InstanceScript.cpp
@@ -266,13 +266,13 @@ void InstanceScript::UpdateSpawnGroups()
{
uint32 const groupId = pair.first;
bool const doSpawn = (pair.second == SPAWN);
- if (sObjectMgr->IsSpawnGroupActive(groupId) == doSpawn)
+ if (instance->IsSpawnGroupActive(groupId) == doSpawn)
continue; // nothing to do here
// if we should spawn group, then spawn it...
if (doSpawn)
- sObjectMgr->SpawnGroupSpawn(groupId, instance);
+ instance->SpawnGroupSpawn(groupId);
else // otherwise, set it as inactive so it no longer respawns (but don't despawn it)
- sObjectMgr->SetSpawnGroupActive(groupId, false);
+ instance->SetSpawnGroupActive(groupId, false);
}
}
@@ -350,7 +350,7 @@ bool InstanceScript::SetBossState(uint32 id, EncounterState state)
if (bossInfo->state == TO_BE_DECIDED) // loading
{
bossInfo->state = state;
- TC_LOG_DEBUG("scripts", "InstanceScript: Initialize boss %u state as %u.", id, (uint32)state);
+ TC_LOG_DEBUG("scripts", "InstanceScript: Initialize boss %u state as %s (map %u, %u).", id, GetBossStateName(state), instance->GetId(), instance->GetInstanceId());
return false;
}
else
@@ -358,6 +358,12 @@ bool InstanceScript::SetBossState(uint32 id, EncounterState state)
if (bossInfo->state == state)
return false;
+ if (bossInfo->state == DONE)
+ {
+ TC_LOG_ERROR("map", "InstanceScript: Tried to set instance state from %s back to %s for map %u, instance id %u. Blocked!", GetBossStateName(bossInfo->state), GetBossStateName(state), instance->GetId(), instance->GetInstanceId());
+ return false;
+ }
+
if (state == DONE)
for (GuidSet::iterator i = bossInfo->minion.begin(); i != bossInfo->minion.end(); ++i)
if (Creature* minion = instance->GetCreature(*i))
@@ -815,7 +821,7 @@ void InstanceScript::UpdatePhasing()
PhasingHandler::SendToPlayer(player);
}
-std::string InstanceScript::GetBossStateName(uint8 state)
+/*static*/ std::string InstanceScript::GetBossStateName(uint8 state)
{
// See enum EncounterState in InstanceScript.h
switch (state)
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 6c3794d16db..79136e3f663 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -3603,6 +3603,148 @@ void Map::ApplyDynamicModeRespawnScaling(WorldObject const* obj, ObjectGuid::Low
respawnDelay = std::max<uint32>(ceil(respawnDelay * adjustFactor), timeMinimum);
}
+SpawnGroupTemplateData const* Map::GetSpawnGroupData(uint32 groupId) const
+{
+ SpawnGroupTemplateData const* data = sObjectMgr->GetSpawnGroupData(groupId);
+ if (data && data->mapId == GetId())
+ return data;
+ return nullptr;
+}
+
+bool Map::SpawnGroupSpawn(uint32 groupId, bool ignoreRespawn, bool force, std::vector<WorldObject*>* spawnedObjects)
+{
+ SpawnGroupTemplateData const* groupData = GetSpawnGroupData(groupId);
+ if (!groupData || groupData->flags & SPAWNGROUP_FLAG_SYSTEM)
+ {
+ TC_LOG_ERROR("maps", "Tried to spawn non-existing (or system) spawn group %u on map %u. Blocked.", groupId, GetId());
+ return false;
+ }
+
+ 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 && respawnTime > time(NULL))
+ {
+ if (!force && !ignoreRespawn)
+ continue;
+
+ // we need to remove the respawn time, otherwise we'd end up double spawning
+ RemoveRespawnTime(data->type, data->spawnId, false);
+ }
+
+ // 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
+ switch (data->type)
+ {
+ case SPAWN_TYPE_CREATURE:
+ {
+ Creature* creature = new Creature();
+ if (!creature->LoadFromDB(data->spawnId, this, true, force))
+ delete creature;
+ else if (spawnedObjects)
+ spawnedObjects->push_back(creature);
+ break;
+ }
+ case SPAWN_TYPE_GAMEOBJECT:
+ {
+ GameObject* gameobject = new GameObject();
+ if (!gameobject->LoadFromDB(data->spawnId, this, true))
+ delete gameobject;
+ else if (spawnedObjects)
+ spawnedObjects->push_back(gameobject);
+ break;
+ }
+ default:
+ ASSERT(false, "Invalid spawn type %u with spawnId " UI64FMTD, uint32(data->type), data->spawnId);
+ return false;
+ }
+ }
+ SetSpawnGroupActive(groupId, true); // start processing respawns for the group
+ return true;
+}
+
+bool Map::SpawnGroupDespawn(uint32 groupId, bool deleteRespawnTimes)
+{
+ SpawnGroupTemplateData const* groupData = GetSpawnGroupData(groupId);
+ if (!groupData || groupData->flags & SPAWNGROUP_FLAG_SYSTEM)
+ {
+ TC_LOG_ERROR("maps", "Tried to despawn non-existing (or system) spawn group %u on map %u. Blocked.", groupId, GetId());
+ return false;
+ }
+
+ std::vector<WorldObject*> toUnload; // unload after iterating, otherwise iterator invalidation
+ for (auto const& pair : sObjectMgr->GetSpawnDataForGroup(groupId))
+ {
+ SpawnData const* data = pair.second;
+ ASSERT(groupData->mapId == data->spawnPoint.GetMapId());
+ 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;
+ }
+ }
+ // now do the actual despawning
+ for (WorldObject* obj : toUnload)
+ obj->AddObjectToRemoveList();
+ SetSpawnGroupActive(groupId, false); // stop processing respawns for the group, too
+ return true;
+}
+
+void Map::SetSpawnGroupActive(uint32 groupId, bool state)
+{
+ SpawnGroupTemplateData const* const data = GetSpawnGroupData(groupId);
+ if (!data || data->flags & SPAWNGROUP_FLAG_SYSTEM)
+ {
+ TC_LOG_ERROR("maps", "Tried to set non-existing (or system) spawn group %u to %s on map %u. Blocked.", groupId, state ? "active" : "inactive", GetId());
+ return;
+ }
+ if (state != !(data->flags & SPAWNGROUP_FLAG_MANUAL_SPAWN)) // toggled
+ _toggledSpawnGroupIds.insert(groupId);
+ else
+ _toggledSpawnGroupIds.erase(groupId);
+}
+
+bool Map::IsSpawnGroupActive(uint32 groupId) const
+{
+ SpawnGroupTemplateData const* const data = GetSpawnGroupData(groupId);
+ if (!data)
+ {
+ TC_LOG_WARN("maps", "Tried to query state of non-existing spawn group %u on map %u.", groupId, GetId());
+ return false;
+ }
+ if (data->flags & SPAWNGROUP_FLAG_SYSTEM)
+ return true;
+ return (_toggledSpawnGroupIds.find(groupId) != _toggledSpawnGroupIds.end()) != !(data->flags & SPAWNGROUP_FLAG_MANUAL_SPAWN);
+}
+
void Map::DelayedUpdate(uint32 t_diff)
{
for (_transportsUpdateIter = _transports.begin(); _transportsUpdateIter != _transports.end();)
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 7b3426c8d6e..d071aa0d404 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -823,6 +823,12 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
RemoveRespawnTime(info, doRespawn, dbTrans);
}
+ SpawnGroupTemplateData const* GetSpawnGroupData(uint32 groupId) const;
+ bool SpawnGroupSpawn(uint32 groupId, bool ignoreRespawn = false, bool force = false, std::vector<WorldObject*>* spawnedObjects = nullptr);
+ bool SpawnGroupDespawn(uint32 groupId, bool deleteRespawnTimes = false);
+ void SetSpawnGroupActive(uint32 groupId, bool state);
+ bool IsSpawnGroupActive(uint32 groupId) const;
+
private:
// Type specific code for add/remove to/from grid
template<class T>
@@ -857,6 +863,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
RespawnInfoMap _gameObjectRespawnTimesBySpawnId;
RespawnInfoMap& GetRespawnMapForType(SpawnObjectType type) { return (type == SPAWN_TYPE_GAMEOBJECT) ? _gameObjectRespawnTimesBySpawnId : _creatureRespawnTimesBySpawnId; }
RespawnInfoMap const& GetRespawnMapForType(SpawnObjectType type) const { return (type == SPAWN_TYPE_GAMEOBJECT) ? _gameObjectRespawnTimesBySpawnId : _creatureRespawnTimesBySpawnId; }
+ std::unordered_set<uint32> _toggledSpawnGroupIds;
uint32 _respawnCheckTimer;
std::unordered_map<uint32, uint32> _zonePlayerCountMap;
diff --git a/src/server/game/Maps/SpawnData.h b/src/server/game/Maps/SpawnData.h
index 5d0c8d17e9d..34c250ec1f3 100644
--- a/src/server/game/Maps/SpawnData.h
+++ b/src/server/game/Maps/SpawnData.h
@@ -56,7 +56,6 @@ struct SpawnGroupTemplateData
std::string name;
uint32 mapId;
SpawnGroupFlags flags;
- bool isActive;
};
struct SpawnData
diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp
index ec5eac82672..4f15fb08a9e 100644
--- a/src/server/scripts/Commands/cs_gobject.cpp
+++ b/src/server/scripts/Commands/cs_gobject.cpp
@@ -659,7 +659,7 @@ public:
if (object->ToGameObject() && object->ToGameObject()->GetGameObjectData() && object->ToGameObject()->GetGameObjectData()->spawnGroupData->groupId)
{
SpawnGroupTemplateData const* groupData = object->ToGameObject()->GetGameObjectData()->spawnGroupData;
- handler->PSendSysMessage(LANG_SPAWNINFO_GROUP_ID, groupData->name.c_str(), groupData->groupId, groupData->flags, groupData->isActive);
+ handler->PSendSysMessage(LANG_SPAWNINFO_GROUP_ID, groupData->name.c_str(), groupData->groupId, groupData->flags, object->GetMap()->IsSpawnGroupActive(groupData->groupId));
}
if (object->ToGameObject())
handler->PSendSysMessage(LANG_SPAWNINFO_COMPATIBILITY_MODE, object->ToGameObject()->GetRespawnCompatibilityMode());
diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp
index e7666490ba8..ea4eb09669f 100644
--- a/src/server/scripts/Commands/cs_list.cpp
+++ b/src/server/scripts/Commands/cs_list.cpp
@@ -715,7 +715,7 @@ public:
uint32 gridX = ri->gridId % MAX_NUMBER_OF_GRIDS;
std::string respawnTime = ri->respawnTime > time(NULL) ? secsToTimeString(uint64(ri->respawnTime - time(NULL)), true) : stringOverdue;
- handler->PSendSysMessage(UI64FMTD " | %u | [%02u,%02u] | %s (%u) | %s", ri->spawnId, ri->entry, gridX, gridY, GetZoneName(ri->zoneId, handler->GetSessionDbcLocale()), ri->zoneId, data->spawnGroupData->isActive ? respawnTime.c_str() : "inactive");
+ handler->PSendSysMessage(UI64FMTD " | %u | [%02u,%02u] | %s (%u) | %s", ri->spawnId, ri->entry, gridX, gridY, GetZoneName(ri->zoneId, handler->GetSessionDbcLocale()), ri->zoneId, map->IsSpawnGroupActive(data->spawnGroupData->groupId) ? respawnTime.c_str() : "inactive");
}
respawns.clear();
@@ -736,7 +736,7 @@ public:
uint32 gridX = ri->gridId % MAX_NUMBER_OF_GRIDS;
std::string respawnTime = ri->respawnTime > time(NULL) ? secsToTimeString(uint64(ri->respawnTime - time(NULL)), true) : stringOverdue;
- handler->PSendSysMessage(UI64FMTD " | %u | [% 02u, % 02u] | %s (%u) | %s", ri->spawnId, ri->entry, gridX, gridY, GetZoneName(ri->zoneId, handler->GetSessionDbcLocale()), ri->zoneId, data->spawnGroupData->isActive ? respawnTime.c_str() : "inactive");
+ handler->PSendSysMessage(UI64FMTD " | %u | [% 02u, % 02u] | %s (%u) | %s", ri->spawnId, ri->entry, gridX, gridY, GetZoneName(ri->zoneId, handler->GetSessionDbcLocale()), ri->zoneId, map->IsSpawnGroupActive(data->spawnGroupData->groupId) ? respawnTime.c_str() : "inactive");
}
return true;
}
diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp
index e420bdfbf16..4c1eb90bcfa 100644
--- a/src/server/scripts/Commands/cs_npc.cpp
+++ b/src/server/scripts/Commands/cs_npc.cpp
@@ -236,7 +236,7 @@ bool HandleNpcSpawnGroup(ChatHandler* handler, char const* args)
Player* player = handler->GetSession()->GetPlayer();
std::vector <WorldObject*> creatureList;
- if (!sObjectMgr->SpawnGroupSpawn(groupId, player->GetMap(), ignoreRespawn, force, &creatureList))
+ if (!player->GetMap()->SpawnGroupSpawn(groupId, ignoreRespawn, force, &creatureList))
{
handler->PSendSysMessage(LANG_SPAWNGROUP_BADGROUP, groupId);
handler->SetSentErrorMessage(true);
@@ -276,7 +276,7 @@ bool HandleNpcDespawnGroup(ChatHandler* handler, char const* args)
Player* player = handler->GetSession()->GetPlayer();
- if (!sObjectMgr->SpawnGroupDespawn(groupId, player->GetMap(), deleteRespawnTimes))
+ if (!player->GetMap()->SpawnGroupDespawn(groupId, deleteRespawnTimes))
{
handler->PSendSysMessage(LANG_SPAWNGROUP_BADGROUP, groupId);
handler->SetSentErrorMessage(true);
@@ -832,8 +832,8 @@ public:
handler->PSendSysMessage(LANG_NPCINFO_CHAR, std::to_string(target->GetSpawnId()).c_str(), target->GetGUID().ToString().c_str(), faction, std::to_string(npcflags).c_str(), Entry, displayid, nativeid);
if (target->GetCreatureData() && target->GetCreatureData()->spawnGroupData->groupId)
{
- if (SpawnGroupTemplateData const* groupData = target->GetCreatureData()->spawnGroupData)
- handler->PSendSysMessage(LANG_SPAWNINFO_GROUP_ID, groupData->name.c_str(), groupData->groupId, groupData->flags, groupData->isActive);
+ SpawnGroupTemplateData const* const groupData = target->GetCreatureData()->spawnGroupData;
+ handler->PSendSysMessage(LANG_SPAWNINFO_GROUP_ID, groupData->name.c_str(), groupData->groupId, groupData->flags, target->GetMap()->IsSpawnGroupActive(groupData->groupId));
}
handler->PSendSysMessage(LANG_SPAWNINFO_COMPATIBILITY_MODE, target->GetRespawnCompatibilityMode());
handler->PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel());