Core/Phasing: Implemented db spawns in personal phases
Port From (https://github.com/TrinityCore/TrinityCore/commit/8fabe5a3aacf7797f03d074ab8434f445be64955)
This commit is contained in:
@@ -770,7 +770,7 @@ namespace Game.Chat
|
|||||||
else if (target.GetDBPhase() < 0)
|
else if (target.GetDBPhase() < 0)
|
||||||
handler.SendSysMessage($"Target creature's PhaseGroup in DB: {Math.Abs(target.GetDBPhase())}");
|
handler.SendSysMessage($"Target creature's PhaseGroup in DB: {Math.Abs(target.GetDBPhase())}");
|
||||||
|
|
||||||
PhasingHandler.PrintToChat(handler, target.GetPhaseShift());
|
PhasingHandler.PrintToChat(handler, target);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -282,9 +282,9 @@ namespace Game.Chat
|
|||||||
obj.Relocate(x, y, z, obj.GetOrientation());
|
obj.Relocate(x, y, z, obj.GetOrientation());
|
||||||
|
|
||||||
// update which cell has this gameobject registered for loading
|
// update which cell has this gameobject registered for loading
|
||||||
Global.ObjectMgr.RemoveGameObjectFromGrid(guidLow, obj.GetGameObjectData());
|
Global.ObjectMgr.RemoveGameObjectFromGrid(obj.GetGameObjectData());
|
||||||
obj.SaveToDB();
|
obj.SaveToDB();
|
||||||
Global.ObjectMgr.AddGameObjectToGrid(guidLow, obj.GetGameObjectData());
|
Global.ObjectMgr.AddGameObjectToGrid(obj.GetGameObjectData());
|
||||||
|
|
||||||
// Generate a completely new spawn with new guid
|
// Generate a completely new spawn with new guid
|
||||||
// client caches recently deleted objects and brings them back to life
|
// client caches recently deleted objects and brings them back to life
|
||||||
@@ -627,7 +627,7 @@ namespace Game.Chat
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// TODO: is it really necessary to add both the real and DB table guid here ?
|
// TODO: is it really necessary to add both the real and DB table guid here ?
|
||||||
Global.ObjectMgr.AddGameObjectToGrid(spawnId, Global.ObjectMgr.GetGameObjectData(spawnId));
|
Global.ObjectMgr.AddGameObjectToGrid(Global.ObjectMgr.GetGameObjectData(spawnId));
|
||||||
handler.SendSysMessage(CypherStrings.GameobjectAdd, objectId, objectInfo.name, spawnId, player.GetPositionX(), player.GetPositionY(), player.GetPositionZ());
|
handler.SendSysMessage(CypherStrings.GameobjectAdd, objectId, objectInfo.name, spawnId, player.GetPositionX(), player.GetPositionY(), player.GetPositionZ());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -981,7 +981,7 @@ namespace Game.Chat
|
|||||||
if (liquidStatus != null)
|
if (liquidStatus != null)
|
||||||
handler.SendSysMessage(CypherStrings.LiquidStatus, liquidStatus.level, liquidStatus.depth_level, liquidStatus.entry, liquidStatus.type_flags, status);
|
handler.SendSysMessage(CypherStrings.LiquidStatus, liquidStatus.level, liquidStatus.depth_level, liquidStatus.entry, liquidStatus.type_flags, status);
|
||||||
|
|
||||||
PhasingHandler.PrintToChat(handler, obj.GetPhaseShift());
|
PhasingHandler.PrintToChat(handler, obj);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1774,7 +1774,7 @@ namespace Game.Chat
|
|||||||
|
|
||||||
// Output XIII. phases
|
// Output XIII. phases
|
||||||
if (target)
|
if (target)
|
||||||
PhasingHandler.PrintToChat(handler, target.GetPhaseShift());
|
PhasingHandler.PrintToChat(handler, target);
|
||||||
|
|
||||||
// Output XIV. LANG_PINFO_CHR_MONEY
|
// Output XIV. LANG_PINFO_CHR_MONEY
|
||||||
ulong gold = money / MoneyConstants.Gold;
|
ulong gold = money / MoneyConstants.Gold;
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ namespace Game.Chat
|
|||||||
if (data != null)
|
if (data != null)
|
||||||
handler.SendSysMessage(CypherStrings.NpcinfoPhases, data.PhaseId, data.PhaseGroup);
|
handler.SendSysMessage(CypherStrings.NpcinfoPhases, data.PhaseId, data.PhaseGroup);
|
||||||
|
|
||||||
PhasingHandler.PrintToChat(handler, target.GetPhaseShift());
|
PhasingHandler.PrintToChat(handler, target);
|
||||||
|
|
||||||
handler.SendSysMessage(CypherStrings.NpcinfoArmor, target.GetArmor());
|
handler.SendSysMessage(CypherStrings.NpcinfoArmor, target.GetArmor());
|
||||||
handler.SendSysMessage(CypherStrings.NpcinfoPosition, target.GetPositionX(), target.GetPositionY(), target.GetPositionZ());
|
handler.SendSysMessage(CypherStrings.NpcinfoPosition, target.GetPositionX(), target.GetPositionY(), target.GetPositionZ());
|
||||||
@@ -239,9 +239,9 @@ namespace Game.Chat
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Global.ObjectMgr.RemoveCreatureFromGrid(lowguid, data);
|
Global.ObjectMgr.RemoveCreatureFromGrid(data);
|
||||||
data.SpawnPoint.Relocate(player);
|
data.SpawnPoint.Relocate(player);
|
||||||
Global.ObjectMgr.AddCreatureToGrid(lowguid, data);
|
Global.ObjectMgr.AddCreatureToGrid(data);
|
||||||
|
|
||||||
// update position in DB
|
// update position in DB
|
||||||
PreparedStatement stmt = DB.World.GetPreparedStatement(WorldStatements.UPD_CREATURE_POSITION);
|
PreparedStatement stmt = DB.World.GetPreparedStatement(WorldStatements.UPD_CREATURE_POSITION);
|
||||||
@@ -668,7 +668,7 @@ namespace Game.Chat
|
|||||||
if (creaturePassenger != null)
|
if (creaturePassenger != null)
|
||||||
{
|
{
|
||||||
creaturePassenger.SaveToDB((uint)trans.GetGoInfo().MoTransport.SpawnMap, new List<Difficulty>() { map.GetDifficultyID() });
|
creaturePassenger.SaveToDB((uint)trans.GetGoInfo().MoTransport.SpawnMap, new List<Difficulty>() { map.GetDifficultyID() });
|
||||||
Global.ObjectMgr.AddCreatureToGrid(guid, data);
|
Global.ObjectMgr.AddCreatureToGrid(data);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -689,7 +689,7 @@ namespace Game.Chat
|
|||||||
if (!creature)
|
if (!creature)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Global.ObjectMgr.AddCreatureToGrid(db_guid, Global.ObjectMgr.GetCreatureData(db_guid));
|
Global.ObjectMgr.AddCreatureToGrid(Global.ObjectMgr.GetCreatureData(db_guid));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1204,7 +1204,7 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint mapId = GetTransport() ? (uint)GetTransport().GetGoInfo().MoTransport.SpawnMap : GetMapId();
|
uint mapId = GetTransport() ? (uint)GetTransport().GetGoInfo().MoTransport.SpawnMap : GetMapId();
|
||||||
SaveToDB(mapId, data.spawnDifficulties);
|
SaveToDB(mapId, data.SpawnDifficulties);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void SaveToDB(uint mapid, List<Difficulty> spawnDifficulties)
|
public virtual void SaveToDB(uint mapid, List<Difficulty> spawnDifficulties)
|
||||||
@@ -1274,7 +1274,7 @@ namespace Game.Entities
|
|||||||
// prevent add data integrity problems
|
// prevent add data integrity problems
|
||||||
data.movementType = (byte)(m_wanderDistance == 0 && GetDefaultMovementType() == MovementGeneratorType.Random
|
data.movementType = (byte)(m_wanderDistance == 0 && GetDefaultMovementType() == MovementGeneratorType.Random
|
||||||
? MovementGeneratorType.Idle : GetDefaultMovementType());
|
? MovementGeneratorType.Idle : GetDefaultMovementType());
|
||||||
data.spawnDifficulties = spawnDifficulties;
|
data.SpawnDifficulties = spawnDifficulties;
|
||||||
data.npcflag = npcflag;
|
data.npcflag = npcflag;
|
||||||
data.unit_flags = unitFlags;
|
data.unit_flags = unitFlags;
|
||||||
data.unit_flags2 = unitFlags2;
|
data.unit_flags2 = unitFlags2;
|
||||||
@@ -1299,7 +1299,7 @@ namespace Game.Entities
|
|||||||
stmt.AddValue(index++, m_spawnId);
|
stmt.AddValue(index++, m_spawnId);
|
||||||
stmt.AddValue(index++, GetEntry());
|
stmt.AddValue(index++, GetEntry());
|
||||||
stmt.AddValue(index++, mapid);
|
stmt.AddValue(index++, mapid);
|
||||||
stmt.AddValue(index++, data.spawnDifficulties.Empty() ? "" : string.Join(',', data.spawnDifficulties));
|
stmt.AddValue(index++, data.SpawnDifficulties.Empty() ? "" : string.Join(',', data.SpawnDifficulties));
|
||||||
stmt.AddValue(index++, data.PhaseId);
|
stmt.AddValue(index++, data.PhaseId);
|
||||||
stmt.AddValue(index++, data.PhaseGroup);
|
stmt.AddValue(index++, data.PhaseGroup);
|
||||||
stmt.AddValue(index++, displayId);
|
stmt.AddValue(index++, displayId);
|
||||||
|
|||||||
@@ -1018,7 +1018,7 @@ namespace Game.Entities
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveToDB(GetMapId(), data.spawnDifficulties);
|
SaveToDB(GetMapId(), data.SpawnDifficulties);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveToDB(uint mapid, List<Difficulty> spawnDifficulties)
|
public void SaveToDB(uint mapid, List<Difficulty> spawnDifficulties)
|
||||||
@@ -1045,7 +1045,7 @@ namespace Game.Entities
|
|||||||
data.spawntimesecs = (int)(m_spawnedByDefault ? m_respawnDelayTime : -m_respawnDelayTime);
|
data.spawntimesecs = (int)(m_spawnedByDefault ? m_respawnDelayTime : -m_respawnDelayTime);
|
||||||
data.animprogress = GetGoAnimProgress();
|
data.animprogress = GetGoAnimProgress();
|
||||||
data.goState = GetGoState();
|
data.goState = GetGoState();
|
||||||
data.spawnDifficulties = spawnDifficulties;
|
data.SpawnDifficulties = spawnDifficulties;
|
||||||
data.artKit = (byte)GetGoArtKit();
|
data.artKit = (byte)GetGoArtKit();
|
||||||
if (data.spawnGroupData == null)
|
if (data.spawnGroupData == null)
|
||||||
data.spawnGroupData = Global.ObjectMgr.GetDefaultSpawnGroup();
|
data.spawnGroupData = Global.ObjectMgr.GetDefaultSpawnGroup();
|
||||||
@@ -1063,7 +1063,7 @@ namespace Game.Entities
|
|||||||
stmt.AddValue(index++, m_spawnId);
|
stmt.AddValue(index++, m_spawnId);
|
||||||
stmt.AddValue(index++, GetEntry());
|
stmt.AddValue(index++, GetEntry());
|
||||||
stmt.AddValue(index++, mapid);
|
stmt.AddValue(index++, mapid);
|
||||||
stmt.AddValue(index++, data.spawnDifficulties.Empty() ? "" : string.Join(",", data.spawnDifficulties));
|
stmt.AddValue(index++, data.SpawnDifficulties.Empty() ? "" : string.Join(",", data.SpawnDifficulties));
|
||||||
stmt.AddValue(index++, data.PhaseId);
|
stmt.AddValue(index++, data.PhaseId);
|
||||||
stmt.AddValue(index++, data.PhaseGroup);
|
stmt.AddValue(index++, data.PhaseGroup);
|
||||||
stmt.AddValue(index++, GetPositionX());
|
stmt.AddValue(index++, GetPositionX());
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ namespace Game.Entities
|
|||||||
if (!pos.IsPositionValid())
|
if (!pos.IsPositionValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
player.GetMap().LoadGrid(firstCamera.locations.X, firstCamera.locations.Y);
|
player.GetMap().LoadGridForActiveObject(pos.GetPositionX(), pos.GetPositionY(), player);
|
||||||
m_CinematicObject = player.SummonCreature(1, pos.posX, pos.posY, pos.posZ, 0.0f, TempSummonType.TimedDespawn, 5 * Time.Minute * Time.InMilliseconds);
|
m_CinematicObject = player.SummonCreature(1, pos.posX, pos.posY, pos.posZ, 0.0f, TempSummonType.TimedDespawn, 5 * Time.Minute * Time.InMilliseconds);
|
||||||
if (m_CinematicObject)
|
if (m_CinematicObject)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2153,6 +2153,13 @@ namespace Game.Entities
|
|||||||
TeleportTo(m_summon_location);
|
TeleportTo(m_summon_location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void OnPhaseChange()
|
||||||
|
{
|
||||||
|
base.OnPhaseChange();
|
||||||
|
|
||||||
|
GetMap().UpdatePersonalPhasesForPlayer(this);
|
||||||
|
}
|
||||||
|
|
||||||
//GM
|
//GM
|
||||||
public bool IsAcceptWhispers() { return m_ExtraFlags.HasAnyFlag(PlayerExtraFlags.AcceptWhispers); }
|
public bool IsAcceptWhispers() { return m_ExtraFlags.HasAnyFlag(PlayerExtraFlags.AcceptWhispers); }
|
||||||
public void SetAcceptWhispers(bool on)
|
public void SetAcceptWhispers(bool on)
|
||||||
|
|||||||
@@ -1222,10 +1222,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
public bool IsPossessed() { return HasUnitState(UnitState.Possessed); }
|
public bool IsPossessed() { return HasUnitState(UnitState.Possessed); }
|
||||||
|
|
||||||
public void OnPhaseChange()
|
public virtual void OnPhaseChange() { }
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint GetModelForForm(ShapeShiftForm form, uint spellId)
|
public uint GetModelForForm(ShapeShiftForm form, uint spellId)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1188,7 +1188,7 @@ namespace Game
|
|||||||
CreatureData data = Global.ObjectMgr.GetCreatureData(guid);
|
CreatureData data = Global.ObjectMgr.GetCreatureData(guid);
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
Global.ObjectMgr.AddCreatureToGrid(guid, data);
|
Global.ObjectMgr.AddCreatureToGrid(data);
|
||||||
|
|
||||||
// Spawn if necessary (loaded grids only)
|
// Spawn if necessary (loaded grids only)
|
||||||
Map map = Global.MapMgr.CreateBaseMap(data.MapId);
|
Map map = Global.MapMgr.CreateBaseMap(data.MapId);
|
||||||
@@ -1212,7 +1212,7 @@ namespace Game
|
|||||||
GameObjectData data = Global.ObjectMgr.GetGameObjectData(guid);
|
GameObjectData data = Global.ObjectMgr.GetGameObjectData(guid);
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
Global.ObjectMgr.AddGameObjectToGrid(guid, data);
|
Global.ObjectMgr.AddGameObjectToGrid(data);
|
||||||
// Spawn if necessary (loaded grids only)
|
// Spawn if necessary (loaded grids only)
|
||||||
// this base map checked as non-instanced and then only existed
|
// this base map checked as non-instanced and then only existed
|
||||||
Map map = Global.MapMgr.CreateBaseMap(data.MapId);
|
Map map = Global.MapMgr.CreateBaseMap(data.MapId);
|
||||||
@@ -1264,7 +1264,7 @@ namespace Game
|
|||||||
CreatureData data = Global.ObjectMgr.GetCreatureData(guid);
|
CreatureData data = Global.ObjectMgr.GetCreatureData(guid);
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
Global.ObjectMgr.RemoveCreatureFromGrid(guid, data);
|
Global.ObjectMgr.RemoveCreatureFromGrid(data);
|
||||||
|
|
||||||
Global.MapMgr.DoForAllMapsWithMapId(data.MapId, map =>
|
Global.MapMgr.DoForAllMapsWithMapId(data.MapId, map =>
|
||||||
{
|
{
|
||||||
@@ -1292,7 +1292,7 @@ namespace Game
|
|||||||
GameObjectData data = Global.ObjectMgr.GetGameObjectData(guid);
|
GameObjectData data = Global.ObjectMgr.GetGameObjectData(guid);
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
Global.ObjectMgr.RemoveGameObjectFromGrid(guid, data);
|
Global.ObjectMgr.RemoveGameObjectFromGrid(data);
|
||||||
|
|
||||||
Global.MapMgr.DoForAllMapsWithMapId(data.MapId, map =>
|
Global.MapMgr.DoForAllMapsWithMapId(data.MapId, map =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2901,7 +2901,7 @@ namespace Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
// they must have a possibility to meet (normal/heroic difficulty)
|
// they must have a possibility to meet (normal/heroic difficulty)
|
||||||
if (!master.spawnDifficulties.Intersect(slave.spawnDifficulties).Any())
|
if (!master.SpawnDifficulties.Intersect(slave.SpawnDifficulties).Any())
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "LinkedRespawn: Creature '{0}' linking to '{1}' with not corresponding spawnMask", guidLow, linkedGuidLow);
|
Log.outError(LogFilter.Sql, "LinkedRespawn: Creature '{0}' linking to '{1}' with not corresponding spawnMask", guidLow, linkedGuidLow);
|
||||||
error = true;
|
error = true;
|
||||||
@@ -2939,7 +2939,7 @@ namespace Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
// they must have a possibility to meet (normal/heroic difficulty)
|
// they must have a possibility to meet (normal/heroic difficulty)
|
||||||
if (!master.spawnDifficulties.Intersect(slave.spawnDifficulties).Any())
|
if (!master.SpawnDifficulties.Intersect(slave.SpawnDifficulties).Any())
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "LinkedRespawn: Creature '{0}' linking to '{1}' with not corresponding spawnMask", guidLow, linkedGuidLow);
|
Log.outError(LogFilter.Sql, "LinkedRespawn: Creature '{0}' linking to '{1}' with not corresponding spawnMask", guidLow, linkedGuidLow);
|
||||||
error = true;
|
error = true;
|
||||||
@@ -2977,7 +2977,7 @@ namespace Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
// they must have a possibility to meet (normal/heroic difficulty)
|
// they must have a possibility to meet (normal/heroic difficulty)
|
||||||
if (!master.spawnDifficulties.Intersect(slave.spawnDifficulties).Any())
|
if (!master.SpawnDifficulties.Intersect(slave.SpawnDifficulties).Any())
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "LinkedRespawn: Creature '{0}' linking to '{1}' with not corresponding spawnMask", guidLow, linkedGuidLow);
|
Log.outError(LogFilter.Sql, "LinkedRespawn: Creature '{0}' linking to '{1}' with not corresponding spawnMask", guidLow, linkedGuidLow);
|
||||||
error = true;
|
error = true;
|
||||||
@@ -3015,7 +3015,7 @@ namespace Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
// they must have a possibility to meet (normal/heroic difficulty)
|
// they must have a possibility to meet (normal/heroic difficulty)
|
||||||
if (!master.spawnDifficulties.Intersect(slave.spawnDifficulties).Any())
|
if (!master.SpawnDifficulties.Intersect(slave.SpawnDifficulties).Any())
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "LinkedRespawn: Creature '{0}' linking to '{1}' with not corresponding spawnMask", guidLow, linkedGuidLow);
|
Log.outError(LogFilter.Sql, "LinkedRespawn: Creature '{0}' linking to '{1}' with not corresponding spawnMask", guidLow, linkedGuidLow);
|
||||||
error = true;
|
error = true;
|
||||||
@@ -3420,7 +3420,7 @@ namespace Game
|
|||||||
data.curhealth = result.Read<uint>(12);
|
data.curhealth = result.Read<uint>(12);
|
||||||
data.curmana = result.Read<uint>(13);
|
data.curmana = result.Read<uint>(13);
|
||||||
data.movementType = result.Read<byte>(14);
|
data.movementType = result.Read<byte>(14);
|
||||||
data.spawnDifficulties = ParseSpawnDifficulties(result.Read<string>(15), "creature", guid, data.MapId, spawnMasks.LookupByKey(data.MapId));
|
data.SpawnDifficulties = ParseSpawnDifficulties(result.Read<string>(15), "creature", guid, data.MapId, spawnMasks.LookupByKey(data.MapId));
|
||||||
short gameEvent = result.Read<short>(16);
|
short gameEvent = result.Read<short>(16);
|
||||||
uint PoolId = result.Read<uint>(17);
|
uint PoolId = result.Read<uint>(17);
|
||||||
data.npcflag = result.Read<ulong>(18);
|
data.npcflag = result.Read<ulong>(18);
|
||||||
@@ -3442,7 +3442,7 @@ namespace Game
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.spawnDifficulties.Empty())
|
if (data.SpawnDifficulties.Empty())
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, $"Table `creature` has creature (GUID: {guid}) that is not spawned in any difficulty, skipped.");
|
Log.outError(LogFilter.Sql, $"Table `creature` has creature (GUID: {guid}) that is not spawned in any difficulty, skipped.");
|
||||||
continue;
|
continue;
|
||||||
@@ -3566,7 +3566,7 @@ namespace Game
|
|||||||
|
|
||||||
// Add to grid if not managed by the game event or pool system
|
// Add to grid if not managed by the game event or pool system
|
||||||
if (gameEvent == 0 && PoolId == 0)
|
if (gameEvent == 0 && PoolId == 0)
|
||||||
AddCreatureToGrid(guid, data);
|
AddCreatureToGrid(data);
|
||||||
|
|
||||||
creatureDataStorage[guid] = data;
|
creatureDataStorage[guid] = data;
|
||||||
count++;
|
count++;
|
||||||
@@ -3575,27 +3575,92 @@ namespace Game
|
|||||||
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} creatures in {1} ms", count, Time.GetMSTimeDiffToNow(time));
|
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} creatures in {1} ms", count, Time.GetMSTimeDiffToNow(time));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddCreatureToGrid(ulong guid, CreatureData data)
|
public bool HasPersonalSpawns(uint mapid, Difficulty spawnMode, uint phaseId)
|
||||||
{
|
{
|
||||||
foreach (Difficulty difficulty in data.spawnDifficulties)
|
return mapPersonalObjectGuidsStore.ContainsKey((mapid, spawnMode, phaseId));
|
||||||
{
|
|
||||||
CellCoord cellCoord = GridDefines.ComputeCellCoord(data.SpawnPoint.GetPositionX(), data.SpawnPoint.GetPositionY());
|
|
||||||
var cellguids = CreateCellObjectGuids(data.MapId, difficulty, cellCoord.GetId());
|
|
||||||
cellguids.creatures.Add(guid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public void RemoveCreatureFromGrid(ulong guid, CreatureData data)
|
|
||||||
{
|
|
||||||
foreach (Difficulty difficulty in data.spawnDifficulties)
|
|
||||||
{
|
|
||||||
CellCoord cellCoord = GridDefines.ComputeCellCoord(data.SpawnPoint.GetPositionX(), data.SpawnPoint.GetPositionY());
|
|
||||||
CellObjectGuids cellguids = GetCellObjectGuids(data.MapId, difficulty, cellCoord.GetId());
|
|
||||||
if (cellguids == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cellguids.creatures.Remove(guid);
|
public CellObjectGuids GetCellPersonalObjectGuids(uint mapid, Difficulty spawnMode, uint phaseId, uint cell_id)
|
||||||
|
{
|
||||||
|
var guids = mapPersonalObjectGuidsStore.LookupByKey((mapid, spawnMode, phaseId));
|
||||||
|
if (guids != null)
|
||||||
|
return guids.LookupByKey(cell_id);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddSpawnDataToGrid(SpawnData data)
|
||||||
|
{
|
||||||
|
uint cellId = GridDefines.ComputeCellCoord(data.SpawnPoint.GetPositionX(), data.SpawnPoint.GetPositionY()).GetId();
|
||||||
|
bool isPersonalPhase = PhasingHandler.IsPersonalPhase(data.PhaseId);
|
||||||
|
if (!isPersonalPhase)
|
||||||
|
{
|
||||||
|
foreach (Difficulty difficulty in data.SpawnDifficulties)
|
||||||
|
{
|
||||||
|
var key = (data.MapId, difficulty);
|
||||||
|
if (!mapObjectGuidsStore.ContainsKey(key))
|
||||||
|
mapObjectGuidsStore[key] = new();
|
||||||
|
|
||||||
|
if (!mapObjectGuidsStore[key].ContainsKey(cellId))
|
||||||
|
mapObjectGuidsStore[key][cellId] = new();
|
||||||
|
|
||||||
|
mapObjectGuidsStore[key][cellId].AddSpawn(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (Difficulty difficulty in data.SpawnDifficulties)
|
||||||
|
{
|
||||||
|
var key = (data.MapId, difficulty, data.PhaseId);
|
||||||
|
if (!mapPersonalObjectGuidsStore.ContainsKey(key))
|
||||||
|
mapPersonalObjectGuidsStore[key] = new();
|
||||||
|
|
||||||
|
if (!mapPersonalObjectGuidsStore[key].ContainsKey(cellId))
|
||||||
|
mapPersonalObjectGuidsStore[key][cellId] = new();
|
||||||
|
|
||||||
|
mapPersonalObjectGuidsStore[key][cellId].AddSpawn(data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RemoveSpawnDataFromGrid(SpawnData data)
|
||||||
|
{
|
||||||
|
uint cellId = GridDefines.ComputeCellCoord(data.SpawnPoint.GetPositionX(), data.SpawnPoint.GetPositionY()).GetId();
|
||||||
|
bool isPersonalPhase = PhasingHandler.IsPersonalPhase(data.PhaseId);
|
||||||
|
if (!isPersonalPhase)
|
||||||
|
{
|
||||||
|
foreach (Difficulty difficulty in data.SpawnDifficulties)
|
||||||
|
{
|
||||||
|
var key = (data.MapId, difficulty);
|
||||||
|
if (!mapObjectGuidsStore.ContainsKey(key) || !mapObjectGuidsStore[key].ContainsKey(cellId))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
mapObjectGuidsStore[(data.MapId, difficulty)][cellId].RemoveSpawn(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (Difficulty difficulty in data.SpawnDifficulties)
|
||||||
|
{
|
||||||
|
var key = (data.MapId, difficulty, data.PhaseId);
|
||||||
|
if (!mapPersonalObjectGuidsStore.ContainsKey(key) || !mapPersonalObjectGuidsStore[key].ContainsKey(cellId))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
mapPersonalObjectGuidsStore[key][cellId].RemoveSpawn(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddCreatureToGrid(CreatureData data)
|
||||||
|
{
|
||||||
|
AddSpawnDataToGrid(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveCreatureFromGrid(CreatureData data)
|
||||||
|
{
|
||||||
|
RemoveSpawnDataFromGrid(data);
|
||||||
|
}
|
||||||
|
|
||||||
public ulong AddCreatureData(uint entry, uint mapId, Position pos, uint spawntimedelay)
|
public ulong AddCreatureData(uint entry, uint mapId, Position pos, uint spawntimedelay)
|
||||||
{
|
{
|
||||||
CreatureTemplate cInfo = GetCreatureTemplate(entry);
|
CreatureTemplate cInfo = GetCreatureTemplate(entry);
|
||||||
@@ -3625,14 +3690,14 @@ namespace Game
|
|||||||
data.curhealth = (uint)(Global.DB2Mgr.EvaluateExpectedStat(ExpectedStatType.CreatureHealth, level, cInfo.HealthScalingExpansion, scaling.ContentTuningID, (Class)cInfo.UnitClass) * cInfo.ModHealth * cInfo.ModHealthExtra);
|
data.curhealth = (uint)(Global.DB2Mgr.EvaluateExpectedStat(ExpectedStatType.CreatureHealth, level, cInfo.HealthScalingExpansion, scaling.ContentTuningID, (Class)cInfo.UnitClass) * cInfo.ModHealth * cInfo.ModHealthExtra);
|
||||||
data.curmana = stats.GenerateMana(cInfo);
|
data.curmana = stats.GenerateMana(cInfo);
|
||||||
data.movementType = (byte)cInfo.MovementType;
|
data.movementType = (byte)cInfo.MovementType;
|
||||||
data.spawnDifficulties.Add(Difficulty.None);
|
data.SpawnDifficulties.Add(Difficulty.None);
|
||||||
data.dbData = false;
|
data.dbData = false;
|
||||||
data.npcflag = (uint)cInfo.Npcflag;
|
data.npcflag = (uint)cInfo.Npcflag;
|
||||||
data.unit_flags = (uint)cInfo.UnitFlags;
|
data.unit_flags = (uint)cInfo.UnitFlags;
|
||||||
data.dynamicflags = cInfo.DynamicFlags;
|
data.dynamicflags = cInfo.DynamicFlags;
|
||||||
data.spawnGroupData = GetLegacySpawnGroup();
|
data.spawnGroupData = GetLegacySpawnGroup();
|
||||||
|
|
||||||
AddCreatureToGrid(spawnId, data);
|
AddCreatureToGrid(data);
|
||||||
|
|
||||||
// We use spawn coords to spawn
|
// We use spawn coords to spawn
|
||||||
if (!map.Instanceable() && !map.IsRemovalGrid(data.SpawnPoint))
|
if (!map.Instanceable() && !map.IsRemovalGrid(data.SpawnPoint))
|
||||||
@@ -3721,7 +3786,7 @@ namespace Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
// they must have a possibility to meet (normal/heroic difficulty)
|
// they must have a possibility to meet (normal/heroic difficulty)
|
||||||
if (!master.spawnDifficulties.Intersect(slave.spawnDifficulties).Any())
|
if (!master.SpawnDifficulties.Intersect(slave.SpawnDifficulties).Any())
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "LinkedRespawn: Creature '{0}' linking to '{1}' with not corresponding spawnMask", guidLow, linkedGuidLow);
|
Log.outError(LogFilter.Sql, "LinkedRespawn: Creature '{0}' linking to '{1}' with not corresponding spawnMask", guidLow, linkedGuidLow);
|
||||||
return false;
|
return false;
|
||||||
@@ -3748,7 +3813,7 @@ namespace Game
|
|||||||
CreatureData data = GetCreatureData(spawnId);
|
CreatureData data = GetCreatureData(spawnId);
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
RemoveCreatureFromGrid(spawnId, data);
|
RemoveCreatureFromGrid(data);
|
||||||
OnDeleteSpawnData(data);
|
OnDeleteSpawnData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4207,8 +4272,8 @@ namespace Game
|
|||||||
}
|
}
|
||||||
data.goState = (GameObjectState)gostate;
|
data.goState = (GameObjectState)gostate;
|
||||||
|
|
||||||
data.spawnDifficulties = ParseSpawnDifficulties(result.Read<string>(14), "gameobject", guid, data.MapId, spawnMasks.LookupByKey(data.MapId));
|
data.SpawnDifficulties = ParseSpawnDifficulties(result.Read<string>(14), "gameobject", guid, data.MapId, spawnMasks.LookupByKey(data.MapId));
|
||||||
if (data.spawnDifficulties.Empty())
|
if (data.SpawnDifficulties.Empty())
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, $"Table `creature` has creature (GUID: {guid}) that is not spawned in any difficulty, skipped.");
|
Log.outError(LogFilter.Sql, $"Table `creature` has creature (GUID: {guid}) that is not spawned in any difficulty, skipped.");
|
||||||
continue;
|
continue;
|
||||||
@@ -4324,7 +4389,7 @@ namespace Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (gameEvent == 0 && PoolId == 0) // if not this is to be managed by GameEvent System or Pool system
|
if (gameEvent == 0 && PoolId == 0) // if not this is to be managed by GameEvent System or Pool system
|
||||||
AddGameObjectToGrid(guid, data);
|
AddGameObjectToGrid(data);
|
||||||
|
|
||||||
gameObjectDataStorage[guid] = data;
|
gameObjectDataStorage[guid] = data;
|
||||||
++count;
|
++count;
|
||||||
@@ -4498,26 +4563,13 @@ namespace Game
|
|||||||
|
|
||||||
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} GameObjects for quests in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
|
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} GameObjects for quests in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
|
||||||
}
|
}
|
||||||
public void AddGameObjectToGrid(ulong guid, GameObjectData data)
|
public void AddGameObjectToGrid(GameObjectData data)
|
||||||
{
|
{
|
||||||
foreach (Difficulty difficulty in data.spawnDifficulties)
|
AddSpawnDataToGrid(data);
|
||||||
{
|
|
||||||
CellCoord cellCoord = GridDefines.ComputeCellCoord(data.SpawnPoint.GetPositionX(), data.SpawnPoint.GetPositionY());
|
|
||||||
var cellguids = CreateCellObjectGuids(data.MapId, difficulty, cellCoord.GetId());
|
|
||||||
cellguids.gameobjects.Add(guid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public void RemoveGameObjectFromGrid(ulong guid, GameObjectData data)
|
public void RemoveGameObjectFromGrid(GameObjectData data)
|
||||||
{
|
{
|
||||||
foreach (Difficulty difficulty in data.spawnDifficulties)
|
RemoveSpawnDataFromGrid(data);
|
||||||
{
|
|
||||||
CellCoord cellCoord = GridDefines.ComputeCellCoord(data.SpawnPoint.GetPositionX(), data.SpawnPoint.GetPositionY());
|
|
||||||
CellObjectGuids cellguids = GetCellObjectGuids(data.MapId, difficulty, cellCoord.GetId());
|
|
||||||
if (cellguids == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cellguids.gameobjects.Remove(guid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public ulong AddGameObjectData(uint entry, uint mapId, Position pos, Quaternion rot, uint spawntimedelay)
|
public ulong AddGameObjectData(uint entry, uint mapId, Position pos, Quaternion rot, uint spawntimedelay)
|
||||||
{
|
{
|
||||||
@@ -4538,13 +4590,13 @@ namespace Game
|
|||||||
data.rotation = rot;
|
data.rotation = rot;
|
||||||
data.spawntimesecs = (int)spawntimedelay;
|
data.spawntimesecs = (int)spawntimedelay;
|
||||||
data.animprogress = 100;
|
data.animprogress = 100;
|
||||||
data.spawnDifficulties.Add(Difficulty.None);
|
data.SpawnDifficulties.Add(Difficulty.None);
|
||||||
data.goState = GameObjectState.Ready;
|
data.goState = GameObjectState.Ready;
|
||||||
data.artKit = (byte)(goinfo.type == GameObjectTypes.ControlZone ? 21 : 0);
|
data.artKit = (byte)(goinfo.type == GameObjectTypes.ControlZone ? 21 : 0);
|
||||||
data.dbData = false;
|
data.dbData = false;
|
||||||
data.spawnGroupData = GetLegacySpawnGroup();
|
data.spawnGroupData = GetLegacySpawnGroup();
|
||||||
|
|
||||||
AddGameObjectToGrid(spawnId, data);
|
AddGameObjectToGrid(data);
|
||||||
|
|
||||||
// Spawn if necessary (loaded grids only)
|
// Spawn if necessary (loaded grids only)
|
||||||
// We use spawn coords to spawn
|
// We use spawn coords to spawn
|
||||||
@@ -4582,7 +4634,7 @@ namespace Game
|
|||||||
GameObjectData data = GetGameObjectData(spawnId);
|
GameObjectData data = GetGameObjectData(spawnId);
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
RemoveGameObjectFromGrid(spawnId, data);
|
RemoveGameObjectFromGrid(data);
|
||||||
OnDeleteSpawnData(data);
|
OnDeleteSpawnData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10666,6 +10718,7 @@ namespace Game
|
|||||||
//Maps
|
//Maps
|
||||||
public Dictionary<uint, GameTele> gameTeleStorage = new();
|
public Dictionary<uint, GameTele> gameTeleStorage = new();
|
||||||
Dictionary<(uint mapId, Difficulty difficulty), Dictionary<uint, CellObjectGuids>> mapObjectGuidsStore = new();
|
Dictionary<(uint mapId, Difficulty difficulty), Dictionary<uint, CellObjectGuids>> mapObjectGuidsStore = new();
|
||||||
|
Dictionary<(uint mapId, Difficulty diffuculty, uint phaseId), Dictionary<uint, CellObjectGuids>> mapPersonalObjectGuidsStore = new();
|
||||||
Dictionary<uint, InstanceTemplate> instanceTemplateStorage = new();
|
Dictionary<uint, InstanceTemplate> instanceTemplateStorage = new();
|
||||||
public MultiMap<uint, GraveYardData> GraveYardStorage = new();
|
public MultiMap<uint, GraveYardData> GraveYardStorage = new();
|
||||||
List<ushort> _transportMaps = new();
|
List<ushort> _transportMaps = new();
|
||||||
@@ -11064,6 +11117,32 @@ namespace Game
|
|||||||
{
|
{
|
||||||
public SortedSet<ulong> creatures = new();
|
public SortedSet<ulong> creatures = new();
|
||||||
public SortedSet<ulong> gameobjects = new();
|
public SortedSet<ulong> gameobjects = new();
|
||||||
|
|
||||||
|
public void AddSpawn(SpawnData data)
|
||||||
|
{
|
||||||
|
switch (data.type)
|
||||||
|
{
|
||||||
|
case SpawnObjectType.Creature:
|
||||||
|
creatures.Add(data.SpawnId);
|
||||||
|
break;
|
||||||
|
case SpawnObjectType.GameObject:
|
||||||
|
gameobjects.Add(data.SpawnId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveSpawn(SpawnData data)
|
||||||
|
{
|
||||||
|
switch (data.type)
|
||||||
|
{
|
||||||
|
case SpawnObjectType.Creature:
|
||||||
|
creatures.Remove(data.SpawnId);
|
||||||
|
break;
|
||||||
|
case SpawnObjectType.GameObject:
|
||||||
|
gameobjects.Remove(data.SpawnId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GameTele
|
public class GameTele
|
||||||
|
|||||||
+29
-1
@@ -461,6 +461,9 @@ namespace Game.Maps
|
|||||||
EnsureGridLoaded(cell);
|
EnsureGridLoaded(cell);
|
||||||
Grid grid = GetGrid(cell.GetGridX(), cell.GetGridY());
|
Grid grid = GetGrid(cell.GetGridX(), cell.GetGridY());
|
||||||
|
|
||||||
|
if (obj.IsPlayer())
|
||||||
|
GetMultiPersonalPhaseTracker().LoadGrid(obj.GetPhaseShift(), grid, this, cell);
|
||||||
|
|
||||||
// refresh grid state & timer
|
// refresh grid state & timer
|
||||||
if (grid.GetGridState() != GridState.Active)
|
if (grid.GetGridState() != GridState.Active)
|
||||||
{
|
{
|
||||||
@@ -526,6 +529,11 @@ namespace Game.Maps
|
|||||||
EnsureGridLoaded(new Cell(x, y));
|
EnsureGridLoaded(new Cell(x, y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void LoadGridForActiveObject(float x, float y, WorldObject obj)
|
||||||
|
{
|
||||||
|
EnsureGridLoadedForActiveObject(new Cell(x, y), obj);
|
||||||
|
}
|
||||||
|
|
||||||
public virtual bool AddPlayerToMap(Player player, bool initPlayer = true)
|
public virtual bool AddPlayerToMap(Player player, bool initPlayer = true)
|
||||||
{
|
{
|
||||||
CellCoord cellCoord = GridDefines.ComputeCellCoord(player.GetPositionX(), player.GetPositionY());
|
CellCoord cellCoord = GridDefines.ComputeCellCoord(player.GetPositionX(), player.GetPositionY());
|
||||||
@@ -563,6 +571,12 @@ namespace Game.Maps
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdatePersonalPhasesForPlayer(Player player)
|
||||||
|
{
|
||||||
|
Cell cell = new(player.GetPositionX(), player.GetPositionY());
|
||||||
|
GetMultiPersonalPhaseTracker().OnOwnerPhaseChanged(player, GetGrid(cell.GetGridX(), cell.GetGridY()), this, cell);
|
||||||
|
}
|
||||||
|
|
||||||
void InitializeObject(WorldObject obj)
|
void InitializeObject(WorldObject obj)
|
||||||
{
|
{
|
||||||
if (!obj.IsTypeId(TypeId.Unit) || !obj.IsTypeId(TypeId.GameObject))
|
if (!obj.IsTypeId(TypeId.Unit) || !obj.IsTypeId(TypeId.GameObject))
|
||||||
@@ -823,6 +837,9 @@ namespace Game.Maps
|
|||||||
_weatherUpdateTimer.Reset();
|
_weatherUpdateTimer.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update phase shift objects
|
||||||
|
GetMultiPersonalPhaseTracker().Update(this, diff);
|
||||||
|
|
||||||
MoveAllCreaturesInMoveList();
|
MoveAllCreaturesInMoveList();
|
||||||
MoveAllGameObjectsInMoveList();
|
MoveAllGameObjectsInMoveList();
|
||||||
MoveAllAreaTriggersInMoveList();
|
MoveAllAreaTriggersInMoveList();
|
||||||
@@ -930,6 +947,8 @@ namespace Game.Maps
|
|||||||
player.UpdateZone(MapConst.InvalidZone, 0);
|
player.UpdateZone(MapConst.InvalidZone, 0);
|
||||||
Global.ScriptMgr.OnPlayerLeaveMap(this, player);
|
Global.ScriptMgr.OnPlayerLeaveMap(this, player);
|
||||||
|
|
||||||
|
GetMultiPersonalPhaseTracker().MarkAllPhasesForDeletion(player.GetGUID());
|
||||||
|
|
||||||
player.CombatStop();
|
player.CombatStop();
|
||||||
|
|
||||||
bool inWorld = player.IsInWorld;
|
bool inWorld = player.IsInWorld;
|
||||||
@@ -955,6 +974,8 @@ namespace Game.Maps
|
|||||||
if (obj.IsActiveObject())
|
if (obj.IsActiveObject())
|
||||||
RemoveFromActive(obj);
|
RemoveFromActive(obj);
|
||||||
|
|
||||||
|
GetMultiPersonalPhaseTracker().UnregisterTrackedObject(obj);
|
||||||
|
|
||||||
if (!inWorld) // if was in world, RemoveFromWorld() called DestroyForNearbyPlayers()
|
if (!inWorld) // if was in world, RemoveFromWorld() called DestroyForNearbyPlayers()
|
||||||
obj.DestroyForNearbyPlayers(); // previous obj.UpdateObjectVisibility(true)
|
obj.DestroyForNearbyPlayers(); // previous obj.UpdateObjectVisibility(true)
|
||||||
|
|
||||||
@@ -1575,6 +1596,9 @@ namespace Game.Maps
|
|||||||
|
|
||||||
RemoveAllObjectsInRemoveList();
|
RemoveAllObjectsInRemoveList();
|
||||||
|
|
||||||
|
// After removing all objects from the map, purge empty tracked phases
|
||||||
|
GetMultiPersonalPhaseTracker().UnloadGrid(grid);
|
||||||
|
|
||||||
{
|
{
|
||||||
ObjectGridUnloader worker = new();
|
ObjectGridUnloader worker = new();
|
||||||
var visitor = new Visitor(worker, GridMapTypeMask.AllGrid);
|
var visitor = new Visitor(worker, GridMapTypeMask.AllGrid);
|
||||||
@@ -3789,7 +3813,7 @@ namespace Game.Maps
|
|||||||
public InstanceMap ToInstanceMap() { return IsDungeon() ? (this as InstanceMap) : null; }
|
public InstanceMap ToInstanceMap() { return IsDungeon() ? (this as InstanceMap) : null; }
|
||||||
public BattlegroundMap ToBattlegroundMap() { return IsBattlegroundOrArena() ? (this as BattlegroundMap) : null; }
|
public BattlegroundMap ToBattlegroundMap() { return IsBattlegroundOrArena() ? (this as BattlegroundMap) : null; }
|
||||||
|
|
||||||
void Balance()
|
public void Balance()
|
||||||
{
|
{
|
||||||
_dynamicTree.Balance();
|
_dynamicTree.Balance();
|
||||||
}
|
}
|
||||||
@@ -4118,6 +4142,8 @@ namespace Game.Maps
|
|||||||
return map != null;
|
return map != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MultiPersonalPhaseTracker GetMultiPersonalPhaseTracker() { return _multiPersonalPhaseTracker; }
|
||||||
|
|
||||||
#region Scripts
|
#region Scripts
|
||||||
|
|
||||||
// Put scripts in the execution queue
|
// Put scripts in the execution queue
|
||||||
@@ -5086,6 +5112,8 @@ namespace Game.Maps
|
|||||||
|
|
||||||
public delegate void FarSpellCallback(Map map);
|
public delegate void FarSpellCallback(Map map);
|
||||||
Queue<FarSpellCallback> _farSpellCallbacks = new();
|
Queue<FarSpellCallback> _farSpellCallbacks = new();
|
||||||
|
|
||||||
|
MultiPersonalPhaseTracker _multiPersonalPhaseTracker;
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,16 +22,71 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace Game.Maps
|
namespace Game.Maps
|
||||||
{
|
{
|
||||||
class ObjectGridLoader : Notifier
|
class ObjectGridLoaderBase : Notifier
|
||||||
{
|
{
|
||||||
public ObjectGridLoader(Grid grid, Map map, Cell cell)
|
internal Cell i_cell;
|
||||||
|
internal Grid i_grid;
|
||||||
|
internal Map i_map;
|
||||||
|
internal uint i_gameObjects;
|
||||||
|
internal uint i_creatures;
|
||||||
|
internal uint i_corpses;
|
||||||
|
internal uint i_areaTriggers;
|
||||||
|
|
||||||
|
public ObjectGridLoaderBase(Grid grid, Map map, Cell cell)
|
||||||
{
|
{
|
||||||
i_cell = new Cell(cell);
|
i_cell = new Cell(cell);
|
||||||
|
|
||||||
i_grid = grid;
|
i_grid = grid;
|
||||||
i_map = map;
|
i_map = map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public uint GetLoadedCreatures() { return i_creatures; }
|
||||||
|
public uint GetLoadedGameObjects() { return i_gameObjects; }
|
||||||
|
public uint GetLoadedCorpses() { return i_corpses; }
|
||||||
|
public uint GetLoadedAreaTriggers() { return i_areaTriggers; }
|
||||||
|
|
||||||
|
internal void LoadHelper<T>(SortedSet<ulong> guid_set, CellCoord cell, ref uint count, Map map, uint phaseId = 0, ObjectGuid? phaseOwner = null) where T : WorldObject, new()
|
||||||
|
{
|
||||||
|
foreach (var guid in guid_set)
|
||||||
|
{
|
||||||
|
// Don't spawn at all if there's a respawn timer
|
||||||
|
if (!map.ShouldBeSpawnedOnGridLoad<T>(guid))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
T obj = new();
|
||||||
|
if (!obj.LoadFromDB(guid, map, false, phaseOwner.HasValue /*allowDuplicate*/))
|
||||||
|
{
|
||||||
|
obj.Dispose();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phaseOwner.HasValue)
|
||||||
|
{
|
||||||
|
PhasingHandler.InitDbPersonalOwnership(obj.GetPhaseShift(), phaseOwner.Value);
|
||||||
|
map.GetMultiPersonalPhaseTracker().RegisterTrackedObject(phaseId, phaseOwner.Value, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddObjectHelper(cell, ref count, map, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddObjectHelper<T>(CellCoord cellCoord, ref uint count, Map map, T obj) where T : WorldObject
|
||||||
|
{
|
||||||
|
var cell = new Cell(cellCoord);
|
||||||
|
map.AddToGrid(obj, cell);
|
||||||
|
obj.AddToWorld();
|
||||||
|
|
||||||
|
if (obj.IsCreature())
|
||||||
|
if (obj.IsActiveObject())
|
||||||
|
map.AddToActive(obj);
|
||||||
|
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ObjectGridLoader : ObjectGridLoaderBase
|
||||||
|
{
|
||||||
|
public ObjectGridLoader(Grid grid, Map map, Cell cell) : base(grid, map, cell) { }
|
||||||
|
|
||||||
public void LoadN()
|
public void LoadN()
|
||||||
{
|
{
|
||||||
i_creatures = 0;
|
i_creatures = 0;
|
||||||
@@ -53,7 +108,7 @@ namespace Game.Maps
|
|||||||
i_grid.VisitGrid(x, y, visitor);
|
i_grid.VisitGrid(x, y, visitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log.outDebug(LogFilter.Maps, "{0} GameObjects, {1} Creatures, and {2} Corpses/Bones loaded for grid {3} on map {4}", i_gameObjects, i_creatures, i_corpses, i_grid.GetGridId(), i_map.GetId());
|
Log.outDebug(LogFilter.Maps, $"{i_gameObjects} GameObjects, {i_creatures} Creatures, {i_areaTriggers} AreaTrriggers and {i_corpses} Corpses/Bones loaded for grid {i_grid.GetGridId()} on map {i_map.GetId()}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Visit(IList<GameObject> objs)
|
public override void Visit(IList<GameObject> objs)
|
||||||
@@ -85,51 +140,57 @@ namespace Game.Maps
|
|||||||
|
|
||||||
LoadHelper<AreaTrigger>(areaTriggers, cellCoord, ref i_areaTriggers, i_map);
|
LoadHelper<AreaTrigger>(areaTriggers, cellCoord, ref i_areaTriggers, i_map);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LoadHelper<T>(SortedSet<ulong> guid_set, CellCoord cell, ref uint count, Map map) where T : WorldObject, new()
|
class PersonalPhaseGridLoader : ObjectGridLoaderBase
|
||||||
|
{
|
||||||
|
uint _phaseId;
|
||||||
|
ObjectGuid _phaseOwner;
|
||||||
|
|
||||||
|
public PersonalPhaseGridLoader(Grid grid, Map map, Cell cell, ObjectGuid phaseOwner) : base(grid, map, cell)
|
||||||
{
|
{
|
||||||
foreach (var guid in guid_set)
|
_phaseId = 0;
|
||||||
|
_phaseOwner = phaseOwner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Visit(IList<GameObject> objs)
|
||||||
|
{
|
||||||
|
CellCoord cellCoord = i_cell.GetCellCoord();
|
||||||
|
CellObjectGuids cell_guids = Global.ObjectMgr.GetCellPersonalObjectGuids(i_map.GetId(), i_map.GetDifficultyID(), _phaseId, cellCoord.GetId());
|
||||||
|
if (cell_guids != null)
|
||||||
|
LoadHelper<GameObject>(cell_guids.gameobjects, cellCoord, ref i_gameObjects, i_map, _phaseId, _phaseOwner);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Visit(IList<Creature> objs)
|
||||||
|
{
|
||||||
|
CellCoord cellCoord = i_cell.GetCellCoord();
|
||||||
|
CellObjectGuids cell_guids = Global.ObjectMgr.GetCellPersonalObjectGuids(i_map.GetId(), i_map.GetDifficultyID(), _phaseId, cellCoord.GetId());
|
||||||
|
if (cell_guids != null)
|
||||||
|
LoadHelper<Creature>(cell_guids.creatures, cellCoord, ref i_creatures, i_map, _phaseId, _phaseOwner);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Load(uint phaseId)
|
||||||
|
{
|
||||||
|
_phaseId = phaseId;
|
||||||
|
i_cell.data.cell_y = 0;
|
||||||
|
for (uint x = 0; x < MapConst.MaxCells; ++x)
|
||||||
{
|
{
|
||||||
// Don't spawn at all if there's a respawn timer
|
i_cell.data.cell_x = x;
|
||||||
if (!map.ShouldBeSpawnedOnGridLoad<T>(guid))
|
for (uint y = 0; y < MapConst.MaxCells; ++y)
|
||||||
continue;
|
|
||||||
|
|
||||||
T obj = new();
|
|
||||||
if (!obj.LoadFromDB(guid, map, false, false))
|
|
||||||
{
|
{
|
||||||
obj.Dispose();
|
i_cell.data.cell_y = y;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
AddObjectHelper(cell, ref count, map, obj);
|
//Load creatures and game objects
|
||||||
|
var visitor = new Visitor(this, GridMapTypeMask.AllGrid);
|
||||||
|
i_grid.VisitGrid(x, y, visitor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddObjectHelper<T>(CellCoord cellCoord, ref uint count, Map map, T obj) where T : WorldObject
|
|
||||||
{
|
|
||||||
var cell = new Cell(cellCoord);
|
|
||||||
map.AddToGrid(obj, cell);
|
|
||||||
obj.AddToWorld();
|
|
||||||
|
|
||||||
if (obj.IsCreature())
|
|
||||||
if (obj.IsActiveObject())
|
|
||||||
map.AddToActive(obj);
|
|
||||||
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Cell i_cell;
|
|
||||||
public Grid i_grid;
|
|
||||||
public Map i_map;
|
|
||||||
uint i_gameObjects;
|
|
||||||
uint i_creatures;
|
|
||||||
public uint i_corpses;
|
|
||||||
uint i_areaTriggers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ObjectWorldLoader : Notifier
|
class ObjectWorldLoader : Notifier
|
||||||
{
|
{
|
||||||
public ObjectWorldLoader(ObjectGridLoader gloader)
|
public ObjectWorldLoader(ObjectGridLoaderBase gloader)
|
||||||
{
|
{
|
||||||
i_cell = gloader.i_cell;
|
i_cell = gloader.i_cell;
|
||||||
i_map = gloader.i_map;
|
i_map = gloader.i_map;
|
||||||
|
|||||||
@@ -38,14 +38,14 @@ namespace Game.Maps
|
|||||||
public uint PhaseGroup;
|
public uint PhaseGroup;
|
||||||
public int terrainSwapMap;
|
public int terrainSwapMap;
|
||||||
public int spawntimesecs;
|
public int spawntimesecs;
|
||||||
public List<Difficulty> spawnDifficulties;
|
public List<Difficulty> SpawnDifficulties;
|
||||||
public uint ScriptId;
|
public uint ScriptId;
|
||||||
|
|
||||||
public SpawnData(SpawnObjectType t) : base(t)
|
public SpawnData(SpawnObjectType t) : base(t)
|
||||||
{
|
{
|
||||||
SpawnPoint = new Position();
|
SpawnPoint = new Position();
|
||||||
terrainSwapMap = -1;
|
terrainSwapMap = -1;
|
||||||
spawnDifficulties = new List<Difficulty>();
|
SpawnDifficulties = new List<Difficulty>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SpawnObjectType TypeFor<T>()
|
public static SpawnObjectType TypeFor<T>()
|
||||||
|
|||||||
@@ -0,0 +1,220 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using Framework.Dynamic;
|
||||||
|
using Game.Entities;
|
||||||
|
using Game.Maps;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Game
|
||||||
|
{
|
||||||
|
class PersonalPhaseSpawns
|
||||||
|
{
|
||||||
|
public static TimeSpan DELETE_TIME_DEFAULT = TimeSpan.FromMinutes(1);
|
||||||
|
|
||||||
|
public List<WorldObject> Objects = new();
|
||||||
|
public List<ushort> Grids = new();
|
||||||
|
public Optional<TimeSpan> DurationRemaining;
|
||||||
|
|
||||||
|
public bool IsEmpty() { return Objects.Empty() && Grids.Empty(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
class PlayerPersonalPhasesTracker
|
||||||
|
{
|
||||||
|
Dictionary<uint, PersonalPhaseSpawns> _spawns = new();
|
||||||
|
|
||||||
|
public void RegisterTrackedObject(uint phaseId, WorldObject obj)
|
||||||
|
{
|
||||||
|
_spawns[phaseId].Objects.Add(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnregisterTrackedObject(WorldObject obj)
|
||||||
|
{
|
||||||
|
foreach (var spawns in _spawns.Values)
|
||||||
|
spawns.Objects.Remove(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnOwnerPhasesChanged(WorldObject owner)
|
||||||
|
{
|
||||||
|
PhaseShift phaseShift = owner.GetPhaseShift();
|
||||||
|
|
||||||
|
// Loop over all our tracked phases. If any don't exist - delete them
|
||||||
|
foreach (var (phaseId, spawns) in _spawns)
|
||||||
|
if (!spawns.DurationRemaining.HasValue && !phaseShift.HasPhase(phaseId))
|
||||||
|
spawns.DurationRemaining.Set(PersonalPhaseSpawns.DELETE_TIME_DEFAULT);
|
||||||
|
|
||||||
|
// loop over all owner phases. If any exist and marked for deletion - reset delete
|
||||||
|
foreach (var phaseRef in phaseShift.GetPhases())
|
||||||
|
{
|
||||||
|
PersonalPhaseSpawns spawns = _spawns.LookupByKey(phaseRef.Key);
|
||||||
|
if (spawns != null)
|
||||||
|
spawns.DurationRemaining.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MarkAllPhasesForDeletion()
|
||||||
|
{
|
||||||
|
foreach (var spawns in _spawns.Values)
|
||||||
|
spawns.DurationRemaining.Set(PersonalPhaseSpawns.DELETE_TIME_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(Map map, uint diff)
|
||||||
|
{
|
||||||
|
foreach (var itr in _spawns.ToList())
|
||||||
|
{
|
||||||
|
if (itr.Value.DurationRemaining.HasValue)
|
||||||
|
{
|
||||||
|
itr.Value.DurationRemaining.Value = itr.Value.DurationRemaining.Value - TimeSpan.FromMilliseconds(diff);
|
||||||
|
if (itr.Value.DurationRemaining.Value <= TimeSpan.Zero)
|
||||||
|
{
|
||||||
|
DespawnPhase(map, itr.Value);
|
||||||
|
_spawns.Remove(itr.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsGridLoadedForPhase(uint gridId, uint phaseId)
|
||||||
|
{
|
||||||
|
PersonalPhaseSpawns spawns = _spawns.LookupByKey(phaseId);
|
||||||
|
if (spawns != null)
|
||||||
|
return spawns.Grids.Contains((ushort)gridId);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetGridLoadedForPhase(uint gridId, uint phaseId)
|
||||||
|
{
|
||||||
|
if (!_spawns.ContainsKey(phaseId))
|
||||||
|
_spawns[phaseId] = new();
|
||||||
|
|
||||||
|
PersonalPhaseSpawns group = _spawns[phaseId];
|
||||||
|
group.Grids.Add((ushort)gridId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetGridUnloaded(uint gridId)
|
||||||
|
{
|
||||||
|
foreach (var itr in _spawns.ToList())
|
||||||
|
{
|
||||||
|
itr.Value.Grids.Remove((ushort)gridId);
|
||||||
|
if (itr.Value.IsEmpty())
|
||||||
|
_spawns.Remove(itr.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DespawnPhase(Map map, PersonalPhaseSpawns spawns)
|
||||||
|
{
|
||||||
|
foreach (var obj in spawns.Objects)
|
||||||
|
map.AddObjectToRemoveList(obj);
|
||||||
|
|
||||||
|
spawns.Objects.Clear();
|
||||||
|
spawns.Grids.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEmpty() { return _spawns.Empty(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MultiPersonalPhaseTracker
|
||||||
|
{
|
||||||
|
Dictionary<ObjectGuid, PlayerPersonalPhasesTracker> _playerData = new();
|
||||||
|
|
||||||
|
public void LoadGrid(PhaseShift phaseShift, Grid grid, Map map, Cell cell)
|
||||||
|
{
|
||||||
|
if (!phaseShift.HasPersonalPhase())
|
||||||
|
return;
|
||||||
|
|
||||||
|
PersonalPhaseGridLoader loader = new(grid, map, cell, phaseShift.GetPersonalGuid());
|
||||||
|
PlayerPersonalPhasesTracker playerTracker = _playerData[phaseShift.GetPersonalGuid()];
|
||||||
|
|
||||||
|
foreach (var phaseRef in phaseShift.GetPhases())
|
||||||
|
{
|
||||||
|
if (!phaseRef.Value.IsPersonal())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!Global.ObjectMgr.HasPersonalSpawns(map.GetId(), map.GetDifficultyID(), phaseRef.Key))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (playerTracker.IsGridLoadedForPhase(grid.GetGridId(), phaseRef.Key))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Log.outDebug(LogFilter.Maps, $"Loading personal phase objects (phase {phaseRef.Key}) in {cell} for map {map.GetId()} instance {map.GetInstanceId()}");
|
||||||
|
|
||||||
|
loader.Load(phaseRef.Key);
|
||||||
|
|
||||||
|
playerTracker.SetGridLoadedForPhase(grid.GetGridId(), phaseRef.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loader.GetLoadedGameObjects() != 0)
|
||||||
|
map.Balance();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnloadGrid(Grid grid)
|
||||||
|
{
|
||||||
|
foreach (var itr in _playerData.ToList())
|
||||||
|
{
|
||||||
|
itr.Value.SetGridUnloaded(grid.GetGridId());
|
||||||
|
if (itr.Value.IsEmpty())
|
||||||
|
_playerData.Remove(itr.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RegisterTrackedObject(uint phaseId, ObjectGuid phaseOwner, WorldObject obj)
|
||||||
|
{
|
||||||
|
Cypher.Assert(phaseId != 0);
|
||||||
|
Cypher.Assert(!phaseOwner.IsEmpty());
|
||||||
|
Cypher.Assert(obj != null);
|
||||||
|
|
||||||
|
_playerData[phaseOwner].RegisterTrackedObject(phaseId, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnregisterTrackedObject(WorldObject obj)
|
||||||
|
{
|
||||||
|
PlayerPersonalPhasesTracker playerTracker = _playerData.LookupByKey(obj.GetPhaseShift().GetPersonalGuid());
|
||||||
|
if (playerTracker != null)
|
||||||
|
playerTracker.UnregisterTrackedObject(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnOwnerPhaseChanged(WorldObject phaseOwner, Grid grid, Map map, Cell cell)
|
||||||
|
{
|
||||||
|
PlayerPersonalPhasesTracker playerTracker = _playerData.LookupByKey(phaseOwner.GetGUID());
|
||||||
|
if (playerTracker != null)
|
||||||
|
playerTracker.OnOwnerPhasesChanged(phaseOwner);
|
||||||
|
|
||||||
|
if (grid != null)
|
||||||
|
LoadGrid(phaseOwner.GetPhaseShift(), grid, map, cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MarkAllPhasesForDeletion(ObjectGuid phaseOwner)
|
||||||
|
{
|
||||||
|
PlayerPersonalPhasesTracker playerTracker = _playerData.LookupByKey(phaseOwner);
|
||||||
|
if (playerTracker != null)
|
||||||
|
playerTracker.MarkAllPhasesForDeletion();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Update(Map map, uint diff)
|
||||||
|
{
|
||||||
|
foreach (var itr in _playerData.ToList())
|
||||||
|
{
|
||||||
|
itr.Value.Update(map, diff);
|
||||||
|
if (itr.Value.IsEmpty())
|
||||||
|
_playerData.Remove(itr.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -230,6 +230,15 @@ namespace Game
|
|||||||
PersonalGuid.Clear();
|
PersonalGuid.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool HasPersonalPhase()
|
||||||
|
{
|
||||||
|
foreach (PhaseRef phaseRef in GetPhases().Values)
|
||||||
|
if (phaseRef.IsPersonal())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public bool HasPhase(uint phaseId) { return Phases.ContainsKey(phaseId); }
|
public bool HasPhase(uint phaseId) { return Phases.ContainsKey(phaseId); }
|
||||||
public Dictionary<uint, PhaseRef> GetPhases() { return Phases; }
|
public Dictionary<uint, PhaseRef> GetPhases() { return Phases; }
|
||||||
|
|
||||||
@@ -239,6 +248,8 @@ namespace Game
|
|||||||
public bool HasUiWorldMapAreaIdSwap(uint uiWorldMapAreaId) { return UiMapPhaseIds.ContainsKey(uiWorldMapAreaId); }
|
public bool HasUiWorldMapAreaIdSwap(uint uiWorldMapAreaId) { return UiMapPhaseIds.ContainsKey(uiWorldMapAreaId); }
|
||||||
public Dictionary<uint, UiMapPhaseIdRef> GetUiMapPhaseIds() { return UiMapPhaseIds; }
|
public Dictionary<uint, UiMapPhaseIdRef> GetUiMapPhaseIds() { return UiMapPhaseIds; }
|
||||||
|
|
||||||
|
public ObjectGuid GetPersonalGuid() { return PersonalGuid; }
|
||||||
|
|
||||||
public PhaseShiftFlags Flags = PhaseShiftFlags.Unphased;
|
public PhaseShiftFlags Flags = PhaseShiftFlags.Unphased;
|
||||||
public ObjectGuid PersonalGuid;
|
public ObjectGuid PersonalGuid;
|
||||||
public Dictionary<uint, PhaseRef> Phases = new();
|
public Dictionary<uint, PhaseRef> Phases = new();
|
||||||
@@ -261,6 +272,8 @@ namespace Game
|
|||||||
AreaConditions = conditions;
|
AreaConditions = conditions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsPersonal() { return Flags.HasFlag(PhaseFlags.Personal); }
|
||||||
|
|
||||||
public PhaseFlags Flags;
|
public PhaseFlags Flags;
|
||||||
public int References;
|
public int References;
|
||||||
public List<Condition> AreaConditions;
|
public List<Condition> AreaConditions;
|
||||||
|
|||||||
@@ -487,6 +487,13 @@ namespace Game
|
|||||||
phaseShift.Flags = flags;
|
phaseShift.Flags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void InitDbPersonalOwnership(PhaseShift phaseShift, ObjectGuid personalGuid)
|
||||||
|
{
|
||||||
|
Cypher.Assert(phaseShift.IsDbPhaseShift);
|
||||||
|
Cypher.Assert(phaseShift.HasPersonalPhase());
|
||||||
|
phaseShift.PersonalGuid = personalGuid;
|
||||||
|
}
|
||||||
|
|
||||||
public static void InitDbVisibleMapId(PhaseShift phaseShift, int visibleMapId)
|
public static void InitDbVisibleMapId(PhaseShift phaseShift, int visibleMapId)
|
||||||
{
|
{
|
||||||
phaseShift.VisibleMapIds.Clear();
|
phaseShift.VisibleMapIds.Clear();
|
||||||
@@ -542,9 +549,20 @@ namespace Game
|
|||||||
UpdateVisibilityIfNeeded(obj, updateVisibility, true);
|
UpdateVisibilityIfNeeded(obj, updateVisibility, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PrintToChat(CommandHandler chat, PhaseShift phaseShift)
|
public static void PrintToChat(CommandHandler chat, WorldObject target)
|
||||||
{
|
{
|
||||||
chat.SendSysMessage(CypherStrings.PhaseshiftStatus, phaseShift.Flags, phaseShift.PersonalGuid.ToString());
|
PhaseShift phaseShift = target.GetPhaseShift();
|
||||||
|
|
||||||
|
string phaseOwnerName = "N/A";
|
||||||
|
if (phaseShift.HasPersonalPhase())
|
||||||
|
{
|
||||||
|
WorldObject personalGuid = Global.ObjAccessor.GetWorldObject(target, phaseShift.PersonalGuid);
|
||||||
|
if (personalGuid != null)
|
||||||
|
phaseOwnerName = personalGuid.GetName();
|
||||||
|
}
|
||||||
|
|
||||||
|
chat.SendSysMessage(CypherStrings.PhaseshiftStatus, phaseShift.Flags, phaseShift.PersonalGuid.ToString(), phaseOwnerName);
|
||||||
|
|
||||||
if (!phaseShift.Phases.Empty())
|
if (!phaseShift.Phases.Empty())
|
||||||
{
|
{
|
||||||
StringBuilder phases = new();
|
StringBuilder phases = new();
|
||||||
@@ -592,6 +610,15 @@ namespace Game
|
|||||||
return phases.ToString();
|
return phases.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsPersonalPhase(uint phaseId)
|
||||||
|
{
|
||||||
|
var phase = CliDB.PhaseStorage.LookupByKey(phaseId);
|
||||||
|
if (phase != null)
|
||||||
|
return phase.Flags.HasFlag(PhaseEntryFlags.Personal);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void UpdateVisibilityIfNeeded(WorldObject obj, bool updateVisibility, bool changed)
|
static void UpdateVisibilityIfNeeded(WorldObject obj, bool updateVisibility, bool changed)
|
||||||
{
|
{
|
||||||
if (changed && obj.IsInWorld)
|
if (changed && obj.IsInWorld)
|
||||||
|
|||||||
@@ -482,7 +482,7 @@ namespace Game
|
|||||||
var data = Global.ObjectMgr.GetCreatureData(guid);
|
var data = Global.ObjectMgr.GetCreatureData(guid);
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
Global.ObjectMgr.RemoveCreatureFromGrid(guid, data);
|
Global.ObjectMgr.RemoveCreatureFromGrid(data);
|
||||||
Map map = Global.MapMgr.FindMap(data.MapId, 0);
|
Map map = Global.MapMgr.FindMap(data.MapId, 0);
|
||||||
if (map != null && !map.Instanceable())
|
if (map != null && !map.Instanceable())
|
||||||
{
|
{
|
||||||
@@ -504,7 +504,7 @@ namespace Game
|
|||||||
var data = Global.ObjectMgr.GetGameObjectData(guid);
|
var data = Global.ObjectMgr.GetGameObjectData(guid);
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
Global.ObjectMgr.RemoveGameObjectFromGrid(guid, data);
|
Global.ObjectMgr.RemoveGameObjectFromGrid(data);
|
||||||
Map map = Global.MapMgr.FindMap(data.MapId, 0);
|
Map map = Global.MapMgr.FindMap(data.MapId, 0);
|
||||||
if (map != null && !map.Instanceable())
|
if (map != null && !map.Instanceable())
|
||||||
{
|
{
|
||||||
@@ -619,7 +619,7 @@ namespace Game
|
|||||||
CreatureData data = Global.ObjectMgr.GetCreatureData(obj.guid);
|
CreatureData data = Global.ObjectMgr.GetCreatureData(obj.guid);
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
Global.ObjectMgr.AddCreatureToGrid(obj.guid, data);
|
Global.ObjectMgr.AddCreatureToGrid(data);
|
||||||
|
|
||||||
// Spawn if necessary (loaded grids only)
|
// Spawn if necessary (loaded grids only)
|
||||||
Map map = Global.MapMgr.FindMap(data.MapId, 0);
|
Map map = Global.MapMgr.FindMap(data.MapId, 0);
|
||||||
@@ -634,7 +634,7 @@ namespace Game
|
|||||||
GameObjectData data = Global.ObjectMgr.GetGameObjectData(obj.guid);
|
GameObjectData data = Global.ObjectMgr.GetGameObjectData(obj.guid);
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
Global.ObjectMgr.AddGameObjectToGrid(obj.guid, data);
|
Global.ObjectMgr.AddGameObjectToGrid(data);
|
||||||
// Spawn if necessary (loaded grids only)
|
// Spawn if necessary (loaded grids only)
|
||||||
// this base map checked as non-instanced and then only existed
|
// this base map checked as non-instanced and then only existed
|
||||||
Map map = Global.MapMgr.FindMap(data.MapId, 0);
|
Map map = Global.MapMgr.FindMap(data.MapId, 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user