Core/Transports: Localized transport objects within each map

Port From (https://github.com/TrinityCore/TrinityCore/commit/cace41449771bbe692e1a45c4d38b15a12f6496e)
This commit is contained in:
hondacrx
2022-06-16 14:08:22 -04:00
parent 30525b4567
commit 37d62e3a32
9 changed files with 208 additions and 208 deletions
+1 -1
View File
@@ -3663,7 +3663,7 @@ namespace Game.Entities
ITransport m_transport;
Map _currMap;
uint instanceId;
public uint instanceId;
PhaseShift _phaseShift = new();
PhaseShift _suppressedPhaseShift = new(); // contains phases for current area but not applied due to conditions
int _dbPhase;
+25 -18
View File
@@ -612,22 +612,14 @@ namespace Game.Entities
{
var createPosition = m_createMode == PlayerCreateMode.NPE && info.createPositionNPE.HasValue ? info.createPositionNPE.Value : info.createPosition;
homebind.WorldRelocate(createPosition.Loc);
if (createPosition.TransportGuid.HasValue)
if (!createPosition.TransportGuid.HasValue)
{
Transport transport = Global.ObjAccessor.FindTransport(ObjectGuid.Create(HighGuid.Transport, createPosition.TransportGuid.Value));
if (transport != null)
{
float orientation = homebind.GetOrientation();
transport.CalculatePassengerPosition(ref homebind.posX, ref homebind.posY, ref homebind.posZ, ref orientation);
homebind.SetOrientation(orientation);
}
homebind.WorldRelocate(createPosition.Loc);
homebindAreaId = Global.MapMgr.GetAreaId(PhasingHandler.EmptyPhaseShift, homebind);
saveHomebindToDb();
ok = true;
}
homebindAreaId = Global.MapMgr.GetAreaId(PhasingHandler.EmptyPhaseShift, homebind);
saveHomebindToDb();
ok = true;
}
if (!ok)
@@ -2864,10 +2856,25 @@ namespace Game.Entities
ObjectGuid transGUID = ObjectGuid.Create(HighGuid.Transport, transguid);
Transport transport = null;
Transport go = Global.ObjAccessor.FindTransport(transGUID);
if (go)
transport = go;
Map transportMap = Global.MapMgr.CreateMap(mapId, this, instanceId);
if (transportMap != null)
{
Transport transportOnMap = transportMap.GetTransport(transGUID);
if (transportOnMap != null)
{
if (transportOnMap.GetExpectedMapId() != mapId)
{
mapId = transportOnMap.GetExpectedMapId();
instanceId = 0;
transportMap = Global.MapMgr.CreateMap(mapId, this, instanceId);
if (transportMap)
transport = transportMap.GetTransport(transGUID);
}
else
transport = transportOnMap;
}
}
if (transport)
{
float x = trans_x;
+1 -1
View File
@@ -203,7 +203,7 @@ namespace Game.Entities
if (position.TransportGuid.HasValue)
{
Transport transport = Global.ObjAccessor.FindTransport(ObjectGuid.Create(HighGuid.Transport, position.TransportGuid.Value));
Transport transport = ObjectAccessor.GetTransport(this, ObjectGuid.Create(HighGuid.Transport, position.TransportGuid.Value));
if (transport != null)
{
transport.AddPassenger(this);
+61 -34
View File
@@ -18,6 +18,7 @@
using Framework.Constants;
using Game.DataStorage;
using Game.Maps;
using Game.Networking.Packets;
using System;
using System.Collections;
using System.Collections.Generic;
@@ -142,14 +143,13 @@ namespace Game.Entities
base.Dispose();
}
public bool Create(ulong guidlow, uint entry, uint mapid, float x, float y, float z, float ang, uint animprogress)
public bool Create(ulong guidlow, uint entry, float x, float y, float z, float ang)
{
Relocate(x, y, z, ang);
if (!IsPositionValid())
{
Log.outError(LogFilter.Transport, "Transport (GUID: {0}) not created. Suggested coordinates isn't valid (X: {1} Y: {2})",
guidlow, x, y);
Log.outError(LogFilter.Transport, $"Transport (GUID: {guidlow}) not created. Suggested coordinates isn't valid (X: {x} Y: {y})");
return false;
}
@@ -159,7 +159,7 @@ namespace Game.Entities
if (goinfo == null)
{
Log.outError(LogFilter.Sql, "Transport not created: entry in `gameobject_template` not found, guidlow: {0} map: {1} (X: {2} Y: {3} Z: {4}) ang: {5}", guidlow, mapid, x, y, z, ang);
Log.outError(LogFilter.Sql, $"Transport not created: entry in `gameobject_template` not found, entry: {entry}");
return false;
}
@@ -191,12 +191,20 @@ namespace Game.Entities
SetDisplayId(goinfo.displayId);
SetGoState(goinfo.MoTransport.allowstopping == 0 ? GameObjectState.Ready : GameObjectState.Active);
SetGoType(GameObjectTypes.MapObjTransport);
SetGoAnimProgress(animprogress);
SetGoAnimProgress(255);
SetUpdateFieldValue(m_values.ModifyValue(m_gameObjectData).ModifyValue(m_gameObjectData.SpawnTrackingStateAnimID), Global.DB2Mgr.GetEmptyAnimStateID());
SetName(goinfo.name);
SetLocalRotation(0.0f, 0.0f, 0.0f, 1.0f);
SetParentRotation(Quaternion.Identity);
int legIndex;
var position = _transportInfo.ComputePosition(_pathProgress, out _, out legIndex);
if (position != null)
{
Relocate(position.GetPositionX(), position.GetPositionY(), position.GetPositionZ(), position.GetOrientation());
_currentPathLeg = legIndex;
}
CreateModel();
return true;
}
@@ -258,7 +266,11 @@ namespace Game.Entities
{
while (eventToTriggerIndex < _transportInfo.Events.Count && _transportInfo.Events[eventToTriggerIndex].Timestamp < timer)
{
GameEvents.Trigger(_transportInfo.Events[eventToTriggerIndex].EventId, this, this);
TransportPathLeg leg = _transportInfo.GetLegForTime(_transportInfo.Events[eventToTriggerIndex].Timestamp);
if (leg != null)
if (leg.MapId == GetMapId())
GameEvents.Trigger(_transportInfo.Events[eventToTriggerIndex].EventId, this, this);
_eventsToTrigger.Set(eventToTriggerIndex, false);
++eventToTriggerIndex;
}
@@ -283,13 +295,14 @@ namespace Game.Entities
if (legIndex != _currentPathLeg)
{
uint oldMapId = _transportInfo.PathLegs[_currentPathLeg].MapId;
_currentPathLeg = legIndex;
TeleportTransport(_transportInfo.PathLegs[legIndex].MapId, newPosition.GetPositionX(), newPosition.GetPositionY(), newPosition.GetPositionZ(), newPosition.GetOrientation());
TeleportTransport(oldMapId, _transportInfo.PathLegs[legIndex].MapId, newPosition.GetPositionX(), newPosition.GetPositionY(), newPosition.GetPositionZ(), newPosition.GetOrientation());
return;
}
// set position
if (_positionChangeTimer.Passed())
if (_positionChangeTimer.Passed() && GetExpectedMapId() == GetMapId())
{
_positionChangeTimer.Reset(positionUpdateDelay);
if (_movementState == TransportMovementState.Moving || justStopped)
@@ -323,11 +336,6 @@ namespace Game.Entities
}
}
public void DelayedUpdate(uint diff)
{
DelayedTeleportTransport();
}
public void AddPassenger(WorldObject passenger)
{
if (!IsInWorld)
@@ -646,14 +654,12 @@ namespace Game.Entities
public void SetDelayedAddModelToMap() { _delayedAddModel = true; }
bool TeleportTransport(uint newMapid, float x, float y, float z, float o)
bool TeleportTransport(uint oldMapId, uint newMapId, float x, float y, float z, float o)
{
Map oldMap = GetMap();
if (oldMap.GetId() != newMapid)
if (oldMapId != newMapId)
{
_delayedTeleport = new(newMapid, x, y, z, o);
UnloadStaticPassengers();
TeleportPassengersAndHideTransport(newMapId, x, y, z, o);
return true;
}
else
@@ -683,21 +689,41 @@ namespace Game.Entities
}
}
void DelayedTeleportTransport()
void TeleportPassengersAndHideTransport(uint newMapid, float x, float y, float z, float o)
{
if (_delayedTeleport == null)
return;
if (newMapid == GetMapId())
{
AddToWorld();
Map newMap = Global.MapMgr.CreateBaseMap(_delayedTeleport.GetMapId());
GetMap().RemoveFromMap(this, false);
SetMap(newMap);
foreach (var player in GetMap().GetPlayers())
{
if (player.GetTransport() != this && player.IsInPhase(this))
{
UpdateData data = new(GetMap().GetId());
BuildCreateUpdateBlockForPlayer(data, player);
player.m_visibleTransports.Add(GetGUID());
data.BuildPacket(out UpdateObject packet);
player.SendPacket(packet);
}
}
}
else
{
UpdateData data = new(GetMap().GetId());
BuildOutOfRangeUpdateBlock(data);
float x = _delayedTeleport.GetPositionX(),
y = _delayedTeleport.GetPositionY(),
z = _delayedTeleport.GetPositionZ(),
o = _delayedTeleport.GetOrientation();
data.BuildPacket(out UpdateObject packet);
foreach (var player in GetMap().GetPlayers())
{
if (player.GetTransport() != this && player.m_visibleTransports.Contains(GetGUID()))
{
player.SendPacket(packet);
player.m_visibleTransports.Remove(GetGUID());
}
}
_delayedTeleport = null;
RemoveFromWorld();
}
List<WorldObject> passengersToTeleport = new(_passengers);
foreach (WorldObject obj in passengersToTeleport)
@@ -709,7 +735,7 @@ namespace Game.Entities
switch (obj.GetTypeId())
{
case TypeId.Player:
if (!obj.ToPlayer().TeleportTo(newMap.GetId(), destX, destY, destZ, destO, TeleportToOptions.NotLeaveTransport, newMap.GetInstanceId()))
if (!obj.ToPlayer().TeleportTo(newMapid, destX, destY, destZ, destO, TeleportToOptions.NotLeaveTransport))
RemovePassenger(obj);
break;
case TypeId.DynamicObject:
@@ -721,9 +747,6 @@ namespace Game.Entities
break;
}
}
Relocate(x, y, z, o);
GetMap().AddToMap(this);
}
void UpdatePassengerPositions(HashSet<WorldObject> passengers)
@@ -750,6 +773,11 @@ namespace Game.Entities
ClearUpdateMask(true);
}
public uint GetExpectedMapId()
{
return _transportInfo.PathLegs[_currentPathLeg].MapId;
}
public HashSet<WorldObject> GetPassengers() { return _passengers; }
public ObjectGuid GetTransportGUID() { return GetGUID(); }
@@ -772,6 +800,5 @@ namespace Game.Entities
HashSet<WorldObject> _staticPassengers = new();
bool _delayedAddModel;
WorldLocation _delayedTeleport;
}
}
+1 -23
View File
@@ -27,7 +27,6 @@ public class ObjectAccessor : Singleton<ObjectAccessor>
object _lockObject = new();
Dictionary<ObjectGuid, Player> _players = new();
Dictionary<ObjectGuid, Transport> _transports = new();
ObjectAccessor() { }
@@ -119,16 +118,11 @@ public class ObjectAccessor : Singleton<ObjectAccessor>
return u.GetMap().GetGameObject(guid);
}
static Transport GetTransportOnMap(WorldObject u, ObjectGuid guid)
public static Transport GetTransport(WorldObject u, ObjectGuid guid)
{
return u.GetMap().GetTransport(guid);
}
Transport GetTransport(ObjectGuid guid)
{
return _transports.LookupByKey(guid);
}
static DynamicObject GetDynamicObject(WorldObject u, ObjectGuid guid)
{
return u.GetMap().GetDynamicObject(guid);
@@ -227,12 +221,6 @@ public class ObjectAccessor : Singleton<ObjectAccessor>
return PlayerNameMapHolder.Find(name);
}
public Transport FindTransport(ObjectGuid guid)
{
lock (_lockObject)
return _transports.LookupByKey(guid);
}
public void SaveAllPlayers()
{
lock (_lockObject)
@@ -256,11 +244,6 @@ public class ObjectAccessor : Singleton<ObjectAccessor>
_players[obj.GetGUID()] = obj;
}
}
public void AddObject(Transport obj)
{
lock (_lockObject)
_transports[obj.GetGUID()] = obj;
}
public void RemoveObject(Player obj)
{
@@ -270,11 +253,6 @@ public class ObjectAccessor : Singleton<ObjectAccessor>
_players.Remove(obj.GetGUID());
}
}
public void RemoveObject(Transport obj)
{
lock (_lockObject)
_transports.Remove(obj.GetGUID());
}
}
class PlayerNameMapHolder
+13
View File
@@ -255,6 +255,11 @@ namespace Game
Map oldMap = player.GetMap();
Map newMap = GetPlayer().GetTeleportDestInstanceId().HasValue ? Global.MapMgr.FindMap(loc.GetMapId(), GetPlayer().GetTeleportDestInstanceId().Value) : Global.MapMgr.CreateMap(loc.GetMapId(), GetPlayer());
MovementInfo.TransportInfo transportInfo = player.m_movementInfo.transport;
ITransport transport = player.GetTransport();
if (transport != null)
transport.RemovePassenger(player);
if (player.IsInWorld)
{
Log.outError(LogFilter.Network, $"Player (Name {player.GetName()}) is still in world when teleported from map {oldMap.GetId()} to new map {loc.GetMapId()}");
@@ -286,6 +291,14 @@ namespace Game
if (!seamlessTeleport)
player.SendInitialPacketsBeforeAddToMap();
// move player between transport copies on each map
Transport newTransport = newMap.GetTransport(transportInfo.guid);
if (newTransport != null)
{
player.m_movementInfo.transport = transportInfo;
newTransport.AddPassenger(player);
}
if (!player.GetMap().AddPlayerToMap(player, !seamlessTeleport))
{
Log.outError(LogFilter.Network, $"WORLD: failed to teleport player {player.GetName()} ({player.GetGUID()}) to map {loc.GetMapId()} ({(newMap ? newMap.GetMapName() : "Unknown")}) because of unknown reason!");
+33 -36
View File
@@ -83,6 +83,8 @@ namespace Game.Maps
_poolData = Global.PoolMgr.InitPoolsForMap(this);
Global.TransportMgr.CreateTransportsForMap(this);
Global.MMapMgr.LoadMapInstance(Global.WorldMgr.GetDataPath(), GetId(), i_InstanceId);
Global.ScriptMgr.OnCreateMap(this);
@@ -408,12 +410,6 @@ namespace Game.Maps
player.Dispose();
}
void DeleteFromWorld(Transport transport)
{
Global.ObjAccessor.RemoveObject(transport);
transport.Dispose();
}
void DeleteFromWorld(WorldObject obj)
{
obj.Dispose();
@@ -642,20 +638,24 @@ namespace Game.Maps
return false; //Should delete object
}
obj.AddToWorld();
_transports.Add(obj);
// Broadcast creation to players
foreach (Player player in GetPlayers())
if (obj.GetExpectedMapId() == GetId())
{
if (player.GetTransport() != obj)
obj.AddToWorld();
// Broadcast creation to players
foreach (var player in GetPlayers())
{
var data = new UpdateData(GetId());
obj.BuildCreateUpdateBlockForPlayer(data, player);
player.m_visibleTransports.Add(obj.GetGUID());
UpdateObject packet;
data.BuildPacket(out packet);
player.SendPacket(packet);
if (player.GetTransport() != obj && player.IsInPhase(obj))
{
var data = new UpdateData(GetId());
obj.BuildCreateUpdateBlockForPlayer(data, player);
player.m_visibleTransports.Add(obj.GetGUID());
UpdateObject packet;
data.BuildPacket(out packet);
player.SendPacket(packet);
}
}
}
@@ -830,7 +830,7 @@ namespace Game.Maps
for (var i = 0; i < _transports.Count; ++i)
{
Transport transport = _transports[i];
if (!transport || !transport.IsInWorld)
if (!transport)
continue;
transport.Update(diff);
@@ -1011,19 +1011,22 @@ namespace Game.Maps
public void RemoveFromMap(Transport obj, bool remove)
{
obj.RemoveFromWorld();
var players = GetPlayers();
if (!players.Empty())
if (obj.IsInWorld)
{
obj.RemoveFromWorld();
UpdateData data = new(GetId());
obj.BuildOutOfRangeUpdateBlock(data);
if (obj.IsDestroyedObject())
obj.BuildDestroyUpdateBlock(data);
else
obj.BuildOutOfRangeUpdateBlock(data);
UpdateObject packet;
data.BuildPacket(out packet);
foreach (var player in players)
foreach (var player in GetPlayers())
{
if (player.GetTransport() != obj)
if (player.GetTransport() != obj && player.m_visibleTransports.Contains(obj.GetGUID()))
{
player.SendPacket(packet);
player.m_visibleTransports.Remove(obj.GetGUID());
@@ -2270,11 +2273,11 @@ namespace Game.Maps
void SendInitTransports(Player player)
{
var transData = new UpdateData(player.GetMapId());
var transData = new UpdateData(GetId());
foreach (Transport transport in _transports)
{
if (transport != player.GetTransport() && player.IsInPhase(transport))
if (transport.IsInWorld && transport != player.GetTransport() && player.IsInPhase(transport))
{
transport.BuildCreateUpdateBlockForPlayer(transData, player);
player.m_visibleTransports.Add(transport.GetGUID());
@@ -2291,7 +2294,7 @@ namespace Game.Maps
var transData = new UpdateData(player.GetMapId());
foreach (Transport transport in _transports)
{
if (transport != player.GetTransport())
if (player.m_visibleTransports.Contains(transport.GetGUID()) && transport != player.GetTransport())
{
transport.BuildOutOfRangeUpdateBlock(transData);
player.m_visibleTransports.Remove(transport.GetGUID());
@@ -2309,6 +2312,9 @@ namespace Game.Maps
UpdateData transData = new(player.GetMapId());
foreach (var transport in _transports)
{
if (!transport.IsInWorld)
continue;
var hasTransport = player.m_visibleTransports.Contains(transport.GetGUID());
if (player.IsInPhase(transport))
{
@@ -2914,15 +2920,6 @@ namespace Game.Maps
while (_farSpellCallbacks.TryDequeue(out FarSpellCallback callback))
callback(this);
for (var i = 0; i < _transports.Count; ++i)
{
Transport transport = _transports[i];
if (!transport.IsInWorld)
continue;
transport.DelayedUpdate(diff);
}
RemoveAllObjectsInRemoveList();
// Don't unload grids if it's Battleground, since we may have manually added GOs, creatures, those doesn't load from DB at grid re-load !
+73 -92
View File
@@ -72,15 +72,7 @@ namespace Game.Maps
// paths are generated per template, saves us from generating it again in case of instanced transports
TransportTemplate transport = new();
List<uint> mapsUsed = new();
GeneratePath(goInfo, transport, mapsUsed);
_transportTemplates[entry] = transport;
// transports in instance are only on one map
if (transport.InInstance)
_instanceTransports.Add(mapsUsed.First(), entry);
GeneratePath(goInfo, transport);
++count;
} while (result.NextRow());
@@ -118,7 +110,8 @@ namespace Game.Maps
uint phaseId = result.Read<uint>(3);
uint phaseGroupId = result.Read<uint>(4);
if (GetTransportTemplate(entry) == null)
TransportTemplate transportTemplate = GetTransportTemplate(entry);
if (transportTemplate == null)
{
Log.outError(LogFilter.Sql, $"Table `transports` have transport (GUID: {guid} Entry: {entry}) with unknown gameobject `entry` set, skipped.");
continue;
@@ -167,6 +160,9 @@ namespace Game.Maps
spawn.PhaseId = phaseId;
spawn.PhaseGroup = phaseGroupId;
foreach (uint mapId in transportTemplate.MapIds)
_transportsByMap[mapId].Add(spawn);
_transportSpawns[guid] = spawn;
} while (result.NextRow());
@@ -321,7 +317,7 @@ namespace Game.Maps
}
}
void GeneratePath(GameObjectTemplate goInfo, TransportTemplate transport, List<uint> mapsUsed)
void GeneratePath(GameObjectTemplate goInfo, TransportTemplate transport)
{
uint pathId = goInfo.MoTransport.taxiPathID;
TaxiPathNodeRecord[] path = CliDB.TaxiPathNodesByPath[pathId];
@@ -360,21 +356,21 @@ namespace Game.Maps
if (node.ArrivalEventID != 0 || node.DepartureEventID != 0)
events.Add(node);
mapsUsed.Add(node.ContinentID);
transport.MapIds.Add(node.ContinentID);
}
if (leg.Spline == null)
InitializeLeg(leg, transport.Events, pathPoints, pauses, events, goInfo, ref totalTime);
if (mapsUsed.Count > 1)
if (transport.MapIds.Count > 1)
{
foreach (uint mapId in mapsUsed)
foreach (uint mapId in transport.MapIds)
Cypher.Assert(!CliDB.MapStorage.LookupByKey(mapId).Instanceable());
transport.InInstance = false;
}
else
transport.InInstance = CliDB.MapStorage.LookupByKey(mapsUsed.First()).Instanceable();
transport.InInstance = CliDB.MapStorage.LookupByKey(transport.MapIds.First()).Instanceable();
transport.TotalPathTime = totalTime;
transport.PathLegs.Add(leg);
@@ -403,23 +399,20 @@ namespace Game.Maps
animNode.TotalTime = timeSeg;
}
public Transport CreateTransport(uint entry, ulong guid = 0, Map map = null, PhaseUseFlagsValues phaseUseFlags = 0, uint phaseId = 0, uint phaseGroupId = 0)
public Transport CreateTransport(uint entry, Map map, ulong guid = 0, PhaseUseFlagsValues phaseUseFlags = 0, uint phaseId = 0, uint phaseGroupId = 0)
{
// instance case, execute GetGameObjectEntry hook
if (map != null)
// SetZoneScript() is called after adding to map, so fetch the script using map
InstanceMap instanceMap = map.ToInstanceMap();
if (instanceMap != null)
{
// SetZoneScript() is called after adding to map, so fetch the script using map
if (map.IsDungeon())
{
InstanceScript instance = ((InstanceMap)map).GetInstanceScript();
if (instance != null)
entry = instance.GetGameObjectEntry(0, entry);
}
if (entry == 0)
return null;
InstanceScript instance = instanceMap.GetInstanceScript();
if (instance != null)
entry = instance.GetGameObjectEntry(0, entry);
}
if (entry == 0)
return null;
TransportTemplate tInfo = GetTransportTemplate(entry);
if (tInfo == null)
{
@@ -446,7 +439,7 @@ namespace Game.Maps
// initialize the gameobject base
ulong guidLow = guid != 0 ? guid : map.GenerateLowGuid(HighGuid.Transport);
if (!trans.Create(guidLow, entry, mapId, x, y, z, o, 255))
if (!trans.Create(guidLow, entry, x, y, z, o))
return null;
PhasingHandler.InitDbPhaseShift(trans.GetPhaseShift(), phaseUseFlags, phaseId, phaseGroupId);
@@ -462,42 +455,27 @@ namespace Game.Maps
}
// use preset map for instances (need to know which instance)
trans.SetMap(map != null ? map : Global.MapMgr.CreateMap(mapId, null));
if (map != null && map.IsDungeon())
trans.m_zoneScript = map.ToInstanceMap().GetInstanceScript();
trans.SetMap(map);
if (instanceMap != null)
trans.m_zoneScript = instanceMap.GetInstanceScript();
// Passengers will be loaded once a player is near
Global.ObjAccessor.AddObject(trans);
trans.GetMap().AddToMap(trans);
map.AddToMap(trans);
return trans;
}
public void SpawnContinentTransports()
public void CreateTransportsForMap(Map map)
{
uint oldMSTime = Time.GetMSTime();
uint count = 0;
foreach (var pair in _transportSpawns)
if (!GetTransportTemplate(pair.Value.TransportGameObjectId).InInstance)
if (CreateTransport(pair.Value.TransportGameObjectId, pair.Value.SpawnId, null, pair.Value.PhaseUseFlags, pair.Value.PhaseId, pair.Value.PhaseGroup))
++count;
Log.outInfo(LogFilter.ServerLoading, "Spawned {0} continent transports in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
}
public void CreateInstanceTransports(Map map)
{
var mapTransports = _instanceTransports.LookupByKey(map.GetId());
var mapTransports = _transportsByMap.LookupByKey(map.GetId());
// no transports here
if (mapTransports.Empty())
return;
// create transports
foreach (var transportGameObjectId in mapTransports)
CreateTransport(transportGameObjectId, 0, map);
foreach (var transport in mapTransports)
CreateTransport(transport.TransportGameObjectId, map, transport.SpawnId, transport.PhaseUseFlags, transport.PhaseId, transport.PhaseGroup);
}
public TransportTemplate GetTransportTemplate(uint entry)
@@ -516,7 +494,7 @@ namespace Game.Maps
}
Dictionary<uint, TransportTemplate> _transportTemplates = new();
MultiMap<uint, uint> _instanceTransports = new();
MultiMap<uint, TransportSpawn> _transportsByMap = new();
Dictionary<uint, TransportAnimation> _transportAnimations = new();
Dictionary<ulong, TransportSpawn> _transportSpawns = new();
}
@@ -553,34 +531,29 @@ namespace Game.Maps
public List<TransportPathLeg> PathLegs = new();
public List<TransportPathEvent> Events = new();
public List<uint> MapIds = new();
public bool InInstance;
public Position ComputePosition(uint time, out TransportMovementState moveState, out int legIndex)
{
moveState = TransportMovementState.Moving;
legIndex = 0;
time %= TotalPathTime;
// find leg
legIndex = 0;
while (PathLegs[legIndex].StartTimestamp + PathLegs[legIndex].Duration <= time)
{
++legIndex;
if (PathLegs.Count >= legIndex)
return null;
}
var legItr = PathLegs[legIndex];
TransportPathLeg leg = GetLegForTime(time);
if (leg == null)
return null;
// find segment
uint prevSegmentTime = legItr.StartTimestamp;
uint prevSegmentTime = leg.StartTimestamp;
var segmentIndex = 0;
double distanceMoved = 0.0;
bool isOnPause = false;
for (segmentIndex = 0; segmentIndex < legItr.Segments.Count; ++segmentIndex)
for (segmentIndex = 0; segmentIndex < leg.Segments.Count; ++segmentIndex)
{
var segment = legItr.Segments[segmentIndex];
var segment = leg.Segments[segmentIndex];
if (time < segment.SegmentEndArrivalTimestamp)
break;
@@ -594,28 +567,57 @@ namespace Game.Maps
prevSegmentTime = segment.SegmentEndArrivalTimestamp + segment.Delay;
}
var pathSegment = legItr.Segments[segmentIndex];
var pathSegment = leg.Segments[segmentIndex];
if (!isOnPause)
distanceMoved += CalculateDistanceMoved(
(double)(time - prevSegmentTime) * 0.001,
(double)(pathSegment.SegmentEndArrivalTimestamp - prevSegmentTime) * 0.001,
segmentIndex == 0,
segmentIndex == legItr.Segments.Count);
segmentIndex == leg.Segments.Count);
int splineIndex = 0;
float splinePointProgress = 0;
legItr.Spline.ComputeIndex((float)Math.Min(distanceMoved / legItr.Spline.Length(), 1.0), ref splineIndex, ref splinePointProgress);
leg.Spline.ComputeIndex((float)Math.Min(distanceMoved / leg.Spline.Length(), 1.0), ref splineIndex, ref splinePointProgress);
Vector3 pos, dir;
legItr.Spline.Evaluate_Percent(splineIndex, splinePointProgress, out pos);
legItr.Spline.Evaluate_Derivative(splineIndex, splinePointProgress, out dir);
leg.Spline.Evaluate_Percent(splineIndex, splinePointProgress, out pos);
leg.Spline.Evaluate_Derivative(splineIndex, splinePointProgress, out dir);
moveState = isOnPause ? TransportMovementState.WaitingOnPauseWaypoint : TransportMovementState.Moving;
legIndex = PathLegs.IndexOf(leg);
return new Position(pos.X, pos.Y, pos.Z, MathF.Atan2(dir.Y, dir.X) + MathF.PI);
}
public TransportPathLeg GetLegForTime(uint time)
{
int legIndex = 0;
while (PathLegs[legIndex].StartTimestamp + PathLegs[legIndex].Duration <= time)
{
++legIndex;
if (PathLegs.Count >= legIndex)
return null;
}
return PathLegs[legIndex];
}
public uint GetNextPauseWaypointTimestamp(uint time)
{
TransportPathLeg leg = GetLegForTime(time);
if (leg == null)
return time;
int segmentIndex = 0;
for (; segmentIndex != leg.Segments.Count - 1; ++segmentIndex)
if (time < leg.Segments[segmentIndex].SegmentEndArrivalTimestamp + leg.Segments[segmentIndex].Delay)
break;
return leg.Segments[segmentIndex].SegmentEndArrivalTimestamp + leg.Segments[segmentIndex].Delay;
}
double CalculateDistanceMoved(double timePassedInSegment, double segmentDuration, bool isFirstSegment, bool isLastSegment)
{
if (isFirstSegment)
@@ -669,27 +671,6 @@ namespace Game.Maps
+ (2.0 * AccelerationRate * accelerationTime1 - segmentTimeSpentAccelerating * AccelerationRate) * 0.5 * segmentTimeSpentAccelerating;
}
}
public uint GetNextPauseWaypointTimestamp(uint time)
{
var legIndex = 0;
while (PathLegs[legIndex].StartTimestamp + PathLegs[legIndex].Duration <= time)
{
++legIndex;
if (legIndex >= PathLegs.Count)
return time;
}
var leg = PathLegs[legIndex];
var segmentIndex = 0;
for (; segmentIndex != leg.Segments.Count - 1; ++segmentIndex)
if (time < leg.Segments[segmentIndex].SegmentEndArrivalTimestamp + leg.Segments[segmentIndex].Delay)
break;
return leg.Segments[segmentIndex].SegmentEndArrivalTimestamp + leg.Segments[segmentIndex].Delay;
}
}
public class SplineRawInitializer
-3
View File
@@ -1053,9 +1053,6 @@ namespace Game
Log.outInfo(LogFilter.ServerLoading, "Starting Battlefield System");
Global.BattleFieldMgr.InitBattlefield();
Log.outInfo(LogFilter.ServerLoading, "Loading Transports...");
Global.TransportMgr.SpawnContinentTransports();
// Initialize Warden
Log.outInfo(LogFilter.ServerLoading, "Loading Warden Checks...");
Global.WardenCheckMgr.LoadWardenChecks();