diff --git a/Source/Game/AI/SmartScripts/SmartScript.cs b/Source/Game/AI/SmartScripts/SmartScript.cs index 2b071e653..6f1cfd54d 100644 --- a/Source/Game/AI/SmartScripts/SmartScript.cs +++ b/Source/Game/AI/SmartScripts/SmartScript.cs @@ -2060,7 +2060,7 @@ namespace Game.AI bool force = ((e.Action.groupSpawn.spawnflags & (uint)SmartAiSpawnFlags.ForceSpawn) != 0); // Instant spawn - Global.ObjectMgr.SpawnGroupSpawn(e.Action.groupSpawn.groupId, GetBaseObject().GetMap(), ignoreRespawn, force); + GetBaseObject().GetMap().SpawnGroupSpawn(e.Action.groupSpawn.groupId, ignoreRespawn, force); } else { @@ -2102,7 +2102,7 @@ namespace Game.AI bool deleteRespawnTimes = ((e.Action.groupSpawn.spawnflags & (uint)SmartAiSpawnFlags.NosaveRespawn) != 0); // Instant spawn - Global.ObjectMgr.SpawnGroupDespawn(e.Action.groupSpawn.groupId, GetBaseObject().GetMap(), deleteRespawnTimes); + GetBaseObject().GetMap().SpawnGroupSpawn(e.Action.groupSpawn.groupId, deleteRespawnTimes); } else { diff --git a/Source/Game/Chat/Commands/GameObjectCommands.cs b/Source/Game/Chat/Commands/GameObjectCommands.cs index 3d12faf21..ab135763d 100644 --- a/Source/Game/Chat/Commands/GameObjectCommands.cs +++ b/Source/Game/Chat/Commands/GameObjectCommands.cs @@ -179,7 +179,7 @@ namespace Game.Chat if (obj.IsGameObject() && obj.ToGameObject().GetGameObjectData() != null && obj.ToGameObject().GetGameObjectData().spawnGroupData.groupId != 0) { SpawnGroupTemplateData groupData = obj.ToGameObject().GetGameObjectData().spawnGroupData; - handler.SendSysMessage(CypherStrings.SpawninfoGroupId, groupData.name, groupData.groupId, groupData.flags, groupData.isActive); + handler.SendSysMessage(CypherStrings.SpawninfoGroupId, groupData.name, groupData.groupId, groupData.flags, obj.GetMap().IsSpawnGroupActive(groupData.groupId)); } if (obj.IsGameObject()) handler.SendSysMessage(CypherStrings.SpawninfoCompatibilityMode, obj.ToGameObject().GetRespawnCompatibilityMode()); diff --git a/Source/Game/Chat/Commands/ListCommands.cs b/Source/Game/Chat/Commands/ListCommands.cs index 907877f76..885260a80 100644 --- a/Source/Game/Chat/Commands/ListCommands.cs +++ b/Source/Game/Chat/Commands/ListCommands.cs @@ -603,7 +603,7 @@ namespace Game.Chat.Commands uint gridX = ri.gridId % MapConst.MaxGrids; string respawnTime = ri.respawnTime > Time.UnixTime ? Time.secsToTimeString((ulong)(ri.respawnTime - Time.UnixTime), true) : stringOverdue; - handler.SendSysMessage($"{ri.spawnId} | {ri.entry} | [{gridX},{gridY}] | {GetZoneName(ri.zoneId, handler.GetSessionDbcLocale())} ({ri.zoneId}) | {(data.spawnGroupData.isActive ? respawnTime : "inactive")}"); + handler.SendSysMessage($"{ri.spawnId} | {ri.entry} | [{gridX},{gridY}] | {GetZoneName(ri.zoneId, handler.GetSessionDbcLocale())} ({ri.zoneId}) | {(map.IsSpawnGroupActive(data.spawnGroupData.groupId) ? respawnTime : "inactive")}"); } respawns.Clear(); @@ -626,7 +626,7 @@ namespace Game.Chat.Commands uint gridX = ri.gridId % MapConst.MaxGrids; string respawnTime = ri.respawnTime > Time.UnixTime ? Time.secsToTimeString((ulong)(ri.respawnTime - Time.UnixTime), true) : stringOverdue; - handler.SendSysMessage($"{ri.spawnId} | {ri.entry} | [{gridX},{gridY}] | {GetZoneName(ri.zoneId, handler.GetSessionDbcLocale())} ({ri.zoneId}) | {(data.spawnGroupData.isActive ? respawnTime : "inactive")}"); + handler.SendSysMessage($"{ri.spawnId} | {ri.entry} | [{gridX},{gridY}] | {GetZoneName(ri.zoneId, handler.GetSessionDbcLocale())} ({ri.zoneId}) | {(map.IsSpawnGroupActive(data.spawnGroupData.groupId) ? respawnTime : "inactive")}"); } return true; } diff --git a/Source/Game/Chat/Commands/NPCCommands.cs b/Source/Game/Chat/Commands/NPCCommands.cs index d557563b5..0a2f66661 100644 --- a/Source/Game/Chat/Commands/NPCCommands.cs +++ b/Source/Game/Chat/Commands/NPCCommands.cs @@ -59,7 +59,7 @@ namespace Game.Chat Player player = handler.GetSession().GetPlayer(); - if (!Global.ObjectMgr.SpawnGroupDespawn(groupId, player.GetMap(), deleteRespawnTimes)) + if (!player.GetMap().SpawnGroupDespawn(groupId, deleteRespawnTimes)) { handler.SendSysMessage(CypherStrings.SpawngroupBadgroup, groupId); return false; @@ -142,8 +142,7 @@ namespace Game.Chat if (target.GetCreatureData() != null && target.GetCreatureData().spawnGroupData.groupId != 0) { SpawnGroupTemplateData groupData = target.GetCreatureData().spawnGroupData; - if (groupData != null) - handler.SendSysMessage(CypherStrings.SpawninfoGroupId, groupData.name, groupData.groupId, groupData.flags, groupData.isActive); + handler.SendSysMessage(CypherStrings.SpawninfoGroupId, groupData.name, groupData.groupId, groupData.flags, target.GetMap().IsSpawnGroupActive(groupData.groupId)); } handler.SendSysMessage(CypherStrings.SpawninfoCompatibilityMode, target.GetRespawnCompatibilityMode()); handler.SendSysMessage(CypherStrings.NpcinfoLevel, target.GetLevel()); @@ -448,7 +447,7 @@ namespace Game.Chat Player player = handler.GetSession().GetPlayer(); List creatureList = new List(); - if (!Global.ObjectMgr.SpawnGroupSpawn(groupId, player.GetMap(), ignoreRespawn, force, creatureList)) + if (!player.GetMap().SpawnGroupSpawn(groupId, ignoreRespawn, force, creatureList)) { handler.SendSysMessage(CypherStrings.SpawngroupBadgroup, groupId); return false; diff --git a/Source/Game/Globals/ObjectManager.cs b/Source/Game/Globals/ObjectManager.cs index 8d443aa3a..4c2c9cb32 100644 --- a/Source/Game/Globals/ObjectManager.cs +++ b/Source/Game/Globals/ObjectManager.cs @@ -5280,7 +5280,6 @@ namespace Game Log.outError(LogFilter.ServerLoading, $"System spawn group {groupId} ({group.name}) has invalid manual spawn flag. Ignored."); } group.flags = flags; - group.isActive = !group.flags.HasAnyFlag(SpawnGroupFlags.ManualSpawn); _spawnGroupDataStorage[groupId] = group; } while (result.NextRow()); @@ -5294,7 +5293,6 @@ namespace Game data.name = "Default Group"; data.mapId = 0; data.flags = SpawnGroupFlags.System; - data.isActive = true; _spawnGroupDataStorage[0] = data; } @@ -5307,7 +5305,6 @@ namespace Game data.name = "Legacy Group"; data.mapId = 0; data.flags = SpawnGroupFlags.System | SpawnGroupFlags.CompatibilityMode; - data.isActive = true; _spawnGroupDataStorage[1] = data; } @@ -5449,137 +5446,6 @@ namespace Game Cypher.Assert(false, $"Spawn data ({data.type},{data.spawnId}) being removed is member of spawn group {data.spawnGroupData.groupId}, but not actually listed in the lookup table for that group!"); } - public bool SpawnGroupSpawn(uint groupId, Map map, bool ignoreRespawn = false, bool force = false, List spawnedObjects = null) - { - var spawnGroup = _spawnGroupDataStorage.LookupByKey(groupId); - if (spawnGroup == null || spawnGroup.flags.HasAnyFlag(SpawnGroupFlags.System)) - { - Log.outError(LogFilter.Maps, $"Tried to spawn non-existing (or system) spawn group {groupId}. Blocked."); - return false; - } - - if (!map) - { - Log.outError(LogFilter.Maps, $"Tried to spawn creature group {groupId}, but no map was supplied. Blocked."); - return false; - } - - if (spawnGroup.mapId != map.GetId()) - { - Log.outError(LogFilter.Maps, $"Tried to spawn creature group {groupId}, but supplied map is {map.GetId()}, creature group has map {spawnGroup.mapId}. Blocked."); - return false; - } - - foreach (var data in _spawnGroupMapStorage.LookupByKey(groupId)) - { - Cypher.Assert(spawnGroup.mapId == data.spawnPoint.GetMapId()); - // Check if there's already an instance spawned - if (!force) - { - WorldObject obj = map.GetWorldObjectBySpawnId(data.type, data.spawnId); - if (obj != null) - if ((data.type != SpawnObjectType.Creature) || obj.ToCreature().IsAlive()) - continue; - } - - long respawnTime = map.GetRespawnTime(data.type, data.spawnId); - if (respawnTime != 0 && respawnTime > Time.UnixTime) - { - 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 SpawnObjectType.Creature: - { - Creature creature = new Creature(); - if (!creature.LoadFromDB(data.spawnId, map, true, force)) - creature.Dispose(); - else if (spawnedObjects != null) - spawnedObjects.Add(creature); - break; - } - case SpawnObjectType.GameObject: - { - GameObject gameobject = new GameObject(); - if (!gameobject.LoadFromDB(data.spawnId, map, true)) - gameobject.Dispose(); - else if (spawnedObjects != null) - spawnedObjects.Add(gameobject); - break; - } - default: - Cypher.Assert(false, $"Invalid spawn type {data.type} with spawnId {data.spawnId}"); - return false; - } - } - spawnGroup.isActive = true; // start processing respawns for the group - return true; - } - public bool SpawnGroupDespawn(uint groupId, Map map, bool deleteRespawnTimes) - { - var spawnGroup = _spawnGroupDataStorage.LookupByKey(groupId); - if (spawnGroup == null || spawnGroup.flags.HasAnyFlag(SpawnGroupFlags.System)) - { - Log.outError(LogFilter.Maps, $"Tried to despawn non-existing (or system) spawn group {groupId}. Blocked."); - return false; - } - - if (!map) - { - Log.outError(LogFilter.Maps, $"Tried to despawn creature group {groupId}, but no map was supplied. Blocked."); - return false; - } - - if (spawnGroup.mapId != map.GetId()) - { - Log.outError(LogFilter.Maps, $"Tried to despawn creature group {groupId}, but supplied map is {map.GetId()}, creature group has map {spawnGroup.mapId}. Blocked."); - return false; - } - - List toUnload = new List(); // unload after iterating, otherwise iterator invalidation - foreach (var data in _spawnGroupMapStorage.LookupByKey(groupId)) - { - if (deleteRespawnTimes) - map.RemoveRespawnTime(data.type, data.spawnId); - switch (data.type) - { - case SpawnObjectType.Creature: - { - var bounds = map.GetCreatureBySpawnIdStore().LookupByKey(data.spawnId); - foreach (var creature in bounds) - toUnload.Add(creature); - break; - } - case SpawnObjectType.GameObject: - { - var bounds = map.GetGameObjectBySpawnIdStore().LookupByKey(data.spawnId); - foreach (var go in bounds) - toUnload.Add(go); - break; - } - default: - Cypher.Assert(false, $"Invalid spawn type {data.type} in spawn data with spawnId {data.spawnId}."); - return false; - } - } - - // now do the actual despawning - foreach (WorldObject obj in toUnload) - obj.AddObjectToRemoveList(); - - spawnGroup.isActive = false; // stop processing respawns for the group, too - return true; - } public InstanceTemplate GetInstanceTemplate(uint mapID) { @@ -5598,20 +5464,10 @@ namespace Game return _dungeonEncounterStorage.LookupByKey(MathFunctions.MakePair64(mapId, (uint)difficulty)); } public bool IsTransportMap(uint mapId) { return _transportMaps.Contains((ushort)mapId); } - SpawnGroupTemplateData GetSpawnGroupData(uint groupId) { return _spawnGroupDataStorage.LookupByKey(groupId); } - public void SetSpawnGroupActive(uint groupId, bool state) - { - var spawnGroup = _spawnGroupDataStorage.LookupByKey(groupId); - if (spawnGroup != null) - spawnGroup.isActive = state; - } - public bool IsSpawnGroupActive(uint groupId) - { - var spawnGroup = _spawnGroupDataStorage.LookupByKey(groupId); - return (spawnGroup != null) && spawnGroup.isActive; - } + public SpawnGroupTemplateData GetSpawnGroupData(uint groupId) { return _spawnGroupDataStorage.LookupByKey(groupId); } public SpawnGroupTemplateData GetDefaultSpawnGroup() { return _spawnGroupDataStorage.ElementAt(0).Value; } - SpawnGroupTemplateData GetLegacySpawnGroup() { return _spawnGroupDataStorage.ElementAt(1).Value; } + public SpawnGroupTemplateData GetLegacySpawnGroup() { return _spawnGroupDataStorage.ElementAt(1).Value; } + public List GetSpawnDataForGroup(uint groupId) { return _spawnGroupMapStorage.LookupByKey(groupId); } public SpawnData GetSpawnData(SpawnObjectType type, ulong guid) { if (type == SpawnObjectType.Creature) diff --git a/Source/Game/Maps/Instances/InstanceScript.cs b/Source/Game/Maps/Instances/InstanceScript.cs index 561737b6a..36bc99407 100644 --- a/Source/Game/Maps/Instances/InstanceScript.cs +++ b/Source/Game/Maps/Instances/InstanceScript.cs @@ -243,13 +243,13 @@ namespace Game.Maps { uint groupId = pair.Key; bool doSpawn = pair.Value == states.Spawn; - if (Global.ObjectMgr.IsSpawnGroupActive(groupId) == doSpawn) + if (instance.IsSpawnGroupActive(groupId) == doSpawn) continue; // nothing to do here // if we should spawn group, then spawn it... if (doSpawn) - Global.ObjectMgr.SpawnGroupSpawn(groupId, instance); + instance.SpawnGroupSpawn(groupId, instance); else // otherwise, set it as inactive so it no longer respawns (but don't despawn it) - Global.ObjectMgr.SetSpawnGroupActive(groupId, false); + instance.SetSpawnGroupActive(groupId, false); } } @@ -331,7 +331,7 @@ namespace Game.Maps if (bossInfo.state == EncounterState.ToBeDecided) // loading { bossInfo.state = state; - Log.outDebug(LogFilter.Scripts, $"InstanceScript: Inialize boss {id} state as {state}."); + Log.outDebug(LogFilter.Scripts, $"InstanceScript: Initialize boss {id} state as {state} (map {instance.GetId()}, {instance.GetInstanceId()})."); return false; } else @@ -339,6 +339,12 @@ namespace Game.Maps if (bossInfo.state == state) return false; + if (bossInfo.state == EncounterState.Done) + { + Log.outError(LogFilter.Maps, $"InstanceScript: Tried to set instance state from {bossInfo.state} back to {state} for map {instance.GetId()}, instance id {instance.GetInstanceId()}. Blocked!"); + return false; + } + if (state == EncounterState.Done) { foreach (var guid in bossInfo.minion) diff --git a/Source/Game/Maps/Map.cs b/Source/Game/Maps/Map.cs index 51268add2..9ecd0a798 100644 --- a/Source/Game/Maps/Map.cs +++ b/Source/Game/Maps/Map.cs @@ -2788,6 +2788,153 @@ namespace Game.Maps respawnDelay = (uint)Math.Max(Math.Ceiling(respawnDelay * adjustFactor), timeMinimum); } + SpawnGroupTemplateData GetSpawnGroupData(uint groupId) + { + SpawnGroupTemplateData data = Global.ObjectMgr.GetSpawnGroupData(groupId); + if (data != null && data.mapId == GetId()) + return data; + + return null; + } + + public bool SpawnGroupSpawn(uint groupId, bool ignoreRespawn = false, bool force = false, List spawnedObjects = null) + { + var groupData = GetSpawnGroupData(groupId); + if (groupData == null || groupData.flags.HasAnyFlag(SpawnGroupFlags.System)) + { + Log.outError(LogFilter.Maps, $"Tried to spawn non-existing (or system) spawn group {groupId}. on map {GetId()} Blocked."); + return false; + } + + foreach (var data in Global.ObjectMgr.GetSpawnDataForGroup(groupId)) + { + Cypher.Assert(groupData.mapId == data.spawnPoint.GetMapId()); + // Check if there's already an instance spawned + if (!force) + { + WorldObject obj = GetWorldObjectBySpawnId(data.type, data.spawnId); + if (obj != null) + if ((data.type != SpawnObjectType.Creature) || obj.ToCreature().IsAlive()) + continue; + } + + long respawnTime = GetRespawnTime(data.type, data.spawnId); + if (respawnTime != 0 && respawnTime > Time.UnixTime) + { + 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 SpawnObjectType.Creature: + { + Creature creature = new Creature(); + if (!creature.LoadFromDB(data.spawnId, this, true, force)) + creature.Dispose(); + else if (spawnedObjects != null) + spawnedObjects.Add(creature); + break; + } + case SpawnObjectType.GameObject: + { + GameObject gameobject = new GameObject(); + if (!gameobject.LoadFromDB(data.spawnId, this, true)) + gameobject.Dispose(); + else if (spawnedObjects != null) + spawnedObjects.Add(gameobject); + break; + } + default: + Cypher.Assert(false, $"Invalid spawn type {data.type} with spawnId {data.spawnId}"); + return false; + } + } + SetSpawnGroupActive(groupId, true); // start processing respawns for the group + return true; + } + + public bool SpawnGroupDespawn(uint groupId, bool deleteRespawnTimes) + { + SpawnGroupTemplateData groupData = GetSpawnGroupData(groupId); + if (groupData == null || groupData.flags.HasAnyFlag(SpawnGroupFlags.System)) + { + Log.outError(LogFilter.Maps, $"Tried to despawn non-existing (or system) spawn group {groupId} on map {GetId()}. Blocked."); + return false; + } + + List toUnload = new List(); // unload after iterating, otherwise iterator invalidation + foreach (var data in Global.ObjectMgr.GetSpawnDataForGroup(groupId)) + { + if (deleteRespawnTimes) + RemoveRespawnTime(data.type, data.spawnId); + switch (data.type) + { + case SpawnObjectType.Creature: + { + var bounds = GetCreatureBySpawnIdStore().LookupByKey(data.spawnId); + foreach (var creature in bounds) + toUnload.Add(creature); + break; + } + case SpawnObjectType.GameObject: + { + var bounds = GetGameObjectBySpawnIdStore().LookupByKey(data.spawnId); + foreach (var go in bounds) + toUnload.Add(go); + break; + } + default: + Cypher.Assert(false, $"Invalid spawn type {data.type} in spawn data with spawnId {data.spawnId}."); + return false; + } + } + + // now do the actual despawning + foreach (WorldObject obj in toUnload) + obj.AddObjectToRemoveList(); + + SetSpawnGroupActive(groupId, false); // stop processing respawns for the group, too + return true; + } + + public void SetSpawnGroupActive(uint groupId, bool state) + { + SpawnGroupTemplateData data = GetSpawnGroupData(groupId); + if (data == null || data.flags.HasAnyFlag(SpawnGroupFlags.System)) + { + Log.outError(LogFilter.Maps, $"Tried to set non-existing (or system) spawn group {groupId} to {(state ? "active" : "inactive")} on map {GetId()}. Blocked."); + return; + } + if (state != !data.flags.HasAnyFlag(SpawnGroupFlags.ManualSpawn)) // toggled + _toggledSpawnGroupIds.Add(groupId); + else + _toggledSpawnGroupIds.Remove(groupId); + } + + public bool IsSpawnGroupActive(uint groupId) + { + SpawnGroupTemplateData data = GetSpawnGroupData(groupId); + if (data == null) + { + Log.outWarn(LogFilter.Maps, $"Tried to query state of non-existing spawn group {groupId} on map {GetId()}."); + return false; + } + + if (data.flags.HasAnyFlag(SpawnGroupFlags.System)) + return true; + + return _toggledSpawnGroupIds.Contains(groupId) != !data.flags.HasAnyFlag(SpawnGroupFlags.ManualSpawn); + } + public virtual void DelayedUpdate(uint diff) { for (var i = 0; i < _transports.Count; ++i) @@ -4863,6 +5010,7 @@ namespace Game.Maps SortedSet _respawnTimes = new SortedSet(new CompareRespawnInfo()); Dictionary _creatureRespawnTimesBySpawnId = new Dictionary(); Dictionary _gameObjectRespawnTimesBySpawnId = new Dictionary(); + List _toggledSpawnGroupIds = new List(); uint _respawnCheckTimer; Dictionary _zonePlayerCountMap = new Dictionary(); diff --git a/Source/Game/Maps/ObjectGridLoader.cs b/Source/Game/Maps/ObjectGridLoader.cs index 4fa6ab81c..87202b5c0 100644 --- a/Source/Game/Maps/ObjectGridLoader.cs +++ b/Source/Game/Maps/ObjectGridLoader.cs @@ -17,6 +17,7 @@ using Framework.Constants; using Game.Entities; +using System; using System.Collections.Generic; namespace Game.Maps @@ -91,13 +92,20 @@ namespace Game.Maps SpawnGroupTemplateData group = cdata.spawnGroupData; // If creature in manual spawn group, don't spawn here, unless group is already active. - if (group.flags.HasFlag(SpawnGroupFlags.ManualSpawn) && !group.isActive) - continue; + if (!group.flags.HasAnyFlag(SpawnGroupFlags.System)) + { + if (!map.IsSpawnGroupActive(group.groupId)) + { + obj.Dispose(); + continue; + } + } // If script is blocking spawn, don't spawn but queue for a re-check in a little bit if (!group.flags.HasFlag(SpawnGroupFlags.CompatibilityMode) && !Global.ScriptMgr.CanSpawn(guid, cdata.Id, cdata, map)) { map.SaveRespawnTime(SpawnObjectType.Creature, guid, cdata.Id, Time.UnixTime + RandomHelper.URand(4, 7), map.GetZoneId(PhasingHandler.EmptyPhaseShift, cdata.spawnPoint), GridDefines.ComputeGridCoord(cdata.spawnPoint.GetPositionX(), cdata.spawnPoint.GetPositionY()).GetId(), false); + obj.Dispose(); continue; } } @@ -107,8 +115,14 @@ namespace Game.Maps GameObjectData godata = Global.ObjectMgr.GetGameObjectData(guid); Cypher.Assert(godata != null, $"Tried to load gameobject with spawnId {guid}, but no such object exists."); - if (godata.spawnGroupData.flags.HasFlag(SpawnGroupFlags.ManualSpawn) && !godata.spawnGroupData.isActive) - continue; + if (!godata.spawnGroupData.flags.HasAnyFlag(SpawnGroupFlags.System)) + { + if (!map.IsSpawnGroupActive(godata.spawnGroupData.groupId)) + { + obj.Dispose(); + continue; + } + } } if (!obj.LoadFromDB(guid, map, false, false)) @@ -128,15 +142,10 @@ namespace Game.Maps var cell = new Cell(cellCoord); map.AddToGrid(obj, cell); obj.AddToWorld(); - ++count; - } - void AddObjectHelper(CellCoord cellCoord, ref uint count, Map map, Creature obj) - { - map.AddToGrid(obj, new Cell(cellCoord)); - obj.AddToWorld(); - if (obj.IsActiveObject()) - map.AddToActive(obj); + if (obj.IsCreature()) + if (obj.IsActiveObject()) + map.AddToActive(obj); ++count; } diff --git a/Source/Game/Maps/SpawnData.cs b/Source/Game/Maps/SpawnData.cs index e3a6f6073..60540b084 100644 --- a/Source/Game/Maps/SpawnData.cs +++ b/Source/Game/Maps/SpawnData.cs @@ -27,7 +27,6 @@ namespace Game.Maps public string name; public uint mapId; public SpawnGroupFlags flags; - public bool isActive; } public class SpawnData