Core/Misc: Some refactoring
Port From (https://github.com/TrinityCore/TrinityCore/commit/94a79bac7a06aa0f931e9d651928de7eea0a8b5c)
This commit is contained in:
@@ -205,16 +205,20 @@ namespace Framework.Constants
|
|||||||
{
|
{
|
||||||
Creature = 0,
|
Creature = 0,
|
||||||
GameObject = 1,
|
GameObject = 1,
|
||||||
|
AreaTrigger = 2,
|
||||||
|
|
||||||
Max
|
NumSpawnTypesWithData,
|
||||||
|
NumSpawnTypes
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SpawnObjectTypeMask
|
public enum SpawnObjectTypeMask
|
||||||
{
|
{
|
||||||
Creature = (1 << SpawnObjectType.Creature),
|
Creature = (1 << SpawnObjectType.Creature),
|
||||||
GameObject = (1 << SpawnObjectType.GameObject),
|
GameObject = (1 << SpawnObjectType.GameObject),
|
||||||
|
AreaTrigger = (1 << SpawnObjectType.AreaTrigger),
|
||||||
|
|
||||||
All = (1 << SpawnObjectType.Max) - 1
|
WithData = (1 << SpawnObjectType.NumSpawnTypesWithData) - 1,
|
||||||
|
All = (1 << SpawnObjectType.NumSpawnTypes) - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
|
|||||||
@@ -866,25 +866,6 @@ namespace Framework.Constants
|
|||||||
DisplayMythic = 0x80 // Controls icon displayed on minimap when inside the instance
|
DisplayMythic = 0x80 // Controls icon displayed on minimap when inside the instance
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SpawnMask
|
|
||||||
{
|
|
||||||
Continent = (1 << Difficulty.None), // Any Maps Without Spawn Modes
|
|
||||||
|
|
||||||
DungeonNormal = (1 << Difficulty.Normal),
|
|
||||||
DungeonHeroic = (1 << Difficulty.Heroic),
|
|
||||||
DungeonAll = (DungeonNormal | DungeonHeroic),
|
|
||||||
|
|
||||||
Raid10Normal = (1 << Difficulty.Raid10N),
|
|
||||||
Raid25Normal = (1 << Difficulty.Raid25N),
|
|
||||||
RaidNormalAll = (Raid10Normal | Raid25Normal),
|
|
||||||
|
|
||||||
Raid10Heroic = (1 << Difficulty.Raid10HC),
|
|
||||||
Raid25Heroic = (1 << Difficulty.Raid25HC),
|
|
||||||
RaidHeroicAll = (Raid10Heroic | Raid25Heroic),
|
|
||||||
|
|
||||||
RaidAll = (RaidNormalAll | RaidHeroicAll)
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum MapFlags
|
public enum MapFlags
|
||||||
{
|
{
|
||||||
CanToggleDifficulty = 0x0100,
|
CanToggleDifficulty = 0x0100,
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ namespace Game.Chat
|
|||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
data.rotation.toEulerAnglesZYX(out float yaw, out float pitch, out float roll);
|
data.rotation.toEulerAnglesZYX(out float yaw, out float pitch, out float roll);
|
||||||
handler.SendSysMessage(CypherStrings.SpawninfoSpawnidLocation, data.spawnId, data.spawnPoint.GetPositionX(), data.spawnPoint.GetPositionY(), data.spawnPoint.GetPositionZ());
|
handler.SendSysMessage(CypherStrings.SpawninfoSpawnidLocation, data.SpawnId, data.SpawnPoint.GetPositionX(), data.SpawnPoint.GetPositionY(), data.SpawnPoint.GetPositionZ());
|
||||||
handler.SendSysMessage(CypherStrings.SpawninfoRotation, yaw, pitch, roll);
|
handler.SendSysMessage(CypherStrings.SpawninfoRotation, yaw, pitch, roll);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -645,9 +645,9 @@ namespace Game.Chat.Commands
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GridDefines.IsValidMapCoord(goData.spawnPoint) || Global.ObjectMgr.IsTransportMap(goData.spawnPoint.GetMapId()))
|
if (!GridDefines.IsValidMapCoord(goData.MapId, goData.SpawnPoint) || Global.ObjectMgr.IsTransportMap(goData.MapId))
|
||||||
{
|
{
|
||||||
handler.SendSysMessage(CypherStrings.InvalidTargetCoord, goData.spawnPoint.GetPositionX(), goData.spawnPoint.GetPositionY(), goData.spawnPoint.GetMapId());
|
handler.SendSysMessage(CypherStrings.InvalidTargetCoord, goData.SpawnPoint.GetPositionX(), goData.SpawnPoint.GetPositionY(), goData.MapId);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -657,7 +657,7 @@ namespace Game.Chat.Commands
|
|||||||
else
|
else
|
||||||
player.SaveRecallPosition(); // save only in non-flight case
|
player.SaveRecallPosition(); // save only in non-flight case
|
||||||
|
|
||||||
player.TeleportTo(goData.spawnPoint);
|
player.TeleportTo(new WorldLocation(goData.MapId, goData.SpawnPoint));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -580,31 +580,37 @@ namespace Game.Chat.Commands
|
|||||||
|
|
||||||
uint zoneId = player.GetZoneId();
|
uint zoneId = player.GetZoneId();
|
||||||
string zoneName = GetZoneName(zoneId, locale);
|
string zoneName = GetZoneName(zoneId, locale);
|
||||||
for (SpawnObjectType type = 0; type < SpawnObjectType.Max; type++)
|
for (SpawnObjectType type = 0; type < SpawnObjectType.NumSpawnTypes; type++)
|
||||||
{
|
{
|
||||||
if (range != 0)
|
if (range != 0)
|
||||||
handler.SendSysMessage(CypherStrings.ListRespawnsRange, type, range);
|
handler.SendSysMessage(CypherStrings.ListRespawnsRange, type, range);
|
||||||
else
|
else
|
||||||
handler.SendSysMessage(CypherStrings.ListRespawnsZone, type, zoneName, zoneId);
|
handler.SendSysMessage(CypherStrings.ListRespawnsZone, type, zoneName, zoneId);
|
||||||
|
|
||||||
handler.SendSysMessage(CypherStrings.ListRespawnsListheader);
|
handler.SendSysMessage(CypherStrings.ListRespawnsListheader);
|
||||||
List<RespawnInfo> respawns = new();
|
List<RespawnInfo> respawns = new();
|
||||||
map.GetRespawnInfo(respawns, (SpawnObjectTypeMask)(1 << (int)type));
|
map.GetRespawnInfo(respawns, (SpawnObjectTypeMask)(1 << (int)type));
|
||||||
foreach (RespawnInfo ri in respawns)
|
foreach (RespawnInfo ri in respawns)
|
||||||
{
|
{
|
||||||
SpawnData data = Global.ObjectMgr.GetSpawnData(ri.type, ri.spawnId);
|
SpawnMetadata data = Global.ObjectMgr.GetSpawnMetadata(ri.type, ri.spawnId);
|
||||||
if (data == null)
|
if (data == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
uint respawnZoneId = map.GetZoneId(PhasingHandler.EmptyPhaseShift, data.spawnPoint);
|
uint respawnZoneId = 0;
|
||||||
if (range != 0)
|
SpawnData edata = data.ToSpawnData();
|
||||||
|
if (edata != null)
|
||||||
{
|
{
|
||||||
if (!player.IsInDist(data.spawnPoint, range))
|
respawnZoneId = map.GetZoneId(PhasingHandler.EmptyPhaseShift, edata.SpawnPoint);
|
||||||
continue;
|
if (range != 0)
|
||||||
}
|
{
|
||||||
else
|
if (!player.IsInDist(edata.SpawnPoint, range))
|
||||||
{
|
continue;
|
||||||
if (zoneId != respawnZoneId)
|
}
|
||||||
continue;
|
else
|
||||||
|
{
|
||||||
|
if (zoneId != respawnZoneId)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint gridY = ri.gridId / MapConst.MaxGrids;
|
uint gridY = ri.gridId / MapConst.MaxGrids;
|
||||||
@@ -652,28 +658,28 @@ namespace Game.Chat.Commands
|
|||||||
foreach (var pair in Global.ObjectMgr.GetAllCreatureData())
|
foreach (var pair in Global.ObjectMgr.GetAllCreatureData())
|
||||||
{
|
{
|
||||||
SpawnData data = pair.Value;
|
SpawnData data = pair.Value;
|
||||||
if (data.spawnPoint.GetMapId() != mapId)
|
if (data.MapId != mapId)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CreatureTemplate cTemp = Global.ObjectMgr.GetCreatureTemplate(data.Id);
|
CreatureTemplate cTemp = Global.ObjectMgr.GetCreatureTemplate(data.Id);
|
||||||
if (cTemp == null)
|
if (cTemp == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (showAll || data.spawnPoint.IsInDist2d(player, 5000.0f))
|
if (showAll || data.SpawnPoint.IsInDist2d(player, 5000.0f))
|
||||||
handler.SendSysMessage($"Type: {data.type} | SpawnId: {data.spawnId} | Entry: {data.Id} ({cTemp.Name}) | X: {data.spawnPoint.GetPositionX():3} | Y: {data.spawnPoint.GetPositionY():3} | Z: {data.spawnPoint.GetPositionZ():3}");
|
handler.SendSysMessage($"Type: {data.type} | SpawnId: {data.SpawnId} | Entry: {data.Id} ({cTemp.Name}) | X: {data.SpawnPoint.GetPositionX():3} | Y: {data.SpawnPoint.GetPositionY():3} | Z: {data.SpawnPoint.GetPositionZ():3}");
|
||||||
}
|
}
|
||||||
foreach (var pair in Global.ObjectMgr.GetAllGameObjectData())
|
foreach (var pair in Global.ObjectMgr.GetAllGameObjectData())
|
||||||
{
|
{
|
||||||
SpawnData data = pair.Value;
|
SpawnData data = pair.Value;
|
||||||
if (data.spawnPoint.GetMapId() != mapId)
|
if (data.MapId != mapId)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
GameObjectTemplate goTemp = Global.ObjectMgr.GetGameObjectTemplate(data.Id);
|
GameObjectTemplate goTemp = Global.ObjectMgr.GetGameObjectTemplate(data.Id);
|
||||||
if (goTemp == null)
|
if (goTemp == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (showAll || data.spawnPoint.IsInDist2d(player, 5000.0f))
|
if (showAll || data.SpawnPoint.IsInDist2d(player, 5000.0f))
|
||||||
handler.SendSysMessage($"Type: {data.type} | SpawnId: {data.spawnId} | Entry: {data.Id} ({goTemp.name}) | X: {data.spawnPoint.GetPositionX():3} | Y: {data.spawnPoint.GetPositionY():3} | Z: {data.spawnPoint.GetPositionZ():3}");
|
handler.SendSysMessage($"Type: {data.type} | SpawnId: {data.SpawnId} | Entry: {data.Id} ({goTemp.name}) | X: {data.SpawnPoint.GetPositionX():3} | Y: {data.SpawnPoint.GetPositionY():3} | Z: {data.SpawnPoint.GetPositionZ():3}");
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ namespace Game.Chat
|
|||||||
|
|
||||||
CreatureData data = Global.ObjectMgr.GetCreatureData(target.GetSpawnId());
|
CreatureData data = Global.ObjectMgr.GetCreatureData(target.GetSpawnId());
|
||||||
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.GetPhaseShift());
|
||||||
|
|
||||||
@@ -233,14 +233,14 @@ namespace Game.Chat
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player.GetMapId() != data.spawnPoint.GetMapId())
|
if (player.GetMapId() != data.MapId)
|
||||||
{
|
{
|
||||||
handler.SendSysMessage(CypherStrings.CommandCreatureatsamemap, lowguid);
|
handler.SendSysMessage(CypherStrings.CommandCreatureatsamemap, lowguid);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Global.ObjectMgr.RemoveCreatureFromGrid(lowguid, data);
|
Global.ObjectMgr.RemoveCreatureFromGrid(lowguid, data);
|
||||||
data.spawnPoint.Relocate(player);
|
data.SpawnPoint.Relocate(player);
|
||||||
Global.ObjectMgr.AddCreatureToGrid(lowguid, data);
|
Global.ObjectMgr.AddCreatureToGrid(lowguid, data);
|
||||||
|
|
||||||
// update position in DB
|
// update position in DB
|
||||||
@@ -659,9 +659,9 @@ namespace Game.Chat
|
|||||||
{
|
{
|
||||||
ulong guid = map.GenerateLowGuid(HighGuid.Creature);
|
ulong guid = map.GenerateLowGuid(HighGuid.Creature);
|
||||||
CreatureData data = Global.ObjectMgr.NewOrExistCreatureData(guid);
|
CreatureData data = Global.ObjectMgr.NewOrExistCreatureData(guid);
|
||||||
data.spawnId = guid;
|
data.SpawnId = guid;
|
||||||
data.Id = id;
|
data.Id = id;
|
||||||
data.spawnPoint.Relocate(chr.GetTransOffsetX(), chr.GetTransOffsetY(), chr.GetTransOffsetZ(), chr.GetTransOffsetO());
|
data.SpawnPoint.Relocate(chr.GetTransOffsetX(), chr.GetTransOffsetY(), chr.GetTransOffsetZ(), chr.GetTransOffsetO());
|
||||||
data.spawnGroupData = new();
|
data.spawnGroupData = new();
|
||||||
|
|
||||||
Creature creaturePassenger = trans.CreateNPCPassenger(guid, data);
|
Creature creaturePassenger = trans.CreateNPCPassenger(guid, data);
|
||||||
|
|||||||
@@ -319,10 +319,11 @@ namespace Game.DataStorage
|
|||||||
|
|
||||||
AreaTriggerSpawn spawn = new();
|
AreaTriggerSpawn spawn = new();
|
||||||
spawn.SpawnId = spawnId;
|
spawn.SpawnId = spawnId;
|
||||||
spawn.Id = areaTriggerId;
|
spawn.MapId = location.GetMapId();
|
||||||
spawn.Location = new WorldLocation(location);
|
spawn.TriggerId = areaTriggerId;
|
||||||
|
spawn.SpawnPoint = new Position(location);
|
||||||
|
|
||||||
spawn.PhaseUseFlags = templates.Read<byte>(8);
|
spawn.PhaseUseFlags = (PhaseUseFlagsValues)templates.Read<byte>(8);
|
||||||
spawn.PhaseId = templates.Read<uint>(9);
|
spawn.PhaseId = templates.Read<uint>(9);
|
||||||
spawn.PhaseGroup = templates.Read<uint>(10);
|
spawn.PhaseGroup = templates.Read<uint>(10);
|
||||||
|
|
||||||
@@ -334,13 +335,14 @@ namespace Game.DataStorage
|
|||||||
}
|
}
|
||||||
|
|
||||||
spawn.ScriptId = Global.ObjectMgr.GetScriptId(templates.Read<string>(18));
|
spawn.ScriptId = Global.ObjectMgr.GetScriptId(templates.Read<string>(18));
|
||||||
|
spawn.spawnGroupData = Global.ObjectMgr.GetLegacySpawnGroup();
|
||||||
|
|
||||||
// Add the trigger to a map::cell map, which is later used by GridLoader to query
|
// Add the trigger to a map::cell map, which is later used by GridLoader to query
|
||||||
CellCoord cellCoord = GridDefines.ComputeCellCoord(spawn.Location.GetPositionX(), spawn.Location.GetPositionY());
|
CellCoord cellCoord = GridDefines.ComputeCellCoord(spawn.SpawnPoint.GetPositionX(), spawn.SpawnPoint.GetPositionY());
|
||||||
if (!_areaTriggerSpawnsByLocation.ContainsKey((spawn.Location.GetMapId(), cellCoord.GetId())))
|
if (!_areaTriggerSpawnsByLocation.ContainsKey((spawn.MapId, cellCoord.GetId())))
|
||||||
_areaTriggerSpawnsByLocation[(spawn.Location.GetMapId(), cellCoord.GetId())] = new SortedSet<ulong>();
|
_areaTriggerSpawnsByLocation[(spawn.MapId, cellCoord.GetId())] = new SortedSet<ulong>();
|
||||||
|
|
||||||
_areaTriggerSpawnsByLocation[(spawn.Location.GetMapId(), cellCoord.GetId())].Add(spawnId);
|
_areaTriggerSpawnsByLocation[(spawn.MapId, cellCoord.GetId())].Add(spawnId);
|
||||||
|
|
||||||
// add the position to the map
|
// add the position to the map
|
||||||
_areaTriggerSpawnsBySpawnId[spawnId] = spawn;
|
_areaTriggerSpawnsBySpawnId[spawnId] = spawn;
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ namespace Game.Entities
|
|||||||
if (!IsInWorld)
|
if (!IsInWorld)
|
||||||
{
|
{
|
||||||
GetMap().GetObjectsStore().Add(GetGUID(), this);
|
GetMap().GetObjectsStore().Add(GetGUID(), this);
|
||||||
|
if (_spawnId != 0)
|
||||||
|
GetMap().GetAreaTriggerBySpawnIdStore().Add(_spawnId, this);
|
||||||
|
|
||||||
base.AddToWorld();
|
base.AddToWorld();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,6 +77,9 @@ namespace Game.Entities
|
|||||||
_ai.OnRemove();
|
_ai.OnRemove();
|
||||||
|
|
||||||
base.RemoveFromWorld();
|
base.RemoveFromWorld();
|
||||||
|
if (_spawnId != 0)
|
||||||
|
GetMap().GetAreaTriggerBySpawnIdStore().Remove(_spawnId, this);
|
||||||
|
|
||||||
GetMap().GetObjectsStore().Remove(GetGUID());
|
GetMap().GetObjectsStore().Remove(GetGUID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -236,7 +242,7 @@ namespace Game.Entities
|
|||||||
if (position == null)
|
if (position == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
AreaTriggerTemplate areaTriggerTemplate = Global.AreaTriggerDataStorage.GetAreaTriggerTemplate(position.Id);
|
AreaTriggerTemplate areaTriggerTemplate = Global.AreaTriggerDataStorage.GetAreaTriggerTemplate(position.TriggerId);
|
||||||
if (areaTriggerTemplate == null)
|
if (areaTriggerTemplate == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -246,7 +252,7 @@ namespace Game.Entities
|
|||||||
bool CreateServer(Map map, AreaTriggerTemplate areaTriggerTemplate, AreaTriggerSpawn position)
|
bool CreateServer(Map map, AreaTriggerTemplate areaTriggerTemplate, AreaTriggerSpawn position)
|
||||||
{
|
{
|
||||||
SetMap(map);
|
SetMap(map);
|
||||||
Relocate(position.Location);
|
Relocate(position.SpawnPoint);
|
||||||
if (!IsPositionValid())
|
if (!IsPositionValid())
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.AreaTrigger, $"AreaTriggerServer (id {areaTriggerTemplate.Id}) not created. Invalid coordinates (X: {GetPositionX()} Y: {GetPositionY()})");
|
Log.outError(LogFilter.AreaTrigger, $"AreaTriggerServer (id {areaTriggerTemplate.Id}) not created. Invalid coordinates (X: {GetPositionX()} Y: {GetPositionY()})");
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
using Framework.Constants;
|
using Framework.Constants;
|
||||||
using Framework.Dynamic;
|
using Framework.Dynamic;
|
||||||
|
using Game.Maps;
|
||||||
using Game.Networking;
|
using Game.Networking;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -319,18 +320,12 @@ namespace Game.Entities
|
|||||||
public uint ScriptId;
|
public uint ScriptId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AreaTriggerSpawn
|
public class AreaTriggerSpawn : SpawnData
|
||||||
{
|
{
|
||||||
public ulong SpawnId;
|
public AreaTriggerId TriggerId;
|
||||||
public AreaTriggerId Id;
|
|
||||||
public WorldLocation Location;
|
|
||||||
public uint PhaseId;
|
|
||||||
public uint PhaseGroup;
|
|
||||||
public byte PhaseUseFlags;
|
|
||||||
|
|
||||||
public AreaTriggerShapeInfo Shape = new();
|
public AreaTriggerShapeInfo Shape = new();
|
||||||
|
|
||||||
public uint ScriptId;
|
public AreaTriggerSpawn() : base(SpawnObjectType.AreaTrigger) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct AreaTriggerAction
|
public struct AreaTriggerAction
|
||||||
|
|||||||
@@ -793,7 +793,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
PhasingHandler.InitDbPhaseShift(GetPhaseShift(), data.phaseUseFlags, data.phaseId, data.phaseGroup);
|
PhasingHandler.InitDbPhaseShift(GetPhaseShift(), data.PhaseUseFlags, data.PhaseId, data.PhaseGroup);
|
||||||
PhasingHandler.InitDbVisibleMapId(GetPhaseShift(), data.terrainSwapMap);
|
PhasingHandler.InitDbVisibleMapId(GetPhaseShift(), data.terrainSwapMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1246,18 +1246,24 @@ namespace Game.Entities
|
|||||||
dynamicflags = 0;
|
dynamicflags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.spawnId == 0)
|
if (data.SpawnId == 0)
|
||||||
data.spawnId = m_spawnId;
|
data.SpawnId = m_spawnId;
|
||||||
Cypher.Assert(data.spawnId == m_spawnId);
|
Cypher.Assert(data.SpawnId == m_spawnId);
|
||||||
|
|
||||||
data.Id = GetEntry();
|
data.Id = GetEntry();
|
||||||
data.displayid = displayId;
|
data.displayid = displayId;
|
||||||
data.equipmentId = (sbyte)GetCurrentEquipmentId();
|
data.equipmentId = (sbyte)GetCurrentEquipmentId();
|
||||||
|
|
||||||
if (GetTransport() == null)
|
if (GetTransport() == null)
|
||||||
data.spawnPoint.WorldRelocate(this);
|
{
|
||||||
|
data.MapId = GetMapId();
|
||||||
|
data.SpawnPoint.Relocate(this);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
data.spawnPoint.WorldRelocate(mapid, GetTransOffsetX(), GetTransOffsetY(), GetTransOffsetZ(), GetTransOffsetO());
|
{
|
||||||
|
data.MapId = mapid;
|
||||||
|
data.SpawnPoint.Relocate(GetTransOffsetX(), GetTransOffsetY(), GetTransOffsetZ(), GetTransOffsetO());
|
||||||
|
}
|
||||||
|
|
||||||
data.spawntimesecs = (int)m_respawnDelay;
|
data.spawntimesecs = (int)m_respawnDelay;
|
||||||
// prevent add data integrity problems
|
// prevent add data integrity problems
|
||||||
@@ -1277,8 +1283,8 @@ namespace Game.Entities
|
|||||||
if (data.spawnGroupData == null)
|
if (data.spawnGroupData == null)
|
||||||
data.spawnGroupData = Global.ObjectMgr.GetDefaultSpawnGroup();
|
data.spawnGroupData = Global.ObjectMgr.GetDefaultSpawnGroup();
|
||||||
|
|
||||||
data.phaseId = GetDBPhase() > 0 ? (uint)GetDBPhase() : data.phaseId;
|
data.PhaseId = GetDBPhase() > 0 ? (uint)GetDBPhase() : data.PhaseId;
|
||||||
data.phaseGroup = GetDBPhase() < 0 ? (uint)-GetDBPhase() : data.phaseGroup;
|
data.PhaseGroup = GetDBPhase() < 0 ? (uint)-GetDBPhase() : data.PhaseGroup;
|
||||||
|
|
||||||
// update in DB
|
// update in DB
|
||||||
SQLTransaction trans = new();
|
SQLTransaction trans = new();
|
||||||
@@ -1294,8 +1300,8 @@ namespace Game.Entities
|
|||||||
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);
|
||||||
stmt.AddValue(index++, GetCurrentEquipmentId());
|
stmt.AddValue(index++, GetCurrentEquipmentId());
|
||||||
stmt.AddValue(index++, GetPositionX());
|
stmt.AddValue(index++, GetPositionX());
|
||||||
@@ -1610,7 +1616,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
SQLTransaction trans = new();
|
SQLTransaction trans = new();
|
||||||
|
|
||||||
Global.MapMgr.DoForAllMapsWithMapId(data.spawnPoint.GetMapId(), map =>
|
Global.MapMgr.DoForAllMapsWithMapId(data.MapId, map =>
|
||||||
{
|
{
|
||||||
// despawn all active creatures, and remove their respawns
|
// despawn all active creatures, and remove their respawns
|
||||||
List<Creature> toUnload = new();
|
List<Creature> toUnload = new();
|
||||||
@@ -2448,7 +2454,7 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
if (m_creatureData != null)
|
if (m_creatureData != null)
|
||||||
{
|
{
|
||||||
m_creatureData.spawnPoint.GetPosition(out x, out y, out z, out ori);
|
m_creatureData.SpawnPoint.GetPosition(out x, out y, out z, out ori);
|
||||||
dist = m_creatureData.spawndist;
|
dist = m_creatureData.spawndist;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2459,7 +2465,7 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsSpawnedOnTransport() { return m_creatureData != null && m_creatureData.spawnPoint.GetMapId() != GetMapId(); }
|
bool IsSpawnedOnTransport() { return m_creatureData != null && m_creatureData.MapId != GetMapId(); }
|
||||||
|
|
||||||
void InitializeMovementFlags()
|
void InitializeMovementFlags()
|
||||||
{
|
{
|
||||||
@@ -3157,7 +3163,7 @@ namespace Game.Entities
|
|||||||
m_respawnradius = data.spawndist;
|
m_respawnradius = data.spawndist;
|
||||||
m_respawnDelay = (uint)data.spawntimesecs;
|
m_respawnDelay = (uint)data.spawntimesecs;
|
||||||
|
|
||||||
if (!Create(map.GenerateLowGuid(HighGuid.Creature), map, data.Id, data.spawnPoint, data, 0, !m_respawnCompatibilityMode))
|
if (!Create(map.GenerateLowGuid(HighGuid.Creature), map, data.Id, data.SpawnPoint, data, 0, !m_respawnCompatibilityMode))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//We should set first home position, because then AI calls home movement
|
//We should set first home position, because then AI calls home movement
|
||||||
@@ -3198,9 +3204,9 @@ namespace Game.Entities
|
|||||||
m_deathState = DeathState.Dead;
|
m_deathState = DeathState.Dead;
|
||||||
if (CanFly())
|
if (CanFly())
|
||||||
{
|
{
|
||||||
float tz = map.GetHeight(GetPhaseShift(), data.spawnPoint, true, MapConst.MaxFallDistance);
|
float tz = map.GetHeight(GetPhaseShift(), data.SpawnPoint, true, MapConst.MaxFallDistance);
|
||||||
if (data.spawnPoint.GetPositionZ() - tz > 0.1f && GridDefines.IsValidMapCoord(tz))
|
if (data.SpawnPoint.GetPositionZ() - tz > 0.1f && GridDefines.IsValidMapCoord(tz))
|
||||||
Relocate(data.spawnPoint.GetPositionX(), data.spawnPoint.GetPositionY(), tz);
|
Relocate(data.SpawnPoint.GetPositionX(), data.SpawnPoint.GetPositionY(), tz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1034,12 +1034,13 @@ namespace Game.Entities
|
|||||||
// update in loaded data (changing data only in this place)
|
// update in loaded data (changing data only in this place)
|
||||||
GameObjectData data = Global.ObjectMgr.NewOrExistGameObjectData(m_spawnId);
|
GameObjectData data = Global.ObjectMgr.NewOrExistGameObjectData(m_spawnId);
|
||||||
|
|
||||||
if (data.spawnId == 0)
|
if (data.SpawnId == 0)
|
||||||
data.spawnId = m_spawnId;
|
data.SpawnId = m_spawnId;
|
||||||
Cypher.Assert(data.spawnId == m_spawnId);
|
Cypher.Assert(data.SpawnId == m_spawnId);
|
||||||
|
|
||||||
data.Id = GetEntry();
|
data.Id = GetEntry();
|
||||||
data.spawnPoint.WorldRelocate(this);
|
data.MapId = GetMapId();
|
||||||
|
data.SpawnPoint.Relocate(this);
|
||||||
data.rotation = m_localRotation;
|
data.rotation = m_localRotation;
|
||||||
data.spawntimesecs = (int)(m_spawnedByDefault ? m_respawnDelayTime : -m_respawnDelayTime);
|
data.spawntimesecs = (int)(m_spawnedByDefault ? m_respawnDelayTime : -m_respawnDelayTime);
|
||||||
data.animprogress = GetGoAnimProgress();
|
data.animprogress = GetGoAnimProgress();
|
||||||
@@ -1049,8 +1050,8 @@ namespace Game.Entities
|
|||||||
if (data.spawnGroupData == null)
|
if (data.spawnGroupData == null)
|
||||||
data.spawnGroupData = Global.ObjectMgr.GetDefaultSpawnGroup();
|
data.spawnGroupData = Global.ObjectMgr.GetDefaultSpawnGroup();
|
||||||
|
|
||||||
data.phaseId = GetDBPhase() > 0 ? (uint)GetDBPhase() : data.phaseId;
|
data.PhaseId = GetDBPhase() > 0 ? (uint)GetDBPhase() : data.PhaseId;
|
||||||
data.phaseGroup = GetDBPhase() < 0 ? (uint)-GetDBPhase() : data.phaseGroup;
|
data.PhaseGroup = GetDBPhase() < 0 ? (uint)-GetDBPhase() : data.PhaseGroup;
|
||||||
|
|
||||||
// Update in DB
|
// Update in DB
|
||||||
byte index = 0;
|
byte index = 0;
|
||||||
@@ -1063,8 +1064,8 @@ namespace Game.Entities
|
|||||||
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());
|
||||||
stmt.AddValue(index++, GetPositionY());
|
stmt.AddValue(index++, GetPositionY());
|
||||||
stmt.AddValue(index++, GetPositionZ());
|
stmt.AddValue(index++, GetPositionZ());
|
||||||
@@ -1096,10 +1097,10 @@ namespace Game.Entities
|
|||||||
|
|
||||||
m_spawnId = spawnId;
|
m_spawnId = spawnId;
|
||||||
m_respawnCompatibilityMode = ((data.spawnGroupData.flags & SpawnGroupFlags.CompatibilityMode) != 0);
|
m_respawnCompatibilityMode = ((data.spawnGroupData.flags & SpawnGroupFlags.CompatibilityMode) != 0);
|
||||||
if (!Create(entry, map, data.spawnPoint, data.rotation, animprogress, go_state, artKit, !m_respawnCompatibilityMode, spawnId))
|
if (!Create(entry, map, data.SpawnPoint, data.rotation, animprogress, go_state, artKit, !m_respawnCompatibilityMode, spawnId))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
PhasingHandler.InitDbPhaseShift(GetPhaseShift(), data.phaseUseFlags, data.phaseId, data.phaseGroup);
|
PhasingHandler.InitDbPhaseShift(GetPhaseShift(), data.PhaseUseFlags, data.PhaseId, data.PhaseGroup);
|
||||||
PhasingHandler.InitDbVisibleMapId(GetPhaseShift(), data.terrainSwapMap);
|
PhasingHandler.InitDbVisibleMapId(GetPhaseShift(), data.terrainSwapMap);
|
||||||
|
|
||||||
if (data.spawntimesecs >= 0)
|
if (data.spawntimesecs >= 0)
|
||||||
@@ -1154,7 +1155,7 @@ namespace Game.Entities
|
|||||||
|
|
||||||
SQLTransaction trans = new();
|
SQLTransaction trans = new();
|
||||||
|
|
||||||
Global.MapMgr.DoForAllMapsWithMapId(data.spawnPoint.GetMapId(), map =>
|
Global.MapMgr.DoForAllMapsWithMapId(data.MapId, map =>
|
||||||
{
|
{
|
||||||
// despawn all active objects, and remove their respawns
|
// despawn all active objects, and remove their respawns
|
||||||
List<GameObject> toUnload = new();
|
List<GameObject> toUnload = new();
|
||||||
@@ -2805,7 +2806,7 @@ namespace Game.Entities
|
|||||||
public void GetRespawnPosition(out float x, out float y, out float z, out float ori)
|
public void GetRespawnPosition(out float x, out float y, out float z, out float ori)
|
||||||
{
|
{
|
||||||
if (m_goData != null)
|
if (m_goData != null)
|
||||||
m_goData.spawnPoint.GetPosition(out x, out y, out z, out ori);
|
m_goData.SpawnPoint.GetPosition(out x, out y, out z, out ori);
|
||||||
else
|
else
|
||||||
GetPosition(out x, out y, out z, out ori);
|
GetPosition(out x, out y, out z, out ori);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -326,7 +326,7 @@ namespace Game.Entities
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
float x, y, z, o;
|
float x, y, z, o;
|
||||||
data.spawnPoint.GetPosition(out x, out y, out z, out o);
|
data.SpawnPoint.GetPosition(out x, out y, out z, out o);
|
||||||
|
|
||||||
creature.SetTransport(this);
|
creature.SetTransport(this);
|
||||||
creature.m_movementInfo.transport.guid = GetGUID();
|
creature.m_movementInfo.transport.guid = GetGUID();
|
||||||
@@ -347,7 +347,7 @@ namespace Game.Entities
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
PhasingHandler.InitDbPhaseShift(creature.GetPhaseShift(), data.phaseUseFlags, data.phaseId, data.phaseGroup);
|
PhasingHandler.InitDbPhaseShift(creature.GetPhaseShift(), data.PhaseUseFlags, data.PhaseId, data.PhaseGroup);
|
||||||
PhasingHandler.InitDbVisibleMapId(creature.GetPhaseShift(), data.terrainSwapMap);
|
PhasingHandler.InitDbVisibleMapId(creature.GetPhaseShift(), data.terrainSwapMap);
|
||||||
|
|
||||||
if (!map.AddToMap(creature))
|
if (!map.AddToMap(creature))
|
||||||
@@ -369,7 +369,7 @@ namespace Game.Entities
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
float x, y, z, o;
|
float x, y, z, o;
|
||||||
data.spawnPoint.GetPosition(out x, out y, out z, out o);
|
data.SpawnPoint.GetPosition(out x, out y, out z, out o);
|
||||||
|
|
||||||
go.SetTransport(this);
|
go.SetTransport(this);
|
||||||
go.m_movementInfo.transport.guid = GetGUID();
|
go.m_movementInfo.transport.guid = GetGUID();
|
||||||
@@ -385,7 +385,7 @@ namespace Game.Entities
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
PhasingHandler.InitDbPhaseShift(go.GetPhaseShift(), data.phaseUseFlags, data.phaseId, data.phaseGroup);
|
PhasingHandler.InitDbPhaseShift(go.GetPhaseShift(), data.PhaseUseFlags, data.PhaseId, data.PhaseGroup);
|
||||||
PhasingHandler.InitDbVisibleMapId(go.GetPhaseShift(), data.terrainSwapMap);
|
PhasingHandler.InitDbVisibleMapId(go.GetPhaseShift(), data.terrainSwapMap);
|
||||||
|
|
||||||
if (!map.AddToMap(go))
|
if (!map.AddToMap(go))
|
||||||
|
|||||||
@@ -1124,7 +1124,7 @@ namespace Game
|
|||||||
// get the creature data from the low guid to get the entry, to be able to find out the whole guid
|
// get the creature data from the low guid to get the entry, to be able to find out the whole guid
|
||||||
CreatureData data = Global.ObjectMgr.GetCreatureData(guid);
|
CreatureData data = Global.ObjectMgr.GetCreatureData(guid);
|
||||||
if (data != null)
|
if (data != null)
|
||||||
creaturesByMap.Add(data.spawnPoint.GetMapId(), guid);
|
creaturesByMap.Add(data.MapId, guid);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var key in creaturesByMap.Keys)
|
foreach (var key in creaturesByMap.Keys)
|
||||||
@@ -1191,10 +1191,10 @@ namespace Game
|
|||||||
Global.ObjectMgr.AddCreatureToGrid(guid, data);
|
Global.ObjectMgr.AddCreatureToGrid(guid, data);
|
||||||
|
|
||||||
// Spawn if necessary (loaded grids only)
|
// Spawn if necessary (loaded grids only)
|
||||||
Map map = Global.MapMgr.CreateBaseMap(data.spawnPoint.GetMapId());
|
Map map = Global.MapMgr.CreateBaseMap(data.MapId);
|
||||||
map.RemoveRespawnTime(SpawnObjectType.Creature, guid);
|
map.RemoveRespawnTime(SpawnObjectType.Creature, guid);
|
||||||
// We use spawn coords to spawn
|
// We use spawn coords to spawn
|
||||||
if (map != null && !map.Instanceable() && map.IsGridLoaded(data.spawnPoint))
|
if (map != null && !map.Instanceable() && map.IsGridLoaded(data.SpawnPoint))
|
||||||
Creature.CreateCreatureFromDB(guid, map);
|
Creature.CreateCreatureFromDB(guid, map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1215,10 +1215,10 @@ namespace Game
|
|||||||
Global.ObjectMgr.AddGameObjectToGrid(guid, data);
|
Global.ObjectMgr.AddGameObjectToGrid(guid, 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.spawnPoint.GetMapId());
|
Map map = Global.MapMgr.CreateBaseMap(data.MapId);
|
||||||
map.RemoveRespawnTime(SpawnObjectType.GameObject, guid);
|
map.RemoveRespawnTime(SpawnObjectType.GameObject, guid);
|
||||||
// We use current coords to unspawn, not spawn coords since creature can have changed grid
|
// We use current coords to unspawn, not spawn coords since creature can have changed grid
|
||||||
if (map != null && !map.Instanceable() && map.IsGridLoaded(data.spawnPoint))
|
if (map != null && !map.Instanceable() && map.IsGridLoaded(data.SpawnPoint))
|
||||||
{
|
{
|
||||||
GameObject pGameobject = GameObject.CreateGameObjectFromDB(guid, map, false);
|
GameObject pGameobject = GameObject.CreateGameObjectFromDB(guid, map, false);
|
||||||
// @todo find out when it is add to map
|
// @todo find out when it is add to map
|
||||||
@@ -1266,7 +1266,7 @@ namespace Game
|
|||||||
{
|
{
|
||||||
Global.ObjectMgr.RemoveCreatureFromGrid(guid, data);
|
Global.ObjectMgr.RemoveCreatureFromGrid(guid, data);
|
||||||
|
|
||||||
Global.MapMgr.DoForAllMapsWithMapId(data.spawnPoint.GetMapId(), map =>
|
Global.MapMgr.DoForAllMapsWithMapId(data.MapId, map =>
|
||||||
{
|
{
|
||||||
map.RemoveRespawnTime(SpawnObjectType.Creature, guid);
|
map.RemoveRespawnTime(SpawnObjectType.Creature, guid);
|
||||||
var creatureBounds = map.GetCreatureBySpawnIdStore().LookupByKey(guid);
|
var creatureBounds = map.GetCreatureBySpawnIdStore().LookupByKey(guid);
|
||||||
@@ -1294,7 +1294,7 @@ namespace Game
|
|||||||
{
|
{
|
||||||
Global.ObjectMgr.RemoveGameObjectFromGrid(guid, data);
|
Global.ObjectMgr.RemoveGameObjectFromGrid(guid, data);
|
||||||
|
|
||||||
Global.MapMgr.DoForAllMapsWithMapId(data.spawnPoint.GetMapId(), map =>
|
Global.MapMgr.DoForAllMapsWithMapId(data.MapId, map =>
|
||||||
{
|
{
|
||||||
map.RemoveRespawnTime(SpawnObjectType.GameObject, guid);
|
map.RemoveRespawnTime(SpawnObjectType.GameObject, guid);
|
||||||
var gameobjectBounds = map.GetGameObjectBySpawnIdStore().LookupByKey(guid);
|
var gameobjectBounds = map.GetGameObjectBySpawnIdStore().LookupByKey(guid);
|
||||||
@@ -1325,7 +1325,7 @@ namespace Game
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Update if spawned
|
// Update if spawned
|
||||||
Global.MapMgr.DoForAllMapsWithMapId(data.spawnPoint.GetMapId(), map =>
|
Global.MapMgr.DoForAllMapsWithMapId(data.MapId, map =>
|
||||||
{
|
{
|
||||||
var creatureBounds = map.GetCreatureBySpawnIdStore().LookupByKey(tuple.Item1);
|
var creatureBounds = map.GetCreatureBySpawnIdStore().LookupByKey(tuple.Item1);
|
||||||
foreach (var creature in creatureBounds)
|
foreach (var creature in creatureBounds)
|
||||||
|
|||||||
@@ -2892,8 +2892,8 @@ namespace Game
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapRecord map = CliDB.MapStorage.LookupByKey(master.spawnPoint.GetMapId());
|
MapRecord map = CliDB.MapStorage.LookupByKey(master.MapId);
|
||||||
if (map == null || !map.Instanceable() || (master.spawnPoint.GetMapId() != slave.spawnPoint.GetMapId()))
|
if (map == null || !map.Instanceable() || (master.MapId != slave.MapId))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Creature '{0}' linking to '{1}' on an unpermitted map.", guidLow, linkedGuidLow);
|
Log.outError(LogFilter.Sql, "Creature '{0}' linking to '{1}' on an unpermitted map.", guidLow, linkedGuidLow);
|
||||||
error = true;
|
error = true;
|
||||||
@@ -2908,8 +2908,8 @@ namespace Game
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
guid = ObjectGuid.Create(HighGuid.Creature, slave.spawnPoint.GetMapId(), slave.Id, guidLow);
|
guid = ObjectGuid.Create(HighGuid.Creature, slave.MapId, slave.Id, guidLow);
|
||||||
linkedGuid = ObjectGuid.Create(HighGuid.Creature, master.spawnPoint.GetMapId(), master.Id, linkedGuidLow);
|
linkedGuid = ObjectGuid.Create(HighGuid.Creature, master.MapId, master.Id, linkedGuidLow);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CreatureLinkedRespawnType.CreatureToGO:
|
case CreatureLinkedRespawnType.CreatureToGO:
|
||||||
@@ -2930,8 +2930,8 @@ namespace Game
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapRecord map = CliDB.MapStorage.LookupByKey(master.spawnPoint.GetMapId());
|
MapRecord map = CliDB.MapStorage.LookupByKey(master.MapId);
|
||||||
if (map == null || !map.Instanceable() || (master.spawnPoint.GetMapId() != slave.spawnPoint.GetMapId()))
|
if (map == null || !map.Instanceable() || (master.MapId != slave.MapId))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Creature '{0}' linking to '{1}' on an unpermitted map.", guidLow, linkedGuidLow);
|
Log.outError(LogFilter.Sql, "Creature '{0}' linking to '{1}' on an unpermitted map.", guidLow, linkedGuidLow);
|
||||||
error = true;
|
error = true;
|
||||||
@@ -2946,8 +2946,8 @@ namespace Game
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
guid = ObjectGuid.Create(HighGuid.Creature, slave.spawnPoint.GetMapId(), slave.Id, guidLow);
|
guid = ObjectGuid.Create(HighGuid.Creature, slave.MapId, slave.Id, guidLow);
|
||||||
linkedGuid = ObjectGuid.Create(HighGuid.GameObject, master.spawnPoint.GetMapId(), master.Id, linkedGuidLow);
|
linkedGuid = ObjectGuid.Create(HighGuid.GameObject, master.MapId, master.Id, linkedGuidLow);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CreatureLinkedRespawnType.GOToGO:
|
case CreatureLinkedRespawnType.GOToGO:
|
||||||
@@ -2968,8 +2968,8 @@ namespace Game
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapRecord map = CliDB.MapStorage.LookupByKey(master.spawnPoint.GetMapId());
|
MapRecord map = CliDB.MapStorage.LookupByKey(master.MapId);
|
||||||
if (map == null || !map.Instanceable() || (master.spawnPoint.GetMapId() != slave.spawnPoint.GetMapId()))
|
if (map == null || !map.Instanceable() || (master.MapId != slave.MapId))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Creature '{0}' linking to '{1}' on an unpermitted map.", guidLow, linkedGuidLow);
|
Log.outError(LogFilter.Sql, "Creature '{0}' linking to '{1}' on an unpermitted map.", guidLow, linkedGuidLow);
|
||||||
error = true;
|
error = true;
|
||||||
@@ -2984,8 +2984,8 @@ namespace Game
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
guid = ObjectGuid.Create(HighGuid.GameObject, slave.spawnPoint.GetMapId(), slave.Id, guidLow);
|
guid = ObjectGuid.Create(HighGuid.GameObject, slave.MapId, slave.Id, guidLow);
|
||||||
linkedGuid = ObjectGuid.Create(HighGuid.GameObject, master.spawnPoint.GetMapId(), master.Id, linkedGuidLow);
|
linkedGuid = ObjectGuid.Create(HighGuid.GameObject, master.MapId, master.Id, linkedGuidLow);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CreatureLinkedRespawnType.GOToCreature:
|
case CreatureLinkedRespawnType.GOToCreature:
|
||||||
@@ -3006,8 +3006,8 @@ namespace Game
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapRecord map = CliDB.MapStorage.LookupByKey(master.spawnPoint.GetMapId());
|
MapRecord map = CliDB.MapStorage.LookupByKey(master.MapId);
|
||||||
if (map == null || !map.Instanceable() || (master.spawnPoint.GetMapId() != slave.spawnPoint.GetMapId()))
|
if (map == null || !map.Instanceable() || (master.MapId != slave.MapId))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Creature '{0}' linking to '{1}' on an unpermitted map.", guidLow, linkedGuidLow);
|
Log.outError(LogFilter.Sql, "Creature '{0}' linking to '{1}' on an unpermitted map.", guidLow, linkedGuidLow);
|
||||||
error = true;
|
error = true;
|
||||||
@@ -3022,8 +3022,8 @@ namespace Game
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
guid = ObjectGuid.Create(HighGuid.GameObject, slave.spawnPoint.GetMapId(), slave.Id, guidLow);
|
guid = ObjectGuid.Create(HighGuid.GameObject, slave.MapId, slave.Id, guidLow);
|
||||||
linkedGuid = ObjectGuid.Create(HighGuid.Creature, master.spawnPoint.GetMapId(), master.Id, linkedGuidLow);
|
linkedGuid = ObjectGuid.Create(HighGuid.Creature, master.MapId, master.Id, linkedGuidLow);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3408,9 +3408,10 @@ namespace Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
CreatureData data = new();
|
CreatureData data = new();
|
||||||
data.spawnId = guid;
|
data.SpawnId = guid;
|
||||||
data.Id = entry;
|
data.Id = entry;
|
||||||
data.spawnPoint = new WorldLocation(result.Read<ushort>(2), result.Read<float>(3), result.Read<float>(4), result.Read<float>(5), result.Read<float>(6));
|
data.MapId = result.Read<ushort>(2);
|
||||||
|
data.SpawnPoint = new Position(result.Read<float>(3), result.Read<float>(4), result.Read<float>(5), result.Read<float>(6));
|
||||||
data.displayid = result.Read<uint>(7);
|
data.displayid = result.Read<uint>(7);
|
||||||
data.equipmentId = result.Read<sbyte>(8);
|
data.equipmentId = result.Read<sbyte>(8);
|
||||||
data.spawntimesecs = result.Read<int>(9);
|
data.spawntimesecs = result.Read<int>(9);
|
||||||
@@ -3419,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.spawnPoint.GetMapId(), spawnMasks.LookupByKey(data.spawnPoint.GetMapId()));
|
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);
|
||||||
@@ -3427,17 +3428,17 @@ namespace Game
|
|||||||
data.unit_flags2 = result.Read<uint>(20);
|
data.unit_flags2 = result.Read<uint>(20);
|
||||||
data.unit_flags3 = result.Read<uint>(21);
|
data.unit_flags3 = result.Read<uint>(21);
|
||||||
data.dynamicflags = result.Read<uint>(22);
|
data.dynamicflags = result.Read<uint>(22);
|
||||||
data.phaseUseFlags = (PhaseUseFlagsValues)result.Read<byte>(23);
|
data.PhaseUseFlags = (PhaseUseFlagsValues)result.Read<byte>(23);
|
||||||
data.phaseId = result.Read<uint>(24);
|
data.PhaseId = result.Read<uint>(24);
|
||||||
data.phaseGroup = result.Read<uint>(25);
|
data.PhaseGroup = result.Read<uint>(25);
|
||||||
data.terrainSwapMap = result.Read<int>(26);
|
data.terrainSwapMap = result.Read<int>(26);
|
||||||
data.ScriptId = GetScriptId(result.Read<string>(27));
|
data.ScriptId = GetScriptId(result.Read<string>(27));
|
||||||
data.spawnGroupData = _spawnGroupDataStorage[IsTransportMap(data.spawnPoint.GetMapId()) ? 1 : 0u]; // transport spawns default to compatibility group
|
data.spawnGroupData = _spawnGroupDataStorage[IsTransportMap(data.MapId) ? 1 : 0u]; // transport spawns default to compatibility group
|
||||||
|
|
||||||
var mapEntry = CliDB.MapStorage.LookupByKey(data.spawnPoint.GetMapId());
|
var mapEntry = CliDB.MapStorage.LookupByKey(data.MapId);
|
||||||
if (mapEntry == null)
|
if (mapEntry == null)
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Table `creature` have creature (GUID: {0}) that spawned at not existed map (Id: {1}), skipped.", guid, data.spawnPoint.GetMapId());
|
Log.outError(LogFilter.Sql, "Table `creature` have creature (GUID: {0}) that spawned at not existed map (Id: {1}), skipped.", guid, data.MapId);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3498,40 +3499,40 @@ namespace Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Convert.ToBoolean(data.phaseUseFlags & ~PhaseUseFlagsValues.All))
|
if (Convert.ToBoolean(data.PhaseUseFlags & ~PhaseUseFlagsValues.All))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Table `creature` have creature (GUID: {0} Entry: {1}) has unknown `phaseUseFlags` set, removed unknown value.", guid, data.Id);
|
Log.outError(LogFilter.Sql, "Table `creature` have creature (GUID: {0} Entry: {1}) has unknown `phaseUseFlags` set, removed unknown value.", guid, data.Id);
|
||||||
data.phaseUseFlags &= PhaseUseFlagsValues.All;
|
data.PhaseUseFlags &= PhaseUseFlagsValues.All;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.phaseUseFlags.HasAnyFlag(PhaseUseFlagsValues.AlwaysVisible) && data.phaseUseFlags.HasAnyFlag(PhaseUseFlagsValues.Inverse))
|
if (data.PhaseUseFlags.HasAnyFlag(PhaseUseFlagsValues.AlwaysVisible) && data.PhaseUseFlags.HasAnyFlag(PhaseUseFlagsValues.Inverse))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Table `creature` have creature (GUID: {0} Entry: {1}) has both `phaseUseFlags` PHASE_USE_FLAGS_ALWAYS_VISIBLE and PHASE_USE_FLAGS_INVERSE," +
|
Log.outError(LogFilter.Sql, "Table `creature` have creature (GUID: {0} Entry: {1}) has both `phaseUseFlags` PHASE_USE_FLAGS_ALWAYS_VISIBLE and PHASE_USE_FLAGS_INVERSE," +
|
||||||
" removing PHASE_USE_FLAGS_INVERSE.", guid, data.Id);
|
" removing PHASE_USE_FLAGS_INVERSE.", guid, data.Id);
|
||||||
data.phaseUseFlags &= ~PhaseUseFlagsValues.Inverse;
|
data.PhaseUseFlags &= ~PhaseUseFlagsValues.Inverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.phaseGroup != 0 && data.phaseId != 0)
|
if (data.PhaseGroup != 0 && data.PhaseId != 0)
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Table `creature` have creature (GUID: {0} Entry: {1}) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, data.Id);
|
Log.outError(LogFilter.Sql, "Table `creature` have creature (GUID: {0} Entry: {1}) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, data.Id);
|
||||||
data.phaseGroup = 0;
|
data.PhaseGroup = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.phaseId != 0)
|
if (data.PhaseId != 0)
|
||||||
{
|
{
|
||||||
if (!CliDB.PhaseStorage.ContainsKey(data.phaseId))
|
if (!CliDB.PhaseStorage.ContainsKey(data.PhaseId))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Table `creature` have creature (GUID: {0} Entry: {1}) with `phaseid` {2} does not exist, set to 0", guid, data.Id, data.phaseId);
|
Log.outError(LogFilter.Sql, "Table `creature` have creature (GUID: {0} Entry: {1}) with `phaseid` {2} does not exist, set to 0", guid, data.Id, data.PhaseId);
|
||||||
data.phaseId = 0;
|
data.PhaseId = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.phaseGroup != 0)
|
if (data.PhaseGroup != 0)
|
||||||
{
|
{
|
||||||
if (Global.DB2Mgr.GetPhasesForGroup(data.phaseGroup).Empty())
|
if (Global.DB2Mgr.GetPhasesForGroup(data.PhaseGroup).Empty())
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Table `creature` have creature (GUID: {0} Entry: {1}) with `phasegroup` {2} does not exist, set to 0", guid, data.Id, data.phaseGroup);
|
Log.outError(LogFilter.Sql, "Table `creature` have creature (GUID: {0} Entry: {1}) with `phasegroup` {2} does not exist, set to 0", guid, data.Id, data.PhaseGroup);
|
||||||
data.phaseGroup = 0;
|
data.PhaseGroup = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3543,7 +3544,7 @@ namespace Game
|
|||||||
Log.outError(LogFilter.Sql, "Table `creature` have creature (GUID: {0} Entry: {1}) with `terrainSwapMap` {2} does not exist, set to -1", guid, data.Id, data.terrainSwapMap);
|
Log.outError(LogFilter.Sql, "Table `creature` have creature (GUID: {0} Entry: {1}) with `terrainSwapMap` {2} does not exist, set to -1", guid, data.Id, data.terrainSwapMap);
|
||||||
data.terrainSwapMap = -1;
|
data.terrainSwapMap = -1;
|
||||||
}
|
}
|
||||||
else if (terrainSwapEntry.ParentMapID != data.spawnPoint.GetMapId())
|
else if (terrainSwapEntry.ParentMapID != data.MapId)
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Table `creature` have creature (GUID: {0} Entry: {1}) with `terrainSwapMap` {2} which cannot be used on spawn map, set to -1", guid, data.Id, data.terrainSwapMap);
|
Log.outError(LogFilter.Sql, "Table `creature` have creature (GUID: {0} Entry: {1}) with `terrainSwapMap` {2} which cannot be used on spawn map, set to -1", guid, data.Id, data.terrainSwapMap);
|
||||||
data.terrainSwapMap = -1;
|
data.terrainSwapMap = -1;
|
||||||
@@ -3553,7 +3554,7 @@ namespace Game
|
|||||||
if (WorldConfig.GetBoolValue(WorldCfg.CalculateCreatureZoneAreaData))
|
if (WorldConfig.GetBoolValue(WorldCfg.CalculateCreatureZoneAreaData))
|
||||||
{
|
{
|
||||||
PhasingHandler.InitDbVisibleMapId(phaseShift, data.terrainSwapMap);
|
PhasingHandler.InitDbVisibleMapId(phaseShift, data.terrainSwapMap);
|
||||||
Global.MapMgr.GetZoneAndAreaId(phaseShift, out uint zoneId, out uint areaId, data.spawnPoint);
|
Global.MapMgr.GetZoneAndAreaId(phaseShift, out uint zoneId, out uint areaId, data.MapId, data.SpawnPoint);
|
||||||
|
|
||||||
PreparedStatement stmt = DB.World.GetPreparedStatement(WorldStatements.UPD_CREATURE_ZONE_AREA_DATA);
|
PreparedStatement stmt = DB.World.GetPreparedStatement(WorldStatements.UPD_CREATURE_ZONE_AREA_DATA);
|
||||||
stmt.AddValue(0, zoneId);
|
stmt.AddValue(0, zoneId);
|
||||||
@@ -3578,8 +3579,8 @@ namespace Game
|
|||||||
{
|
{
|
||||||
foreach (Difficulty difficulty in data.spawnDifficulties)
|
foreach (Difficulty difficulty in data.spawnDifficulties)
|
||||||
{
|
{
|
||||||
CellCoord cellCoord = GridDefines.ComputeCellCoord(data.spawnPoint.GetPositionX(), data.spawnPoint.GetPositionY());
|
CellCoord cellCoord = GridDefines.ComputeCellCoord(data.SpawnPoint.GetPositionX(), data.SpawnPoint.GetPositionY());
|
||||||
var cellguids = CreateCellObjectGuids(data.spawnPoint.GetMapId(), difficulty, cellCoord.GetId());
|
var cellguids = CreateCellObjectGuids(data.MapId, difficulty, cellCoord.GetId());
|
||||||
cellguids.creatures.Add(guid);
|
cellguids.creatures.Add(guid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3587,8 +3588,8 @@ namespace Game
|
|||||||
{
|
{
|
||||||
foreach (Difficulty difficulty in data.spawnDifficulties)
|
foreach (Difficulty difficulty in data.spawnDifficulties)
|
||||||
{
|
{
|
||||||
CellCoord cellCoord = GridDefines.ComputeCellCoord(data.spawnPoint.GetPositionX(), data.spawnPoint.GetPositionY());
|
CellCoord cellCoord = GridDefines.ComputeCellCoord(data.SpawnPoint.GetPositionX(), data.SpawnPoint.GetPositionY());
|
||||||
CellObjectGuids cellguids = GetCellObjectGuids(data.spawnPoint.GetMapId(), difficulty, cellCoord.GetId());
|
CellObjectGuids cellguids = GetCellObjectGuids(data.MapId, difficulty, cellCoord.GetId());
|
||||||
if (cellguids == null)
|
if (cellguids == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -3611,9 +3612,10 @@ namespace Game
|
|||||||
|
|
||||||
ulong spawnId = GenerateCreatureSpawnId();
|
ulong spawnId = GenerateCreatureSpawnId();
|
||||||
CreatureData data = NewOrExistCreatureData(spawnId);
|
CreatureData data = NewOrExistCreatureData(spawnId);
|
||||||
data.spawnId = spawnId;
|
data.SpawnId = spawnId;
|
||||||
data.Id = entry;
|
data.Id = entry;
|
||||||
data.spawnPoint.WorldRelocate(mapId, pos);
|
data.MapId = mapId;
|
||||||
|
data.SpawnPoint.Relocate(pos);
|
||||||
data.displayid = 0;
|
data.displayid = 0;
|
||||||
data.equipmentId = 0;
|
data.equipmentId = 0;
|
||||||
|
|
||||||
@@ -3633,7 +3635,7 @@ namespace Game
|
|||||||
AddCreatureToGrid(spawnId, data);
|
AddCreatureToGrid(spawnId, 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))
|
||||||
{
|
{
|
||||||
Creature creature = Creature.CreateCreatureFromDB(spawnId, map, true, true);
|
Creature creature = Creature.CreateCreatureFromDB(spawnId, map, true, true);
|
||||||
if (!creature)
|
if (!creature)
|
||||||
@@ -3674,13 +3676,13 @@ namespace Game
|
|||||||
return creatureTemplateStorage;
|
return creatureTemplateStorage;
|
||||||
}
|
}
|
||||||
public Dictionary<ulong, CreatureData> GetAllCreatureData() { return creatureDataStorage; }
|
public Dictionary<ulong, CreatureData> GetAllCreatureData() { return creatureDataStorage; }
|
||||||
public CreatureData GetCreatureData(ulong guid)
|
public CreatureData GetCreatureData(ulong spawnId)
|
||||||
{
|
{
|
||||||
return creatureDataStorage.LookupByKey(guid);
|
return creatureDataStorage.LookupByKey(spawnId);
|
||||||
}
|
}
|
||||||
public ObjectGuid GetLinkedRespawnGuid(ObjectGuid guid)
|
public ObjectGuid GetLinkedRespawnGuid(ObjectGuid spawnId)
|
||||||
{
|
{
|
||||||
var retGuid = linkedRespawnStorage.LookupByKey(guid);
|
var retGuid = linkedRespawnStorage.LookupByKey(spawnId);
|
||||||
if (retGuid.IsEmpty())
|
if (retGuid.IsEmpty())
|
||||||
return ObjectGuid.Empty;
|
return ObjectGuid.Empty;
|
||||||
return retGuid;
|
return retGuid;
|
||||||
@@ -3691,7 +3693,7 @@ namespace Game
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
CreatureData master = GetCreatureData(guidLow);
|
CreatureData master = GetCreatureData(guidLow);
|
||||||
ObjectGuid guid = ObjectGuid.Create(HighGuid.Creature, master.spawnPoint.GetMapId(), master.Id, guidLow);
|
ObjectGuid guid = ObjectGuid.Create(HighGuid.Creature, master.MapId, master.Id, guidLow);
|
||||||
PreparedStatement stmt;
|
PreparedStatement stmt;
|
||||||
|
|
||||||
if (linkedGuidLow == 0) // we're removing the linking
|
if (linkedGuidLow == 0) // we're removing the linking
|
||||||
@@ -3711,8 +3713,8 @@ namespace Game
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapRecord map = CliDB.MapStorage.LookupByKey(master.spawnPoint.GetMapId());
|
MapRecord map = CliDB.MapStorage.LookupByKey(master.MapId);
|
||||||
if (map == null || !map.Instanceable() || (master.spawnPoint.GetMapId() != slave.spawnPoint.GetMapId()))
|
if (map == null || !map.Instanceable() || (master.MapId != slave.MapId))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Creature '{0}' linking to '{1}' on an unpermitted map.", guidLow, linkedGuidLow);
|
Log.outError(LogFilter.Sql, "Creature '{0}' linking to '{1}' on an unpermitted map.", guidLow, linkedGuidLow);
|
||||||
return false;
|
return false;
|
||||||
@@ -3725,7 +3727,7 @@ namespace Game
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectGuid linkedGuid = ObjectGuid.Create(HighGuid.Creature, slave.spawnPoint.GetMapId(), slave.Id, linkedGuidLow);
|
ObjectGuid linkedGuid = ObjectGuid.Create(HighGuid.Creature, slave.MapId, slave.Id, linkedGuidLow);
|
||||||
|
|
||||||
linkedRespawnStorage[guid] = linkedGuid;
|
linkedRespawnStorage[guid] = linkedGuid;
|
||||||
stmt = DB.World.GetPreparedStatement(WorldStatements.REP_LINKED_RESPAWN);
|
stmt = DB.World.GetPreparedStatement(WorldStatements.REP_LINKED_RESPAWN);
|
||||||
@@ -3735,22 +3737,22 @@ namespace Game
|
|||||||
DB.World.Execute(stmt);
|
DB.World.Execute(stmt);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
public CreatureData NewOrExistCreatureData(ulong guid)
|
public CreatureData NewOrExistCreatureData(ulong spawnId)
|
||||||
{
|
{
|
||||||
if (!creatureDataStorage.ContainsKey(guid))
|
if (!creatureDataStorage.ContainsKey(spawnId))
|
||||||
creatureDataStorage[guid] = new CreatureData();
|
creatureDataStorage[spawnId] = new CreatureData();
|
||||||
return creatureDataStorage[guid];
|
return creatureDataStorage[spawnId];
|
||||||
}
|
}
|
||||||
public void DeleteCreatureData(ulong guid)
|
public void DeleteCreatureData(ulong spawnId)
|
||||||
{
|
{
|
||||||
CreatureData data = GetCreatureData(guid);
|
CreatureData data = GetCreatureData(spawnId);
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
RemoveCreatureFromGrid(guid, data);
|
RemoveCreatureFromGrid(spawnId, data);
|
||||||
OnDeleteSpawnData(data);
|
OnDeleteSpawnData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
creatureDataStorage.Remove(guid);
|
creatureDataStorage.Remove(spawnId);
|
||||||
}
|
}
|
||||||
public CreatureBaseStats GetCreatureBaseStats(uint level, uint unitClass)
|
public CreatureBaseStats GetCreatureBaseStats(uint level, uint unitClass)
|
||||||
{
|
{
|
||||||
@@ -4168,20 +4170,21 @@ namespace Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
GameObjectData data = new();
|
GameObjectData data = new();
|
||||||
data.spawnId = guid;
|
data.SpawnId = guid;
|
||||||
data.Id = entry;
|
data.Id = entry;
|
||||||
data.spawnPoint = new WorldLocation(result.Read<ushort>(2), result.Read<float>(3), result.Read<float>(4), result.Read<float>(5), result.Read<float>(6));
|
data.MapId = result.Read<ushort>(2);
|
||||||
|
data.SpawnPoint = new Position(result.Read<float>(3), result.Read<float>(4), result.Read<float>(5), result.Read<float>(6));
|
||||||
data.rotation.X = result.Read<float>(7);
|
data.rotation.X = result.Read<float>(7);
|
||||||
data.rotation.Y = result.Read<float>(8);
|
data.rotation.Y = result.Read<float>(8);
|
||||||
data.rotation.Z = result.Read<float>(9);
|
data.rotation.Z = result.Read<float>(9);
|
||||||
data.rotation.W = result.Read<float>(10);
|
data.rotation.W = result.Read<float>(10);
|
||||||
data.spawntimesecs = result.Read<int>(11);
|
data.spawntimesecs = result.Read<int>(11);
|
||||||
data.spawnGroupData = _spawnGroupDataStorage[IsTransportMap(data.spawnPoint.GetMapId()) ? 1 : 0u]; // transport spawns default to compatibility group
|
data.spawnGroupData = IsTransportMap(data.MapId) ? GetLegacySpawnGroup() : GetDefaultSpawnGroup(); // transport spawns default to compatibility group
|
||||||
|
|
||||||
var mapEntry = CliDB.MapStorage.LookupByKey(data.spawnPoint.GetMapId());
|
var mapEntry = CliDB.MapStorage.LookupByKey(data.MapId);
|
||||||
if (mapEntry == null)
|
if (mapEntry == null)
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Table `gameobject` has gameobject (GUID: {0} Entry: {1}) spawned on a non-existed map (Id: {2}), skip", guid, data.Id, data.spawnPoint.GetMapId());
|
Log.outError(LogFilter.Sql, "Table `gameobject` has gameobject (GUID: {0} Entry: {1}) spawned on a non-existed map (Id: {2}), skip", guid, data.Id, data.MapId);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4204,7 +4207,7 @@ namespace Game
|
|||||||
}
|
}
|
||||||
data.goState = (GameObjectState)gostate;
|
data.goState = (GameObjectState)gostate;
|
||||||
|
|
||||||
data.spawnDifficulties = ParseSpawnDifficulties(result.Read<string>(14), "gameobject", guid, data.spawnPoint.GetMapId(), spawnMasks.LookupByKey(data.spawnPoint.GetMapId()));
|
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.");
|
||||||
@@ -4213,44 +4216,44 @@ namespace Game
|
|||||||
|
|
||||||
short gameEvent = result.Read<sbyte>(15);
|
short gameEvent = result.Read<sbyte>(15);
|
||||||
uint PoolId = result.Read<uint>(16);
|
uint PoolId = result.Read<uint>(16);
|
||||||
data.phaseUseFlags = (PhaseUseFlagsValues)result.Read<byte>(17);
|
data.PhaseUseFlags = (PhaseUseFlagsValues)result.Read<byte>(17);
|
||||||
data.phaseId = result.Read<uint>(18);
|
data.PhaseId = result.Read<uint>(18);
|
||||||
data.phaseGroup = result.Read<uint>(19);
|
data.PhaseGroup = result.Read<uint>(19);
|
||||||
|
|
||||||
if (Convert.ToBoolean(data.phaseUseFlags & ~PhaseUseFlagsValues.All))
|
if (Convert.ToBoolean(data.PhaseUseFlags & ~PhaseUseFlagsValues.All))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Table `gameobject` have gameobject (GUID: {0} Entry: {1}) has unknown `phaseUseFlags` set, removed unknown value.", guid, data.Id);
|
Log.outError(LogFilter.Sql, "Table `gameobject` have gameobject (GUID: {0} Entry: {1}) has unknown `phaseUseFlags` set, removed unknown value.", guid, data.Id);
|
||||||
data.phaseUseFlags &= PhaseUseFlagsValues.All;
|
data.PhaseUseFlags &= PhaseUseFlagsValues.All;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.phaseUseFlags.HasAnyFlag(PhaseUseFlagsValues.AlwaysVisible) && data.phaseUseFlags.HasAnyFlag(PhaseUseFlagsValues.Inverse))
|
if (data.PhaseUseFlags.HasAnyFlag(PhaseUseFlagsValues.AlwaysVisible) && data.PhaseUseFlags.HasAnyFlag(PhaseUseFlagsValues.Inverse))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Table `gameobject` have gameobject (GUID: {0} Entry: {1}) has both `phaseUseFlags` PHASE_USE_FLAGS_ALWAYS_VISIBLE and PHASE_USE_FLAGS_INVERSE," +
|
Log.outError(LogFilter.Sql, "Table `gameobject` have gameobject (GUID: {0} Entry: {1}) has both `phaseUseFlags` PHASE_USE_FLAGS_ALWAYS_VISIBLE and PHASE_USE_FLAGS_INVERSE," +
|
||||||
" removing PHASE_USE_FLAGS_INVERSE.", guid, data.Id);
|
" removing PHASE_USE_FLAGS_INVERSE.", guid, data.Id);
|
||||||
data.phaseUseFlags &= ~PhaseUseFlagsValues.Inverse;
|
data.PhaseUseFlags &= ~PhaseUseFlagsValues.Inverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.phaseGroup != 0 && data.phaseId != 0)
|
if (data.PhaseGroup != 0 && data.PhaseId != 0)
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Table `gameobject` have gameobject (GUID: {0} Entry: {1}) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, data.Id);
|
Log.outError(LogFilter.Sql, "Table `gameobject` have gameobject (GUID: {0} Entry: {1}) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, data.Id);
|
||||||
data.phaseGroup = 0;
|
data.PhaseGroup = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.phaseId != 0)
|
if (data.PhaseId != 0)
|
||||||
{
|
{
|
||||||
if (!CliDB.PhaseStorage.ContainsKey(data.phaseId))
|
if (!CliDB.PhaseStorage.ContainsKey(data.PhaseId))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Table `gameobject` have gameobject (GUID: {0} Entry: {1}) with `phaseid` {2} does not exist, set to 0", guid, data.Id, data.phaseId);
|
Log.outError(LogFilter.Sql, "Table `gameobject` have gameobject (GUID: {0} Entry: {1}) with `phaseid` {2} does not exist, set to 0", guid, data.Id, data.PhaseId);
|
||||||
data.phaseId = 0;
|
data.PhaseId = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.phaseGroup != 0)
|
if (data.PhaseGroup != 0)
|
||||||
{
|
{
|
||||||
if (Global.DB2Mgr.GetPhasesForGroup(data.phaseGroup).Empty())
|
if (Global.DB2Mgr.GetPhasesForGroup(data.PhaseGroup).Empty())
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Table `gameobject` have gameobject (GUID: {0} Entry: {1}) with `phaseGroup` {2} does not exist, set to 0", guid, data.Id, data.phaseGroup);
|
Log.outError(LogFilter.Sql, "Table `gameobject` have gameobject (GUID: {0} Entry: {1}) with `phaseGroup` {2} does not exist, set to 0", guid, data.Id, data.PhaseGroup);
|
||||||
data.phaseGroup = 0;
|
data.PhaseGroup = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4263,7 +4266,7 @@ namespace Game
|
|||||||
Log.outError(LogFilter.Sql, "Table `gameobject` have gameobject (GUID: {0} Entry: {1}) with `terrainSwapMap` {2} does not exist, set to -1", guid, data.Id, data.terrainSwapMap);
|
Log.outError(LogFilter.Sql, "Table `gameobject` have gameobject (GUID: {0} Entry: {1}) with `terrainSwapMap` {2} does not exist, set to -1", guid, data.Id, data.terrainSwapMap);
|
||||||
data.terrainSwapMap = -1;
|
data.terrainSwapMap = -1;
|
||||||
}
|
}
|
||||||
else if (terrainSwapEntry.ParentMapID != data.spawnPoint.GetMapId())
|
else if (terrainSwapEntry.ParentMapID != data.MapId)
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Table `gameobject` have gameobject (GUID: {0} Entry: {1}) with `terrainSwapMap` {2} which cannot be used on spawn map, set to -1", guid, data.Id, data.terrainSwapMap);
|
Log.outError(LogFilter.Sql, "Table `gameobject` have gameobject (GUID: {0} Entry: {1}) with `terrainSwapMap` {2} which cannot be used on spawn map, set to -1", guid, data.Id, data.terrainSwapMap);
|
||||||
data.terrainSwapMap = -1;
|
data.terrainSwapMap = -1;
|
||||||
@@ -4296,7 +4299,7 @@ namespace Game
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GridDefines.IsValidMapCoord(data.spawnPoint))
|
if (!GridDefines.IsValidMapCoord(data.MapId, data.SpawnPoint))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, "Table `gameobject` has gameobject (GUID: {0} Entry: {1}) with invalid coordinates, skip", guid, data.Id);
|
Log.outError(LogFilter.Sql, "Table `gameobject` has gameobject (GUID: {0} Entry: {1}) with invalid coordinates, skip", guid, data.Id);
|
||||||
continue;
|
continue;
|
||||||
@@ -4305,13 +4308,13 @@ namespace Game
|
|||||||
if (!(Math.Abs(Quaternion.Dot(data.rotation, data.rotation) - 1) < 1e-5))
|
if (!(Math.Abs(Quaternion.Dot(data.rotation, data.rotation) - 1) < 1e-5))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, $"Table `gameobject` has gameobject (GUID: {guid} Entry: {data.Id}) with invalid rotation quaternion (non-unit), defaulting to orientation on Z axis only");
|
Log.outError(LogFilter.Sql, $"Table `gameobject` has gameobject (GUID: {guid} Entry: {data.Id}) with invalid rotation quaternion (non-unit), defaulting to orientation on Z axis only");
|
||||||
data.rotation = Quaternion.CreateFromRotationMatrix(Extensions.fromEulerAnglesZYX(data.spawnPoint.GetOrientation(), 0f, 0f));
|
data.rotation = Quaternion.CreateFromRotationMatrix(Extensions.fromEulerAnglesZYX(data.SpawnPoint.GetOrientation(), 0f, 0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WorldConfig.GetBoolValue(WorldCfg.CalculateGameobjectZoneAreaData))
|
if (WorldConfig.GetBoolValue(WorldCfg.CalculateGameobjectZoneAreaData))
|
||||||
{
|
{
|
||||||
PhasingHandler.InitDbVisibleMapId(phaseShift, data.terrainSwapMap);
|
PhasingHandler.InitDbVisibleMapId(phaseShift, data.terrainSwapMap);
|
||||||
Global.MapMgr.GetZoneAndAreaId(phaseShift, out uint zoneId, out uint areaId, data.spawnPoint);
|
Global.MapMgr.GetZoneAndAreaId(phaseShift, out uint zoneId, out uint areaId, data.MapId, data.SpawnPoint);
|
||||||
|
|
||||||
PreparedStatement stmt = DB.World.GetPreparedStatement(WorldStatements.UPD_GAMEOBJECT_ZONE_AREA_DATA);
|
PreparedStatement stmt = DB.World.GetPreparedStatement(WorldStatements.UPD_GAMEOBJECT_ZONE_AREA_DATA);
|
||||||
stmt.AddValue(0, zoneId);
|
stmt.AddValue(0, zoneId);
|
||||||
@@ -4499,8 +4502,8 @@ namespace Game
|
|||||||
{
|
{
|
||||||
foreach (Difficulty difficulty in data.spawnDifficulties)
|
foreach (Difficulty difficulty in data.spawnDifficulties)
|
||||||
{
|
{
|
||||||
CellCoord cellCoord = GridDefines.ComputeCellCoord(data.spawnPoint.GetPositionX(), data.spawnPoint.GetPositionY());
|
CellCoord cellCoord = GridDefines.ComputeCellCoord(data.SpawnPoint.GetPositionX(), data.SpawnPoint.GetPositionY());
|
||||||
var cellguids = CreateCellObjectGuids(data.spawnPoint.GetMapId(), difficulty, cellCoord.GetId());
|
var cellguids = CreateCellObjectGuids(data.MapId, difficulty, cellCoord.GetId());
|
||||||
cellguids.gameobjects.Add(guid);
|
cellguids.gameobjects.Add(guid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4508,8 +4511,8 @@ namespace Game
|
|||||||
{
|
{
|
||||||
foreach (Difficulty difficulty in data.spawnDifficulties)
|
foreach (Difficulty difficulty in data.spawnDifficulties)
|
||||||
{
|
{
|
||||||
CellCoord cellCoord = GridDefines.ComputeCellCoord(data.spawnPoint.GetPositionX(), data.spawnPoint.GetPositionY());
|
CellCoord cellCoord = GridDefines.ComputeCellCoord(data.SpawnPoint.GetPositionX(), data.SpawnPoint.GetPositionY());
|
||||||
CellObjectGuids cellguids = GetCellObjectGuids(data.spawnPoint.GetMapId(), difficulty, cellCoord.GetId());
|
CellObjectGuids cellguids = GetCellObjectGuids(data.MapId, difficulty, cellCoord.GetId());
|
||||||
if (cellguids == null)
|
if (cellguids == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -4528,9 +4531,10 @@ namespace Game
|
|||||||
|
|
||||||
ulong spawnId = GenerateGameObjectSpawnId();
|
ulong spawnId = GenerateGameObjectSpawnId();
|
||||||
GameObjectData data = NewOrExistGameObjectData(spawnId);
|
GameObjectData data = NewOrExistGameObjectData(spawnId);
|
||||||
data.spawnId = spawnId;
|
data.SpawnId = spawnId;
|
||||||
data.Id = entry;
|
data.Id = entry;
|
||||||
data.spawnPoint.WorldRelocate(mapId, pos);
|
data.MapId = mapId;
|
||||||
|
data.SpawnPoint.Relocate(pos);
|
||||||
data.rotation = rot;
|
data.rotation = rot;
|
||||||
data.spawntimesecs = (int)spawntimedelay;
|
data.spawntimesecs = (int)spawntimedelay;
|
||||||
data.animprogress = 100;
|
data.animprogress = 100;
|
||||||
@@ -4544,7 +4548,7 @@ namespace Game
|
|||||||
|
|
||||||
// Spawn if necessary (loaded grids only)
|
// Spawn if necessary (loaded grids only)
|
||||||
// We use spawn coords to spawn
|
// We use spawn coords to spawn
|
||||||
if (!map.Instanceable() && map.IsGridLoaded(data.spawnPoint))
|
if (!map.Instanceable() && map.IsGridLoaded(data.SpawnPoint))
|
||||||
{
|
{
|
||||||
GameObject go = GameObject.CreateGameObjectFromDB(spawnId, map);
|
GameObject go = GameObject.CreateGameObjectFromDB(spawnId, map);
|
||||||
if (!go)
|
if (!go)
|
||||||
@@ -4554,7 +4558,7 @@ namespace Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.outDebug(LogFilter.Maps, $"AddGameObjectData: dbguid:{spawnId} entry:{entry} map:{mapId} pos:{data.spawnPoint}");
|
Log.outDebug(LogFilter.Maps, $"AddGameObjectData: dbguid:{spawnId} entry:{entry} map:{mapId} pos:{data.SpawnPoint}");
|
||||||
|
|
||||||
return spawnId;
|
return spawnId;
|
||||||
}
|
}
|
||||||
@@ -4569,27 +4573,27 @@ namespace Game
|
|||||||
}
|
}
|
||||||
MultiMap<uint, uint> GetGameObjectQuestItemMap() { return _gameObjectQuestItemStorage; }
|
MultiMap<uint, uint> GetGameObjectQuestItemMap() { return _gameObjectQuestItemStorage; }
|
||||||
public Dictionary<ulong, GameObjectData> GetAllGameObjectData() { return gameObjectDataStorage; }
|
public Dictionary<ulong, GameObjectData> GetAllGameObjectData() { return gameObjectDataStorage; }
|
||||||
public GameObjectData GetGameObjectData(ulong guid)
|
public GameObjectData GetGameObjectData(ulong spawnId)
|
||||||
{
|
{
|
||||||
return gameObjectDataStorage.LookupByKey(guid);
|
return gameObjectDataStorage.LookupByKey(spawnId);
|
||||||
}
|
}
|
||||||
public void DeleteGameObjectData(ulong guid)
|
public void DeleteGameObjectData(ulong spawnId)
|
||||||
{
|
{
|
||||||
GameObjectData data = GetGameObjectData(guid);
|
GameObjectData data = GetGameObjectData(spawnId);
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
RemoveGameObjectFromGrid(guid, data);
|
RemoveGameObjectFromGrid(spawnId, data);
|
||||||
OnDeleteSpawnData(data);
|
OnDeleteSpawnData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
gameObjectDataStorage.Remove(guid);
|
gameObjectDataStorage.Remove(spawnId);
|
||||||
}
|
}
|
||||||
public GameObjectData NewOrExistGameObjectData(ulong guid)
|
public GameObjectData NewOrExistGameObjectData(ulong spawnId)
|
||||||
{
|
{
|
||||||
if (!gameObjectDataStorage.ContainsKey(guid))
|
if (!gameObjectDataStorage.ContainsKey(spawnId))
|
||||||
gameObjectDataStorage[guid] = new GameObjectData();
|
gameObjectDataStorage[spawnId] = new GameObjectData();
|
||||||
|
|
||||||
return gameObjectDataStorage[guid];
|
return gameObjectDataStorage[spawnId];
|
||||||
}
|
}
|
||||||
public GameObjectTemplate GetGameObjectTemplate(uint entry)
|
public GameObjectTemplate GetGameObjectTemplate(uint entry)
|
||||||
{
|
{
|
||||||
@@ -5509,14 +5513,14 @@ namespace Game
|
|||||||
{
|
{
|
||||||
uint groupId = result.Read<uint>(0);
|
uint groupId = result.Read<uint>(0);
|
||||||
SpawnObjectType spawnType = (SpawnObjectType)result.Read<byte>(1);
|
SpawnObjectType spawnType = (SpawnObjectType)result.Read<byte>(1);
|
||||||
if (spawnType >= SpawnObjectType.Max)
|
if (!SpawnData.TypeIsValid(spawnType))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, $"Spawn data with invalid type {spawnType} listed for spawn group {groupId}. Skipped.");
|
Log.outError(LogFilter.Sql, $"Spawn data with invalid type {spawnType} listed for spawn group {groupId}. Skipped.");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ulong spawnId = result.Read<ulong>(2);
|
ulong spawnId = result.Read<ulong>(2);
|
||||||
|
|
||||||
SpawnData data = GetSpawnData(spawnType, spawnId);
|
SpawnMetadata data = GetSpawnMetadata(spawnType, spawnId);
|
||||||
if (data == null)
|
if (data == null)
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, $"Spawn data with ID ({spawnType},{spawnId}) not found, but is listed as a member of spawn group {groupId}!");
|
Log.outError(LogFilter.Sql, $"Spawn data with ID ({spawnType},{spawnId}) not found, but is listed as a member of spawn group {groupId}!");
|
||||||
@@ -5536,10 +5540,10 @@ namespace Game
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (groupTemplate.mapId == 0xFFFFFFFF)
|
if (groupTemplate.mapId == 0xFFFFFFFF)
|
||||||
groupTemplate.mapId = data.spawnPoint.GetMapId();
|
groupTemplate.mapId = data.MapId;
|
||||||
else if (groupTemplate.mapId != data.spawnPoint.GetMapId() && !groupTemplate.flags.HasAnyFlag(SpawnGroupFlags.System))
|
else if (groupTemplate.mapId != data.MapId && !groupTemplate.flags.HasAnyFlag(SpawnGroupFlags.System))
|
||||||
{
|
{
|
||||||
Log.outError(LogFilter.Sql, $"Spawn group {groupId} has map ID {groupTemplate.mapId}, but spawn ({spawnType},{spawnId}) has map id {data.spawnPoint.GetMapId()} - spawn NOT added to group!");
|
Log.outError(LogFilter.Sql, $"Spawn group {groupId} has map ID {groupTemplate.mapId}, but spawn ({spawnType},{spawnId}) has map id {data.MapId} - spawn NOT added to group!");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
data.spawnGroupData = groupTemplate;
|
data.spawnGroupData = groupTemplate;
|
||||||
@@ -5609,7 +5613,7 @@ namespace Game
|
|||||||
void OnDeleteSpawnData(SpawnData data)
|
void OnDeleteSpawnData(SpawnData data)
|
||||||
{
|
{
|
||||||
var templateIt = _spawnGroupDataStorage.LookupByKey(data.spawnGroupData.groupId);
|
var templateIt = _spawnGroupDataStorage.LookupByKey(data.spawnGroupData.groupId);
|
||||||
Cypher.Assert(templateIt != null, $"Creature data for ({data.type},{data.spawnId}) is being deleted and has invalid spawn group index {data.spawnGroupData.groupId}!");
|
Cypher.Assert(templateIt != null, $"Creature data for ({data.type},{data.SpawnId}) is being deleted and has invalid spawn group index {data.spawnGroupData.groupId}!");
|
||||||
|
|
||||||
if (templateIt.flags.HasAnyFlag(SpawnGroupFlags.System)) // system groups don't store their members in the map
|
if (templateIt.flags.HasAnyFlag(SpawnGroupFlags.System)) // system groups don't store their members in the map
|
||||||
return;
|
return;
|
||||||
@@ -5623,7 +5627,7 @@ namespace Game
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 Dictionary<uint, InstanceTemplate> GetInstanceTemplates() { return instanceTemplateStorage; }
|
public Dictionary<uint, InstanceTemplate> GetInstanceTemplates() { return instanceTemplateStorage; }
|
||||||
@@ -5691,19 +5695,38 @@ namespace Game
|
|||||||
}
|
}
|
||||||
public bool IsTransportMap(uint mapId) { return _transportMaps.Contains((ushort)mapId); }
|
public bool IsTransportMap(uint mapId) { return _transportMaps.Contains((ushort)mapId); }
|
||||||
public SpawnGroupTemplateData GetSpawnGroupData(uint groupId) { return _spawnGroupDataStorage.LookupByKey(groupId); }
|
public SpawnGroupTemplateData GetSpawnGroupData(uint groupId) { return _spawnGroupDataStorage.LookupByKey(groupId); }
|
||||||
|
public SpawnGroupTemplateData GetSpawnGroupData(SpawnObjectType type, ulong spawnId)
|
||||||
|
{
|
||||||
|
SpawnMetadata data = GetSpawnMetadata(type, spawnId);
|
||||||
|
return data != null ? data.spawnGroupData : null;
|
||||||
|
}
|
||||||
public SpawnGroupTemplateData GetDefaultSpawnGroup() { return _spawnGroupDataStorage.ElementAt(0).Value; }
|
public SpawnGroupTemplateData GetDefaultSpawnGroup() { return _spawnGroupDataStorage.ElementAt(0).Value; }
|
||||||
public 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 List<SpawnMetadata> GetSpawnMetadataForGroup(uint groupId) { return _spawnGroupMapStorage.LookupByKey(groupId); }
|
||||||
public SpawnData GetSpawnData(SpawnObjectType type, ulong guid)
|
public SpawnMetadata GetSpawnMetadata(SpawnObjectType type, ulong spawnId)
|
||||||
{
|
{
|
||||||
if (type == SpawnObjectType.Creature)
|
if (SpawnData.TypeHasData(type))
|
||||||
return GetCreatureData(guid);
|
return GetSpawnData(type, spawnId);
|
||||||
else if (type == SpawnObjectType.GameObject)
|
|
||||||
return GetGameObjectData(guid);
|
|
||||||
else
|
else
|
||||||
Cypher.Assert(false, $"Invalid spawn object type {type}");
|
return null;
|
||||||
|
}
|
||||||
|
public SpawnData GetSpawnData(SpawnObjectType type, ulong spawnId)
|
||||||
|
{
|
||||||
|
if (!SpawnData.TypeHasData(type))
|
||||||
|
return null;
|
||||||
|
|
||||||
return null;
|
switch (type)
|
||||||
|
{
|
||||||
|
case SpawnObjectType.Creature:
|
||||||
|
return GetCreatureData(spawnId);
|
||||||
|
case SpawnObjectType.GameObject:
|
||||||
|
return GetGameObjectData(spawnId);
|
||||||
|
case SpawnObjectType.AreaTrigger:
|
||||||
|
return Global.AreaTriggerDataStorage.GetAreaTriggerSpawn(spawnId);
|
||||||
|
default:
|
||||||
|
Cypher.Assert(false, $"Invalid spawn object type {type}");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public List<InstanceSpawnGroupInfo> GetSpawnGroupsForInstance(uint instanceId) { return _instanceSpawnGroupStorage.LookupByKey(instanceId); }
|
public List<InstanceSpawnGroupInfo> GetSpawnGroupsForInstance(uint instanceId) { return _instanceSpawnGroupStorage.LookupByKey(instanceId); }
|
||||||
|
|
||||||
@@ -10593,7 +10616,7 @@ namespace Game
|
|||||||
public MultiMap<uint, GraveYardData> GraveYardStorage = new();
|
public MultiMap<uint, GraveYardData> GraveYardStorage = new();
|
||||||
List<ushort> _transportMaps = new();
|
List<ushort> _transportMaps = new();
|
||||||
Dictionary<uint, SpawnGroupTemplateData> _spawnGroupDataStorage = new();
|
Dictionary<uint, SpawnGroupTemplateData> _spawnGroupDataStorage = new();
|
||||||
MultiMap<uint, SpawnData> _spawnGroupMapStorage = new();
|
MultiMap<uint, SpawnMetadata> _spawnGroupMapStorage = new();
|
||||||
MultiMap<ushort, InstanceSpawnGroupInfo> _instanceSpawnGroupStorage = new();
|
MultiMap<ushort, InstanceSpawnGroupInfo> _instanceSpawnGroupStorage = new();
|
||||||
|
|
||||||
//Spells /Skills / Phases
|
//Spells /Skills / Phases
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ namespace Game.Maps
|
|||||||
{
|
{
|
||||||
return IsValidMapCoord(x, y, z) && float.IsFinite(o);
|
return IsValidMapCoord(x, y, z) && float.IsFinite(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsValidMapCoord(uint mapid, float x, float y)
|
public static bool IsValidMapCoord(uint mapid, float x, float y)
|
||||||
{
|
{
|
||||||
return Global.MapMgr.IsValidMAP(mapid, false) && IsValidMapCoord(x, y);
|
return Global.MapMgr.IsValidMAP(mapid, false) && IsValidMapCoord(x, y);
|
||||||
@@ -58,9 +58,14 @@ namespace Game.Maps
|
|||||||
return Global.MapMgr.IsValidMAP(mapid, false) && IsValidMapCoord(x, y, z, o);
|
return Global.MapMgr.IsValidMAP(mapid, false) && IsValidMapCoord(x, y, z, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool IsValidMapCoord(uint mapid, Position pos)
|
||||||
|
{
|
||||||
|
return IsValidMapCoord(mapid, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation());
|
||||||
|
}
|
||||||
|
|
||||||
public static bool IsValidMapCoord(WorldLocation loc)
|
public static bool IsValidMapCoord(WorldLocation loc)
|
||||||
{
|
{
|
||||||
return IsValidMapCoord(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetOrientation());
|
return IsValidMapCoord(loc.GetMapId(), loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void NormalizeMapCoord(ref float c)
|
public static void NormalizeMapCoord(ref float c)
|
||||||
|
|||||||
+264
-182
@@ -2411,6 +2411,159 @@ namespace Game.Maps
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Respawn(SpawnObjectType type, ulong spawnId, SQLTransaction dbTrans = null)
|
||||||
|
{
|
||||||
|
RespawnInfo info = GetRespawnInfo(type, spawnId);
|
||||||
|
if (info != null)
|
||||||
|
Respawn(info, dbTrans);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Respawn(RespawnInfo info, SQLTransaction dbTrans = null)
|
||||||
|
{
|
||||||
|
info.respawnTime = GameTime.GetGameTime();
|
||||||
|
SaveRespawnInfoDB(info, dbTrans);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveRespawnTime(SpawnObjectType type, ulong spawnId, SQLTransaction dbTrans = null)
|
||||||
|
{
|
||||||
|
RespawnInfo info = GetRespawnInfo(type, spawnId);
|
||||||
|
if (info != null)
|
||||||
|
DeleteRespawnInfo(info, dbTrans);
|
||||||
|
}
|
||||||
|
|
||||||
|
int DespawnAll(SpawnObjectType type, ulong spawnId)
|
||||||
|
{
|
||||||
|
List<WorldObject> toUnload = new();
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case SpawnObjectType.Creature:
|
||||||
|
foreach (var creature in GetCreatureBySpawnIdStore().LookupByKey(spawnId))
|
||||||
|
toUnload.Add(creature);
|
||||||
|
break;
|
||||||
|
case SpawnObjectType.GameObject:
|
||||||
|
foreach (var obj in GetGameObjectBySpawnIdStore().LookupByKey(spawnId))
|
||||||
|
toUnload.Add(obj);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (WorldObject o in toUnload)
|
||||||
|
AddObjectToRemoveList(o);
|
||||||
|
|
||||||
|
return toUnload.Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AddRespawnInfo(RespawnInfo info)
|
||||||
|
{
|
||||||
|
if (info.spawnId == 0)
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Maps, $"Attempt to insert respawn info for zero spawn id (type {info.type})");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bySpawnIdMap = GetRespawnMapForType(info.type);
|
||||||
|
if (bySpawnIdMap == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// check if we already have the maximum possible number of respawns scheduled
|
||||||
|
if (SpawnData.TypeHasData(info.type))
|
||||||
|
{
|
||||||
|
var existing = bySpawnIdMap.LookupByKey(info.spawnId);
|
||||||
|
if (existing != null) // spawnid already has a respawn scheduled
|
||||||
|
{
|
||||||
|
if (info.respawnTime <= existing.respawnTime) // delete existing in this case
|
||||||
|
DeleteRespawnInfo(existing);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Cypher.Assert(!bySpawnIdMap.ContainsKey(info.spawnId), $"Insertion of respawn info with id ({info.type},{info.spawnId}) into spawn id map failed - state desync.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Cypher.Assert(false, $"Invalid respawn info for spawn id ({info.type},{info.spawnId}) being inserted");
|
||||||
|
|
||||||
|
RespawnInfo ri = new(info);
|
||||||
|
_respawnTimes.Add(ri);
|
||||||
|
bySpawnIdMap.Add(ri.spawnId, ri);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PushRespawnInfoFrom(List<RespawnInfo> data, Dictionary<ulong, RespawnInfo> map)
|
||||||
|
{
|
||||||
|
foreach (var pair in map)
|
||||||
|
data.Add(pair.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GetRespawnInfo(List<RespawnInfo> respawnData, SpawnObjectTypeMask types)
|
||||||
|
{
|
||||||
|
if ((types & SpawnObjectTypeMask.Creature) != 0)
|
||||||
|
PushRespawnInfoFrom(respawnData, _creatureRespawnTimesBySpawnId);
|
||||||
|
if ((types & SpawnObjectTypeMask.GameObject) != 0)
|
||||||
|
PushRespawnInfoFrom(respawnData, _gameObjectRespawnTimesBySpawnId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RespawnInfo GetRespawnInfo(SpawnObjectType type, ulong spawnId)
|
||||||
|
{
|
||||||
|
var map = GetRespawnMapForType(type);
|
||||||
|
if (map == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var respawnInfo = map.LookupByKey(spawnId);
|
||||||
|
if (respawnInfo == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return respawnInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary<ulong, RespawnInfo> GetRespawnMapForType(SpawnObjectType type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case SpawnObjectType.Creature:
|
||||||
|
return _creatureRespawnTimesBySpawnId;
|
||||||
|
case SpawnObjectType.GameObject:
|
||||||
|
return _gameObjectRespawnTimesBySpawnId;
|
||||||
|
case SpawnObjectType.AreaTrigger:
|
||||||
|
return null;
|
||||||
|
default:
|
||||||
|
Cypher.Assert(false);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnloadAllRespawnInfos() // delete everything from memory
|
||||||
|
{
|
||||||
|
_respawnTimes.Clear();
|
||||||
|
_creatureRespawnTimesBySpawnId.Clear();
|
||||||
|
_gameObjectRespawnTimesBySpawnId.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeleteRespawnInfo(RespawnInfo info, SQLTransaction dbTrans = null)
|
||||||
|
{
|
||||||
|
// Delete from all relevant containers to ensure consistency
|
||||||
|
Cypher.Assert(info != null);
|
||||||
|
|
||||||
|
// spawnid store
|
||||||
|
var spawnMap = GetRespawnMapForType(info.type);
|
||||||
|
if (spawnMap == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var respawnInfo = spawnMap.LookupByKey(info.spawnId);
|
||||||
|
Cypher.Assert(respawnInfo != info, $"Respawn stores inconsistent for map {GetId()}, spawnid {info.spawnId} (type {info.type})");
|
||||||
|
spawnMap.Remove(info.spawnId);
|
||||||
|
|
||||||
|
// respawn heap
|
||||||
|
_respawnTimes.Remove(info);
|
||||||
|
|
||||||
|
// database
|
||||||
|
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_RESPAWN);
|
||||||
|
stmt.AddValue(0, (ushort)info.type);
|
||||||
|
stmt.AddValue(1, info.spawnId);
|
||||||
|
stmt.AddValue(2, GetId());
|
||||||
|
stmt.AddValue(3, GetInstanceId());
|
||||||
|
DB.Characters.ExecuteOrAppend(dbTrans, stmt);
|
||||||
|
}
|
||||||
|
|
||||||
void DoRespawn(SpawnObjectType type, ulong spawnId, uint gridId)
|
void DoRespawn(SpawnObjectType type, ulong spawnId, uint gridId)
|
||||||
{
|
{
|
||||||
if (!IsGridLoaded(gridId)) // if grid isn't loaded, this will be processed in grid load handler
|
if (!IsGridLoaded(gridId)) // if grid isn't loaded, this will be processed in grid load handler
|
||||||
@@ -2438,120 +2591,6 @@ namespace Game.Maps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Respawn(SpawnObjectType type, ulong spawnId, SQLTransaction dbTrans = null)
|
|
||||||
{
|
|
||||||
RespawnInfo info = GetRespawnInfo(type, spawnId);
|
|
||||||
if (info != null)
|
|
||||||
Respawn(info, dbTrans);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Respawn(RespawnInfo info, SQLTransaction dbTrans = null)
|
|
||||||
{
|
|
||||||
if (!CheckRespawn(info))
|
|
||||||
{
|
|
||||||
if (info.respawnTime != 0)
|
|
||||||
{
|
|
||||||
//_respawnTimes.decrease(info);
|
|
||||||
SaveRespawnInfoDB(info, dbTrans);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
DeleteRespawnInfo(info, dbTrans);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove the actual respawn record first - since this deletes it, we save what we need
|
|
||||||
SpawnObjectType type = info.type;
|
|
||||||
uint gridId = info.gridId;
|
|
||||||
ulong spawnId = info.spawnId;
|
|
||||||
DeleteRespawnInfo(info, dbTrans);
|
|
||||||
DoRespawn(type, spawnId, gridId);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AddRespawnInfo(RespawnInfo info)
|
|
||||||
{
|
|
||||||
Cypher.Assert(info.spawnId != 0, $"Attempt to schedule respawn with zero spawnid (type {info.type})");
|
|
||||||
|
|
||||||
var bySpawnIdMap = GetRespawnMapForType(info.type);
|
|
||||||
|
|
||||||
var existing = bySpawnIdMap.LookupByKey(info.spawnId);
|
|
||||||
if (existing != null) // spawnid already has a respawn scheduled
|
|
||||||
{
|
|
||||||
if (info.respawnTime < existing.respawnTime) // delete existing in this case
|
|
||||||
DeleteRespawnInfo(existing);
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we get to this point, we should insert the respawninfo (there either was no prior entry, or it was deleted already)
|
|
||||||
RespawnInfo ri = new(info);
|
|
||||||
_respawnTimes.Add(ri);
|
|
||||||
bool success = bySpawnIdMap.TryAdd(ri.spawnId, ri);
|
|
||||||
Cypher.Assert(success, $"Insertion of respawn info with id ({ri.type},{ri.spawnId}) into spawn id map failed - state desync.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void PushRespawnInfoFrom(List<RespawnInfo> data, Dictionary<ulong, RespawnInfo> map)
|
|
||||||
{
|
|
||||||
foreach (var pair in map)
|
|
||||||
data.Add(pair.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GetRespawnInfo(List<RespawnInfo> respawnData, SpawnObjectTypeMask types)
|
|
||||||
{
|
|
||||||
if (types.HasAnyFlag(SpawnObjectTypeMask.Creature))
|
|
||||||
PushRespawnInfoFrom(respawnData, _creatureRespawnTimesBySpawnId);
|
|
||||||
if (types.HasAnyFlag(SpawnObjectTypeMask.GameObject))
|
|
||||||
PushRespawnInfoFrom(respawnData, _gameObjectRespawnTimesBySpawnId);
|
|
||||||
}
|
|
||||||
|
|
||||||
RespawnInfo GetRespawnInfo(SpawnObjectType type, ulong spawnId)
|
|
||||||
{
|
|
||||||
var map = GetRespawnMapForType(type);
|
|
||||||
var respawnInfo = map.LookupByKey(spawnId);
|
|
||||||
if (respawnInfo == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return respawnInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dictionary<ulong, RespawnInfo> GetRespawnMapForType(SpawnObjectType type) { return (type == SpawnObjectType.GameObject) ? _gameObjectRespawnTimesBySpawnId : _creatureRespawnTimesBySpawnId; }
|
|
||||||
|
|
||||||
void UnloadAllRespawnInfos() // delete everything from memory
|
|
||||||
{
|
|
||||||
_respawnTimes.Clear();
|
|
||||||
_creatureRespawnTimesBySpawnId.Clear();
|
|
||||||
_gameObjectRespawnTimesBySpawnId.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DeleteRespawnInfo(RespawnInfo info, SQLTransaction dbTrans = null)
|
|
||||||
{
|
|
||||||
// Delete from all relevant containers to ensure consistency
|
|
||||||
Cypher.Assert(info != null);
|
|
||||||
|
|
||||||
// spawnid store
|
|
||||||
bool removed = GetRespawnMapForType(info.type).Remove(info.spawnId);
|
|
||||||
Cypher.Assert(removed, $"Respawn stores inconsistent for map {GetId()}, spawnid {info.spawnId} (type {info.type})");
|
|
||||||
|
|
||||||
// respawn heap
|
|
||||||
_respawnTimes.Remove(info);
|
|
||||||
|
|
||||||
// database
|
|
||||||
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_RESPAWN);
|
|
||||||
stmt.AddValue(0, (ushort)info.type);
|
|
||||||
stmt.AddValue(1, info.spawnId);
|
|
||||||
stmt.AddValue(2, GetId());
|
|
||||||
stmt.AddValue(3, GetInstanceId());
|
|
||||||
DB.Characters.ExecuteOrAppend(dbTrans, stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveRespawnTime(SpawnObjectType type, ulong spawnId, SQLTransaction dbTrans = null)
|
|
||||||
{
|
|
||||||
RespawnInfo info = GetRespawnInfo(type, spawnId);
|
|
||||||
if (info != null)
|
|
||||||
DeleteRespawnInfo(info, dbTrans);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProcessRespawns()
|
void ProcessRespawns()
|
||||||
{
|
{
|
||||||
long now = GameTime.GetGameTime();
|
long now = GameTime.GetGameTime();
|
||||||
@@ -2603,8 +2642,11 @@ namespace Game.Maps
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpawnData data = Global.ObjectMgr.GetSpawnData(type, spawnId);
|
SpawnMetadata data = Global.ObjectMgr.GetSpawnMetadata(type, spawnId);
|
||||||
if (data == null || data.spawnGroupData == null || !!data.spawnGroupData.flags.HasAnyFlag(SpawnGroupFlags.DynamicSpawnRate))
|
if (data == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!data.spawnGroupData.flags.HasFlag(SpawnGroupFlags.DynamicSpawnRate))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!_zonePlayerCountMap.ContainsKey(obj.GetZoneId()))
|
if (!_zonePlayerCountMap.ContainsKey(obj.GetZoneId()))
|
||||||
@@ -2625,6 +2667,25 @@ namespace Game.Maps
|
|||||||
respawnDelay = (uint)Math.Max(Math.Ceiling(respawnDelay * adjustFactor), timeMinimum);
|
respawnDelay = (uint)Math.Max(Math.Ceiling(respawnDelay * adjustFactor), timeMinimum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool ShouldBeSpawnedOnGridLoad<T>(ulong spawnId) { return ShouldBeSpawnedOnGridLoad(SpawnData.TypeFor<T>(), spawnId); }
|
||||||
|
|
||||||
|
bool ShouldBeSpawnedOnGridLoad(SpawnObjectType type, ulong spawnId)
|
||||||
|
{
|
||||||
|
Cypher.Assert(SpawnData.TypeHasData(type));
|
||||||
|
// check if the object is on its respawn timer
|
||||||
|
if (GetRespawnTime(type, spawnId) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SpawnMetadata spawnData = Global.ObjectMgr.GetSpawnMetadata(type, spawnId);
|
||||||
|
// check if the object is part of a spawn group
|
||||||
|
SpawnGroupTemplateData spawnGroup = spawnData.spawnGroupData;
|
||||||
|
if (!spawnGroup.flags.HasFlag(SpawnGroupFlags.System))
|
||||||
|
if (!IsSpawnGroupActive(spawnGroup.groupId))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
SpawnGroupTemplateData GetSpawnGroupData(uint groupId)
|
SpawnGroupTemplateData GetSpawnGroupData(uint groupId)
|
||||||
{
|
{
|
||||||
SpawnGroupTemplateData data = Global.ObjectMgr.GetSpawnGroupData(groupId);
|
SpawnGroupTemplateData data = Global.ObjectMgr.GetSpawnGroupData(groupId);
|
||||||
@@ -2644,39 +2705,52 @@ namespace Game.Maps
|
|||||||
}
|
}
|
||||||
|
|
||||||
SetSpawnGroupActive(groupId, true); // start processing respawns for the group
|
SetSpawnGroupActive(groupId, true); // start processing respawns for the group
|
||||||
foreach (var data in Global.ObjectMgr.GetSpawnDataForGroup(groupId))
|
|
||||||
|
List<SpawnData> toSpawn = new();
|
||||||
|
foreach (var data in Global.ObjectMgr.GetSpawnMetadataForGroup(groupId))
|
||||||
{
|
{
|
||||||
Cypher.Assert(groupData.mapId == data.spawnPoint.GetMapId());
|
Cypher.Assert(groupData.mapId == data.MapId);
|
||||||
// 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);
|
var respawnMap = GetRespawnMapForType(data.type);
|
||||||
if (respawnTime != 0)
|
if (respawnMap == null)
|
||||||
{
|
|
||||||
if (!force && !ignoreRespawn && respawnTime > GameTime.GetGameTime())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// we need to remove the respawn time, otherwise we'd end up double spawning
|
|
||||||
RemoveRespawnTime(data.type, data.spawnId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't spawn if the grid isn't loaded (will be handled in grid loader)
|
|
||||||
if (!IsGridLoaded(data.spawnPoint))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Everything OK, now do the actual (re)spawn
|
if (force || ignoreRespawn)
|
||||||
|
RemoveRespawnTime(data.type, data.SpawnId);
|
||||||
|
|
||||||
|
bool hasRespawnTimer = respawnMap.ContainsKey(data.SpawnId);
|
||||||
|
if (SpawnData.TypeHasData(data.type))
|
||||||
|
{
|
||||||
|
// has a respawn timer
|
||||||
|
if (hasRespawnTimer)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// has a spawn already active
|
||||||
|
if (!force)
|
||||||
|
{
|
||||||
|
WorldObject obj = GetWorldObjectBySpawnId(data.type, data.SpawnId);
|
||||||
|
if (obj != null)
|
||||||
|
if ((data.type != SpawnObjectType.Creature) || obj.ToCreature().IsAlive())
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
toSpawn.Add(data.ToSpawnData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (SpawnData data in toSpawn)
|
||||||
|
{
|
||||||
|
// don't spawn if the grid isn't loaded (will be handled in grid loader)
|
||||||
|
if (!IsGridLoaded(data.SpawnPoint))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// now do the actual (re)spawn
|
||||||
switch (data.type)
|
switch (data.type)
|
||||||
{
|
{
|
||||||
case SpawnObjectType.Creature:
|
case SpawnObjectType.Creature:
|
||||||
{
|
{
|
||||||
Creature creature = new();
|
Creature creature = new();
|
||||||
if (!creature.LoadFromDB(data.spawnId, this, true, force))
|
if (!creature.LoadFromDB(data.SpawnId, this, true, force))
|
||||||
creature.Dispose();
|
creature.Dispose();
|
||||||
else if (spawnedObjects != null)
|
else if (spawnedObjects != null)
|
||||||
spawnedObjects.Add(creature);
|
spawnedObjects.Add(creature);
|
||||||
@@ -2685,14 +2759,23 @@ namespace Game.Maps
|
|||||||
case SpawnObjectType.GameObject:
|
case SpawnObjectType.GameObject:
|
||||||
{
|
{
|
||||||
GameObject gameobject = new();
|
GameObject gameobject = new();
|
||||||
if (!gameobject.LoadFromDB(data.spawnId, this, true))
|
if (!gameobject.LoadFromDB(data.SpawnId, this, true))
|
||||||
gameobject.Dispose();
|
gameobject.Dispose();
|
||||||
else if (spawnedObjects != null)
|
else if (spawnedObjects != null)
|
||||||
spawnedObjects.Add(gameobject);
|
spawnedObjects.Add(gameobject);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SpawnObjectType.AreaTrigger:
|
||||||
|
{
|
||||||
|
AreaTrigger areaTrigger = new AreaTrigger();
|
||||||
|
if (!areaTrigger.LoadFromDB(data.SpawnId, this, true, false))
|
||||||
|
areaTrigger.Dispose();
|
||||||
|
else if (spawnedObjects != null)
|
||||||
|
spawnedObjects.Add(areaTrigger);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
Cypher.Assert(false, $"Invalid spawn type {data.type} with spawnId {data.spawnId}");
|
Cypher.Assert(false, $"Invalid spawn type {data.type} with spawnId {data.SpawnId}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2704,6 +2787,7 @@ namespace Game.Maps
|
|||||||
{
|
{
|
||||||
return SpawnGroupDespawn(groupId, deleteRespawnTimes, out _);
|
return SpawnGroupDespawn(groupId, deleteRespawnTimes, out _);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool SpawnGroupDespawn(uint groupId, bool deleteRespawnTimes, out int count)
|
public bool SpawnGroupDespawn(uint groupId, bool deleteRespawnTimes, out int count)
|
||||||
{
|
{
|
||||||
count = 0;
|
count = 0;
|
||||||
@@ -2714,39 +2798,14 @@ namespace Game.Maps
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<WorldObject> toUnload = new(); // unload after iterating, otherwise iterator invalidation
|
foreach (var data in Global.ObjectMgr.GetSpawnMetadataForGroup(groupId))
|
||||||
foreach (var data in Global.ObjectMgr.GetSpawnDataForGroup(groupId))
|
|
||||||
{
|
{
|
||||||
|
Cypher.Assert(groupData.mapId == data.MapId);
|
||||||
if (deleteRespawnTimes)
|
if (deleteRespawnTimes)
|
||||||
RemoveRespawnTime(data.type, data.spawnId);
|
RemoveRespawnTime(data.type, data.SpawnId);
|
||||||
switch (data.type)
|
count += DespawnAll(data.type, data.SpawnId);
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
count = toUnload.Count;
|
|
||||||
|
|
||||||
// now do the actual despawning
|
|
||||||
foreach (WorldObject obj in toUnload)
|
|
||||||
obj.AddObjectToRemoveList();
|
|
||||||
|
|
||||||
SetSpawnGroupActive(groupId, false); // stop processing respawns for the group, too
|
SetSpawnGroupActive(groupId, false); // stop processing respawns for the group, too
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -3030,19 +3089,23 @@ namespace Game.Maps
|
|||||||
|
|
||||||
public void SaveRespawnTime(SpawnObjectType type, ulong spawnId, uint entry, long respawnTime, uint gridId = 0, SQLTransaction dbTrans = null, bool startup = false)
|
public void SaveRespawnTime(SpawnObjectType type, ulong spawnId, uint entry, long respawnTime, uint gridId = 0, SQLTransaction dbTrans = null, bool startup = false)
|
||||||
{
|
{
|
||||||
if (spawnId == 0)
|
SpawnMetadata data = Global.ObjectMgr.GetSpawnMetadata(type, spawnId);
|
||||||
|
if (data == null)
|
||||||
|
{
|
||||||
|
Log.outError(LogFilter.Maps, $"Map {GetId()} attempt to save respawn time for nonexistant spawnid ({type},{spawnId}).");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (respawnTime == 0)
|
if (respawnTime == 0)
|
||||||
{
|
{
|
||||||
// Delete only
|
// Delete only
|
||||||
RemoveRespawnTime(type, spawnId, dbTrans);
|
RemoveRespawnTime(data.type, data.SpawnId, dbTrans);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RespawnInfo ri = new();
|
RespawnInfo ri = new();
|
||||||
ri.type = type;
|
ri.type = data.type;
|
||||||
ri.spawnId = spawnId;
|
ri.spawnId = data.SpawnId;
|
||||||
ri.entry = entry;
|
ri.entry = entry;
|
||||||
ri.respawnTime = respawnTime;
|
ri.respawnTime = respawnTime;
|
||||||
ri.gridId = gridId;
|
ri.gridId = gridId;
|
||||||
@@ -3083,11 +3146,11 @@ namespace Game.Maps
|
|||||||
var spawnId = result.Read<ulong>(1);
|
var spawnId = result.Read<ulong>(1);
|
||||||
var respawnTime = result.Read<long>(2);
|
var respawnTime = result.Read<long>(2);
|
||||||
|
|
||||||
if (type < SpawnObjectType.Max)
|
if (SpawnData.TypeHasData(type))
|
||||||
{
|
{
|
||||||
SpawnData data = Global.ObjectMgr.GetSpawnData(type, spawnId);
|
SpawnData data = Global.ObjectMgr.GetSpawnData(type, spawnId);
|
||||||
if (data != null)
|
if (data != null)
|
||||||
SaveRespawnTime(type, spawnId, data.Id, respawnTime, GridDefines.ComputeGridCoord(data.spawnPoint.GetPositionX(), data.spawnPoint.GetPositionY()).GetId(), null, true);
|
SaveRespawnTime(type, spawnId, data.Id, respawnTime, GridDefines.ComputeGridCoord(data.SpawnPoint.GetPositionX(), data.SpawnPoint.GetPositionY()).GetId(), null, true);
|
||||||
else
|
else
|
||||||
Log.outError(LogFilter.Maps, $"Loading saved respawn time of {respawnTime} for spawnid ({type},{spawnId}) - spawn does not exist, ignoring");
|
Log.outError(LogFilter.Maps, $"Loading saved respawn time of {respawnTime} for spawnid ({type},{spawnId}) - spawn does not exist, ignoring");
|
||||||
}
|
}
|
||||||
@@ -3702,6 +3765,8 @@ namespace Game.Maps
|
|||||||
|
|
||||||
public MultiMap<ulong, GameObject> GetGameObjectBySpawnIdStore() { return _gameobjectBySpawnIdStore; }
|
public MultiMap<ulong, GameObject> GetGameObjectBySpawnIdStore() { return _gameobjectBySpawnIdStore; }
|
||||||
|
|
||||||
|
public MultiMap<ulong, AreaTrigger> GetAreaTriggerBySpawnIdStore() { return _areaTriggerBySpawnIdStore; }
|
||||||
|
|
||||||
public List<Corpse> GetCorpsesInCell(uint cellId)
|
public List<Corpse> GetCorpsesInCell(uint cellId)
|
||||||
{
|
{
|
||||||
return _corpsesByCell.LookupByKey(cellId);
|
return _corpsesByCell.LookupByKey(cellId);
|
||||||
@@ -3748,12 +3813,17 @@ namespace Game.Maps
|
|||||||
|
|
||||||
public long GetRespawnTime(SpawnObjectType type, ulong spawnId)
|
public long GetRespawnTime(SpawnObjectType type, ulong spawnId)
|
||||||
{
|
{
|
||||||
var respawnDic = GetRespawnMapForType(type);
|
var map = GetRespawnMapForType(type);
|
||||||
var respawnInfo = respawnDic.LookupByKey(spawnId);
|
if (map != null)
|
||||||
return (respawnInfo == null) ? 0 : respawnInfo.respawnTime;
|
{
|
||||||
|
var respawnInfo = map.LookupByKey(spawnId);
|
||||||
|
return (respawnInfo == null) ? 0 : respawnInfo.respawnTime;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long GetCreatureRespawnTime(ulong spawnId) { return GetRespawnTime(SpawnObjectType.Creature, spawnId); }
|
public long GetCreatureRespawnTime(ulong spawnId) { return GetRespawnTime(SpawnObjectType.Creature, spawnId); }
|
||||||
|
|
||||||
public long GetGORespawnTime(ulong spawnId) { return GetRespawnTime(SpawnObjectType.GameObject, spawnId); }
|
public long GetGORespawnTime(ulong spawnId) { return GetRespawnTime(SpawnObjectType.GameObject, spawnId); }
|
||||||
|
|
||||||
void SetTimer(uint t)
|
void SetTimer(uint t)
|
||||||
@@ -3851,7 +3921,7 @@ namespace Game.Maps
|
|||||||
return go ? go.ToTransport() : null;
|
return go ? go.ToTransport() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Creature GetCreatureBySpawnId(ulong spawnId)
|
public Creature GetCreatureBySpawnId(ulong spawnId)
|
||||||
{
|
{
|
||||||
var bounds = GetCreatureBySpawnIdStore().LookupByKey(spawnId);
|
var bounds = GetCreatureBySpawnIdStore().LookupByKey(spawnId);
|
||||||
if (bounds.Empty())
|
if (bounds.Empty())
|
||||||
@@ -3862,7 +3932,7 @@ namespace Game.Maps
|
|||||||
return foundCreature != null ? foundCreature : bounds[0];
|
return foundCreature != null ? foundCreature : bounds[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
GameObject GetGameObjectBySpawnId(ulong spawnId)
|
public GameObject GetGameObjectBySpawnId(ulong spawnId)
|
||||||
{
|
{
|
||||||
var bounds = GetGameObjectBySpawnIdStore().LookupByKey(spawnId);
|
var bounds = GetGameObjectBySpawnIdStore().LookupByKey(spawnId);
|
||||||
if (bounds.Empty())
|
if (bounds.Empty())
|
||||||
@@ -3873,6 +3943,15 @@ namespace Game.Maps
|
|||||||
return foundGameObject != null ? foundGameObject : bounds[0];
|
return foundGameObject != null ? foundGameObject : bounds[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AreaTrigger GetAreaTriggerBySpawnId(ulong spawnId)
|
||||||
|
{
|
||||||
|
var bounds = GetAreaTriggerBySpawnIdStore().LookupByKey(spawnId);
|
||||||
|
if (bounds.Empty())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return bounds.FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
public WorldObject GetWorldObjectBySpawnId(SpawnObjectType type, ulong spawnId)
|
public WorldObject GetWorldObjectBySpawnId(SpawnObjectType type, ulong spawnId)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
@@ -3881,6 +3960,8 @@ namespace Game.Maps
|
|||||||
return GetCreatureBySpawnId(spawnId);
|
return GetCreatureBySpawnId(spawnId);
|
||||||
case SpawnObjectType.GameObject:
|
case SpawnObjectType.GameObject:
|
||||||
return GetGameObjectBySpawnId(spawnId);
|
return GetGameObjectBySpawnId(spawnId);
|
||||||
|
case SpawnObjectType.AreaTrigger:
|
||||||
|
return GetAreaTriggerBySpawnId(spawnId);
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -4986,6 +5067,7 @@ namespace Game.Maps
|
|||||||
Dictionary<ObjectGuid, WorldObject> _objectsStore = new();
|
Dictionary<ObjectGuid, WorldObject> _objectsStore = new();
|
||||||
MultiMap<ulong, Creature> _creatureBySpawnIdStore = new();
|
MultiMap<ulong, Creature> _creatureBySpawnIdStore = new();
|
||||||
MultiMap<ulong, GameObject> _gameobjectBySpawnIdStore = new();
|
MultiMap<ulong, GameObject> _gameobjectBySpawnIdStore = new();
|
||||||
|
MultiMap<ulong, AreaTrigger> _areaTriggerBySpawnIdStore = new();
|
||||||
MultiMap<uint, Corpse> _corpsesByCell = new();
|
MultiMap<uint, Corpse> _corpsesByCell = new();
|
||||||
Dictionary<ObjectGuid, Corpse> _corpsesByPlayer = new();
|
Dictionary<ObjectGuid, Corpse> _corpsesByPlayer = new();
|
||||||
List<Corpse> _corpseBones = new();
|
List<Corpse> _corpseBones = new();
|
||||||
|
|||||||
@@ -90,52 +90,18 @@ namespace Game.Maps
|
|||||||
{
|
{
|
||||||
foreach (var guid in guid_set)
|
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();
|
T obj = new();
|
||||||
// Don't spawn at all if there's a respawn time
|
if (!obj.LoadFromDB(guid, map, false, false))
|
||||||
if ((obj.IsTypeId(TypeId.Unit) && map.GetCreatureRespawnTime(guid) == 0) || (obj.IsTypeId(TypeId.GameObject) && map.GetGORespawnTime(guid) == 0) || obj.IsTypeId(TypeId.AreaTrigger))
|
|
||||||
{
|
{
|
||||||
//TC_LOG_INFO("misc", "DEBUG: LoadHelper from table: %s for (guid: %u) Loading", table, guid);
|
|
||||||
if (obj.IsTypeId(TypeId.Unit))
|
|
||||||
{
|
|
||||||
CreatureData cdata = Global.ObjectMgr.GetCreatureData(guid);
|
|
||||||
Cypher.Assert(cdata != null, $"Tried to load creature with spawnId {guid}, but no such creature exists.");
|
|
||||||
|
|
||||||
SpawnGroupTemplateData group = cdata.spawnGroupData;
|
|
||||||
// If creature in manual spawn group, don't spawn here, unless group is already active.
|
|
||||||
if (!group.flags.HasAnyFlag(SpawnGroupFlags.System))
|
|
||||||
{
|
|
||||||
if (!map.IsSpawnGroupActive(group.groupId))
|
|
||||||
{
|
|
||||||
obj.Dispose();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (obj.IsTypeId(TypeId.GameObject))
|
|
||||||
{
|
|
||||||
// If gameobject in manual spawn group, don't spawn here, unless group is already active.
|
|
||||||
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.HasAnyFlag(SpawnGroupFlags.System))
|
|
||||||
{
|
|
||||||
if (!map.IsSpawnGroupActive(godata.spawnGroupData.groupId))
|
|
||||||
{
|
|
||||||
obj.Dispose();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!obj.LoadFromDB(guid, map, false, false))
|
|
||||||
{
|
|
||||||
obj.Dispose();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
AddObjectHelper(cell, ref count, map, obj);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
obj.Dispose();
|
obj.Dispose();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddObjectHelper(cell, ref count, map, obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,29 +29,58 @@ namespace Game.Maps
|
|||||||
public SpawnGroupFlags flags;
|
public SpawnGroupFlags flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SpawnData
|
public class SpawnData : SpawnMetadata
|
||||||
{
|
{
|
||||||
public SpawnObjectType type;
|
|
||||||
public ulong spawnId;
|
|
||||||
public uint Id; // entry in respective _template table
|
public uint Id; // entry in respective _template table
|
||||||
public WorldLocation spawnPoint;
|
public Position SpawnPoint;
|
||||||
public PhaseUseFlagsValues phaseUseFlags;
|
public PhaseUseFlagsValues PhaseUseFlags;
|
||||||
public uint phaseId;
|
public uint PhaseId;
|
||||||
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 SpawnGroupTemplateData spawnGroupData;
|
|
||||||
public uint ScriptId;
|
public uint ScriptId;
|
||||||
public bool dbData;
|
|
||||||
|
|
||||||
public SpawnData(SpawnObjectType t)
|
public SpawnData(SpawnObjectType t) : base(t)
|
||||||
{
|
{
|
||||||
type = t;
|
SpawnPoint = new Position();
|
||||||
spawnPoint = new WorldLocation();
|
|
||||||
terrainSwapMap = -1;
|
terrainSwapMap = -1;
|
||||||
spawnDifficulties = new List<Difficulty>();
|
spawnDifficulties = new List<Difficulty>();
|
||||||
dbData = true;
|
}
|
||||||
|
|
||||||
|
public static SpawnObjectType TypeFor<T>()
|
||||||
|
{
|
||||||
|
switch (typeof(T).Name)
|
||||||
|
{
|
||||||
|
case nameof(Creature):
|
||||||
|
return SpawnObjectType.Creature;
|
||||||
|
case nameof(GameObject):
|
||||||
|
return SpawnObjectType.GameObject;
|
||||||
|
case nameof(AreaTrigger):
|
||||||
|
return SpawnObjectType.AreaTrigger;
|
||||||
|
default:
|
||||||
|
return SpawnObjectType.NumSpawnTypes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SpawnMetadata
|
||||||
|
{
|
||||||
|
public SpawnObjectType type;
|
||||||
|
public ulong SpawnId;
|
||||||
|
public uint MapId = 0xFFFFFFFF;
|
||||||
|
public bool dbData = true;
|
||||||
|
public SpawnGroupTemplateData spawnGroupData = null;
|
||||||
|
|
||||||
|
public static bool TypeInMask(SpawnObjectType type, SpawnObjectTypeMask mask) { return ((1 << (int)type) & (int)mask) != 0; }
|
||||||
|
public static bool TypeHasData(SpawnObjectType type) { return type < SpawnObjectType.NumSpawnTypesWithData; }
|
||||||
|
public static bool TypeIsValid(SpawnObjectType type) { return type < SpawnObjectType.NumSpawnTypes; }
|
||||||
|
|
||||||
|
public SpawnMetadata(SpawnObjectType t)
|
||||||
|
{
|
||||||
|
type = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpawnData ToSpawnData() { return TypeHasData(type) ? (SpawnData)this : null; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -383,6 +383,8 @@ namespace Game
|
|||||||
return IsPartOfAPool<Creature>(spawnId);
|
return IsPartOfAPool<Creature>(spawnId);
|
||||||
case SpawnObjectType.GameObject:
|
case SpawnObjectType.GameObject:
|
||||||
return IsPartOfAPool<GameObject>(spawnId);
|
return IsPartOfAPool<GameObject>(spawnId);
|
||||||
|
case SpawnObjectType.AreaTrigger:
|
||||||
|
return 0;
|
||||||
default:
|
default:
|
||||||
Cypher.Assert(false, $"Invalid spawn type {type} passed to PoolMgr.IsPartOfPool (with spawnId {spawnId})");
|
Cypher.Assert(false, $"Invalid spawn type {type} passed to PoolMgr.IsPartOfPool (with spawnId {spawnId})");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -481,7 +483,7 @@ namespace Game
|
|||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
Global.ObjectMgr.RemoveCreatureFromGrid(guid, data);
|
Global.ObjectMgr.RemoveCreatureFromGrid(guid, data);
|
||||||
Map map = Global.MapMgr.FindMap(data.spawnPoint.GetMapId(), 0);
|
Map map = Global.MapMgr.FindMap(data.MapId, 0);
|
||||||
if (map != null && !map.Instanceable())
|
if (map != null && !map.Instanceable())
|
||||||
{
|
{
|
||||||
var creatureBounds = map.GetCreatureBySpawnIdStore().LookupByKey(guid);
|
var creatureBounds = map.GetCreatureBySpawnIdStore().LookupByKey(guid);
|
||||||
@@ -503,7 +505,7 @@ namespace Game
|
|||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
Global.ObjectMgr.RemoveGameObjectFromGrid(guid, data);
|
Global.ObjectMgr.RemoveGameObjectFromGrid(guid, data);
|
||||||
Map map = Global.MapMgr.FindMap(data.spawnPoint.GetMapId(), 0);
|
Map map = Global.MapMgr.FindMap(data.MapId, 0);
|
||||||
if (map != null && !map.Instanceable())
|
if (map != null && !map.Instanceable())
|
||||||
{
|
{
|
||||||
var gameobjectBounds = map.GetGameObjectBySpawnIdStore().LookupByKey(guid);
|
var gameobjectBounds = map.GetGameObjectBySpawnIdStore().LookupByKey(guid);
|
||||||
@@ -620,9 +622,9 @@ namespace Game
|
|||||||
Global.ObjectMgr.AddCreatureToGrid(obj.guid, data);
|
Global.ObjectMgr.AddCreatureToGrid(obj.guid, data);
|
||||||
|
|
||||||
// Spawn if necessary (loaded grids only)
|
// Spawn if necessary (loaded grids only)
|
||||||
Map map = Global.MapMgr.FindMap(data.spawnPoint.GetMapId(), 0);
|
Map map = Global.MapMgr.FindMap(data.MapId, 0);
|
||||||
// We use spawn coords to spawn
|
// We use spawn coords to spawn
|
||||||
if (map != null && !map.Instanceable() && map.IsGridLoaded(data.spawnPoint))
|
if (map != null && !map.Instanceable() && map.IsGridLoaded(data.SpawnPoint))
|
||||||
Creature.CreateCreatureFromDB(obj.guid, map);
|
Creature.CreateCreatureFromDB(obj.guid, map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -635,9 +637,9 @@ namespace Game
|
|||||||
Global.ObjectMgr.AddGameObjectToGrid(obj.guid, data);
|
Global.ObjectMgr.AddGameObjectToGrid(obj.guid, 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.spawnPoint.GetMapId(), 0);
|
Map map = Global.MapMgr.FindMap(data.MapId, 0);
|
||||||
// We use current coords to unspawn, not spawn coords since creature can have changed grid
|
// We use current coords to unspawn, not spawn coords since creature can have changed grid
|
||||||
if (map != null && !map.Instanceable() && map.IsGridLoaded(data.spawnPoint))
|
if (map != null && !map.Instanceable() && map.IsGridLoaded(data.SpawnPoint))
|
||||||
{
|
{
|
||||||
GameObject go = GameObject.CreateGameObjectFromDB(obj.guid, map, false);
|
GameObject go = GameObject.CreateGameObjectFromDB(obj.guid, map, false);
|
||||||
if (go)
|
if (go)
|
||||||
|
|||||||
Reference in New Issue
Block a user