Core/Spawn: Move spawn group state management from sObjectMgr to the Map object, which makes it actually function as intended with instances.

Port From (https://github.com/TrinityCore/TrinityCore/commit/27806eeac9d2588d2f7a3b8a0852d45b15a6a241)
This commit is contained in:
hondacrx
2020-08-24 21:21:27 -04:00
parent 15f0aebb23
commit 18d7144ca6
9 changed files with 190 additions and 173 deletions
+2 -2
View File
@@ -2060,7 +2060,7 @@ namespace Game.AI
bool force = ((e.Action.groupSpawn.spawnflags & (uint)SmartAiSpawnFlags.ForceSpawn) != 0); bool force = ((e.Action.groupSpawn.spawnflags & (uint)SmartAiSpawnFlags.ForceSpawn) != 0);
// Instant spawn // Instant spawn
Global.ObjectMgr.SpawnGroupSpawn(e.Action.groupSpawn.groupId, GetBaseObject().GetMap(), ignoreRespawn, force); GetBaseObject().GetMap().SpawnGroupSpawn(e.Action.groupSpawn.groupId, ignoreRespawn, force);
} }
else else
{ {
@@ -2102,7 +2102,7 @@ namespace Game.AI
bool deleteRespawnTimes = ((e.Action.groupSpawn.spawnflags & (uint)SmartAiSpawnFlags.NosaveRespawn) != 0); bool deleteRespawnTimes = ((e.Action.groupSpawn.spawnflags & (uint)SmartAiSpawnFlags.NosaveRespawn) != 0);
// Instant spawn // Instant spawn
Global.ObjectMgr.SpawnGroupDespawn(e.Action.groupSpawn.groupId, GetBaseObject().GetMap(), deleteRespawnTimes); GetBaseObject().GetMap().SpawnGroupSpawn(e.Action.groupSpawn.groupId, deleteRespawnTimes);
} }
else else
{ {
@@ -179,7 +179,7 @@ namespace Game.Chat
if (obj.IsGameObject() && obj.ToGameObject().GetGameObjectData() != null && obj.ToGameObject().GetGameObjectData().spawnGroupData.groupId != 0) if (obj.IsGameObject() && obj.ToGameObject().GetGameObjectData() != null && obj.ToGameObject().GetGameObjectData().spawnGroupData.groupId != 0)
{ {
SpawnGroupTemplateData groupData = obj.ToGameObject().GetGameObjectData().spawnGroupData; 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()) if (obj.IsGameObject())
handler.SendSysMessage(CypherStrings.SpawninfoCompatibilityMode, obj.ToGameObject().GetRespawnCompatibilityMode()); handler.SendSysMessage(CypherStrings.SpawninfoCompatibilityMode, obj.ToGameObject().GetRespawnCompatibilityMode());
+2 -2
View File
@@ -603,7 +603,7 @@ namespace Game.Chat.Commands
uint gridX = ri.gridId % MapConst.MaxGrids; uint gridX = ri.gridId % MapConst.MaxGrids;
string respawnTime = ri.respawnTime > Time.UnixTime ? Time.secsToTimeString((ulong)(ri.respawnTime - Time.UnixTime), true) : stringOverdue; 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(); respawns.Clear();
@@ -626,7 +626,7 @@ namespace Game.Chat.Commands
uint gridX = ri.gridId % MapConst.MaxGrids; uint gridX = ri.gridId % MapConst.MaxGrids;
string respawnTime = ri.respawnTime > Time.UnixTime ? Time.secsToTimeString((ulong)(ri.respawnTime - Time.UnixTime), true) : stringOverdue; 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; return true;
} }
+3 -4
View File
@@ -59,7 +59,7 @@ namespace Game.Chat
Player player = handler.GetSession().GetPlayer(); Player player = handler.GetSession().GetPlayer();
if (!Global.ObjectMgr.SpawnGroupDespawn(groupId, player.GetMap(), deleteRespawnTimes)) if (!player.GetMap().SpawnGroupDespawn(groupId, deleteRespawnTimes))
{ {
handler.SendSysMessage(CypherStrings.SpawngroupBadgroup, groupId); handler.SendSysMessage(CypherStrings.SpawngroupBadgroup, groupId);
return false; return false;
@@ -142,8 +142,7 @@ namespace Game.Chat
if (target.GetCreatureData() != null && target.GetCreatureData().spawnGroupData.groupId != 0) if (target.GetCreatureData() != null && target.GetCreatureData().spawnGroupData.groupId != 0)
{ {
SpawnGroupTemplateData groupData = target.GetCreatureData().spawnGroupData; SpawnGroupTemplateData groupData = target.GetCreatureData().spawnGroupData;
if (groupData != null) handler.SendSysMessage(CypherStrings.SpawninfoGroupId, groupData.name, groupData.groupId, groupData.flags, target.GetMap().IsSpawnGroupActive(groupData.groupId));
handler.SendSysMessage(CypherStrings.SpawninfoGroupId, groupData.name, groupData.groupId, groupData.flags, groupData.isActive);
} }
handler.SendSysMessage(CypherStrings.SpawninfoCompatibilityMode, target.GetRespawnCompatibilityMode()); handler.SendSysMessage(CypherStrings.SpawninfoCompatibilityMode, target.GetRespawnCompatibilityMode());
handler.SendSysMessage(CypherStrings.NpcinfoLevel, target.GetLevel()); handler.SendSysMessage(CypherStrings.NpcinfoLevel, target.GetLevel());
@@ -448,7 +447,7 @@ namespace Game.Chat
Player player = handler.GetSession().GetPlayer(); Player player = handler.GetSession().GetPlayer();
List<WorldObject> creatureList = new List<WorldObject>(); List<WorldObject> creatureList = new List<WorldObject>();
if (!Global.ObjectMgr.SpawnGroupSpawn(groupId, player.GetMap(), ignoreRespawn, force, creatureList)) if (!player.GetMap().SpawnGroupSpawn(groupId, ignoreRespawn, force, creatureList))
{ {
handler.SendSysMessage(CypherStrings.SpawngroupBadgroup, groupId); handler.SendSysMessage(CypherStrings.SpawngroupBadgroup, groupId);
return false; return false;
+3 -147
View File
@@ -5280,7 +5280,6 @@ namespace Game
Log.outError(LogFilter.ServerLoading, $"System spawn group {groupId} ({group.name}) has invalid manual spawn flag. Ignored."); Log.outError(LogFilter.ServerLoading, $"System spawn group {groupId} ({group.name}) has invalid manual spawn flag. Ignored.");
} }
group.flags = flags; group.flags = flags;
group.isActive = !group.flags.HasAnyFlag(SpawnGroupFlags.ManualSpawn);
_spawnGroupDataStorage[groupId] = group; _spawnGroupDataStorage[groupId] = group;
} while (result.NextRow()); } while (result.NextRow());
@@ -5294,7 +5293,6 @@ namespace Game
data.name = "Default Group"; data.name = "Default Group";
data.mapId = 0; data.mapId = 0;
data.flags = SpawnGroupFlags.System; data.flags = SpawnGroupFlags.System;
data.isActive = true;
_spawnGroupDataStorage[0] = data; _spawnGroupDataStorage[0] = data;
} }
@@ -5307,7 +5305,6 @@ namespace Game
data.name = "Legacy Group"; data.name = "Legacy Group";
data.mapId = 0; data.mapId = 0;
data.flags = SpawnGroupFlags.System | SpawnGroupFlags.CompatibilityMode; data.flags = SpawnGroupFlags.System | SpawnGroupFlags.CompatibilityMode;
data.isActive = true;
_spawnGroupDataStorage[1] = data; _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!"); 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<WorldObject> 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<WorldObject> toUnload = new List<WorldObject>(); // 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) public InstanceTemplate GetInstanceTemplate(uint mapID)
{ {
@@ -5598,20 +5464,10 @@ namespace Game
return _dungeonEncounterStorage.LookupByKey(MathFunctions.MakePair64(mapId, (uint)difficulty)); return _dungeonEncounterStorage.LookupByKey(MathFunctions.MakePair64(mapId, (uint)difficulty));
} }
public bool IsTransportMap(uint mapId) { return _transportMaps.Contains((ushort)mapId); } public bool IsTransportMap(uint mapId) { return _transportMaps.Contains((ushort)mapId); }
SpawnGroupTemplateData GetSpawnGroupData(uint groupId) { return _spawnGroupDataStorage.LookupByKey(groupId); } public 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 GetDefaultSpawnGroup() { return _spawnGroupDataStorage.ElementAt(0).Value; } 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<SpawnData> GetSpawnDataForGroup(uint groupId) { return _spawnGroupMapStorage.LookupByKey(groupId); }
public SpawnData GetSpawnData(SpawnObjectType type, ulong guid) public SpawnData GetSpawnData(SpawnObjectType type, ulong guid)
{ {
if (type == SpawnObjectType.Creature) if (type == SpawnObjectType.Creature)
+10 -4
View File
@@ -243,13 +243,13 @@ namespace Game.Maps
{ {
uint groupId = pair.Key; uint groupId = pair.Key;
bool doSpawn = pair.Value == states.Spawn; bool doSpawn = pair.Value == states.Spawn;
if (Global.ObjectMgr.IsSpawnGroupActive(groupId) == doSpawn) if (instance.IsSpawnGroupActive(groupId) == doSpawn)
continue; // nothing to do here continue; // nothing to do here
// if we should spawn group, then spawn it... // if we should spawn group, then spawn it...
if (doSpawn) 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) 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 if (bossInfo.state == EncounterState.ToBeDecided) // loading
{ {
bossInfo.state = state; 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; return false;
} }
else else
@@ -339,6 +339,12 @@ namespace Game.Maps
if (bossInfo.state == state) if (bossInfo.state == state)
return false; 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) if (state == EncounterState.Done)
{ {
foreach (var guid in bossInfo.minion) foreach (var guid in bossInfo.minion)
+148
View File
@@ -2788,6 +2788,153 @@ namespace Game.Maps
respawnDelay = (uint)Math.Max(Math.Ceiling(respawnDelay * adjustFactor), timeMinimum); 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<WorldObject> 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<WorldObject> toUnload = new List<WorldObject>(); // 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) public virtual void DelayedUpdate(uint diff)
{ {
for (var i = 0; i < _transports.Count; ++i) for (var i = 0; i < _transports.Count; ++i)
@@ -4863,6 +5010,7 @@ namespace Game.Maps
SortedSet<RespawnInfo> _respawnTimes = new SortedSet<RespawnInfo>(new CompareRespawnInfo()); SortedSet<RespawnInfo> _respawnTimes = new SortedSet<RespawnInfo>(new CompareRespawnInfo());
Dictionary<ulong, RespawnInfo> _creatureRespawnTimesBySpawnId = new Dictionary<ulong, RespawnInfo>(); Dictionary<ulong, RespawnInfo> _creatureRespawnTimesBySpawnId = new Dictionary<ulong, RespawnInfo>();
Dictionary<ulong, RespawnInfo> _gameObjectRespawnTimesBySpawnId = new Dictionary<ulong, RespawnInfo>(); Dictionary<ulong, RespawnInfo> _gameObjectRespawnTimesBySpawnId = new Dictionary<ulong, RespawnInfo>();
List<uint> _toggledSpawnGroupIds = new List<uint>();
uint _respawnCheckTimer; uint _respawnCheckTimer;
Dictionary<uint, uint> _zonePlayerCountMap = new Dictionary<uint, uint>(); Dictionary<uint, uint> _zonePlayerCountMap = new Dictionary<uint, uint>();
+21 -12
View File
@@ -17,6 +17,7 @@
using Framework.Constants; using Framework.Constants;
using Game.Entities; using Game.Entities;
using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace Game.Maps namespace Game.Maps
@@ -91,13 +92,20 @@ namespace Game.Maps
SpawnGroupTemplateData group = cdata.spawnGroupData; SpawnGroupTemplateData group = cdata.spawnGroupData;
// If creature in manual spawn group, don't spawn here, unless group is already active. // If creature in manual spawn group, don't spawn here, unless group is already active.
if (group.flags.HasFlag(SpawnGroupFlags.ManualSpawn) && !group.isActive) if (!group.flags.HasAnyFlag(SpawnGroupFlags.System))
continue; {
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 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)) 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); 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; continue;
} }
} }
@@ -107,8 +115,14 @@ namespace Game.Maps
GameObjectData godata = Global.ObjectMgr.GetGameObjectData(guid); GameObjectData godata = Global.ObjectMgr.GetGameObjectData(guid);
Cypher.Assert(godata != null, $"Tried to load gameobject with spawnId {guid}, but no such object exists."); 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) if (!godata.spawnGroupData.flags.HasAnyFlag(SpawnGroupFlags.System))
continue; {
if (!map.IsSpawnGroupActive(godata.spawnGroupData.groupId))
{
obj.Dispose();
continue;
}
}
} }
if (!obj.LoadFromDB(guid, map, false, false)) if (!obj.LoadFromDB(guid, map, false, false))
@@ -128,15 +142,10 @@ namespace Game.Maps
var cell = new Cell(cellCoord); var cell = new Cell(cellCoord);
map.AddToGrid(obj, cell); map.AddToGrid(obj, cell);
obj.AddToWorld(); obj.AddToWorld();
++count;
}
void AddObjectHelper(CellCoord cellCoord, ref uint count, Map map, Creature obj) if (obj.IsCreature())
{ if (obj.IsActiveObject())
map.AddToGrid(obj, new Cell(cellCoord)); map.AddToActive(obj);
obj.AddToWorld();
if (obj.IsActiveObject())
map.AddToActive(obj);
++count; ++count;
} }
-1
View File
@@ -27,7 +27,6 @@ namespace Game.Maps
public string name; public string name;
public uint mapId; public uint mapId;
public SpawnGroupFlags flags; public SpawnGroupFlags flags;
public bool isActive;
} }
public class SpawnData public class SpawnData