mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-06-09 10:06:34 +02:00
Update map loader to work with grid entities.
This commit is contained in:
@@ -16,6 +16,7 @@ using System.Globalization;
|
|||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Robust.Server.Interfaces.Timing;
|
using Robust.Server.Interfaces.Timing;
|
||||||
|
using Robust.Shared.GameObjects.Components.Map;
|
||||||
using YamlDotNet.Core;
|
using YamlDotNet.Core;
|
||||||
|
|
||||||
namespace Robust.Server.Maps
|
namespace Robust.Server.Maps
|
||||||
@@ -32,7 +33,7 @@ namespace Robust.Server.Maps
|
|||||||
private readonly IResourceManager _resMan;
|
private readonly IResourceManager _resMan;
|
||||||
|
|
||||||
[Dependency]
|
[Dependency]
|
||||||
private readonly IMapManager _mapManager;
|
private readonly IMapManagerInternal _mapManager;
|
||||||
|
|
||||||
[Dependency]
|
[Dependency]
|
||||||
private readonly ITileDefinitionManager _tileDefinitionManager;
|
private readonly ITileDefinitionManager _tileDefinitionManager;
|
||||||
@@ -207,7 +208,7 @@ namespace Robust.Server.Maps
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private class MapContext : YamlObjectSerializer.Context, IEntityLoadContext
|
private class MapContext : YamlObjectSerializer.Context, IEntityLoadContext
|
||||||
{
|
{
|
||||||
private readonly IMapManager _mapManager;
|
private readonly IMapManagerInternal _mapManager;
|
||||||
private readonly ITileDefinitionManager _tileDefinitionManager;
|
private readonly ITileDefinitionManager _tileDefinitionManager;
|
||||||
private readonly IServerEntityManagerInternal _serverEntityManager;
|
private readonly IServerEntityManagerInternal _serverEntityManager;
|
||||||
private readonly IPauseManager _pauseManager;
|
private readonly IPauseManager _pauseManager;
|
||||||
@@ -219,6 +220,10 @@ namespace Robust.Server.Maps
|
|||||||
private readonly Dictionary<int, EntityUid> UidEntityMap = new Dictionary<int, EntityUid>();
|
private readonly Dictionary<int, EntityUid> UidEntityMap = new Dictionary<int, EntityUid>();
|
||||||
public readonly List<IEntity> Entities = new List<IEntity>();
|
public readonly List<IEntity> Entities = new List<IEntity>();
|
||||||
|
|
||||||
|
private readonly List<(IEntity, YamlMappingNode)> _entitiesToDeserialize
|
||||||
|
= new List<(IEntity, YamlMappingNode)>();
|
||||||
|
|
||||||
|
private bool IsBlueprintMode => GridIDMap.Count == 1;
|
||||||
|
|
||||||
private int uidCounter;
|
private int uidCounter;
|
||||||
|
|
||||||
@@ -234,7 +239,7 @@ namespace Robust.Server.Maps
|
|||||||
|
|
||||||
public bool MapIsPostInit { get; private set; }
|
public bool MapIsPostInit { get; private set; }
|
||||||
|
|
||||||
public MapContext(IMapManager maps, ITileDefinitionManager tileDefs, IServerEntityManagerInternal entities, IPauseManager pauseManager)
|
public MapContext(IMapManagerInternal maps, ITileDefinitionManager tileDefs, IServerEntityManagerInternal entities, IPauseManager pauseManager)
|
||||||
{
|
{
|
||||||
_mapManager = maps;
|
_mapManager = maps;
|
||||||
_tileDefinitionManager = tileDefs;
|
_tileDefinitionManager = tileDefs;
|
||||||
@@ -244,7 +249,7 @@ namespace Robust.Server.Maps
|
|||||||
RootNode = new YamlMappingNode();
|
RootNode = new YamlMappingNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapContext(IMapManager maps, ITileDefinitionManager tileDefs, IServerEntityManagerInternal entities,
|
public MapContext(IMapManagerInternal maps, ITileDefinitionManager tileDefs, IServerEntityManagerInternal entities,
|
||||||
IPauseManager pauseManager, YamlMappingNode node, MapId targetMapId)
|
IPauseManager pauseManager, YamlMappingNode node, MapId targetMapId)
|
||||||
{
|
{
|
||||||
_mapManager = maps;
|
_mapManager = maps;
|
||||||
@@ -273,6 +278,14 @@ namespace Robust.Server.Maps
|
|||||||
// Actually instance components and run ExposeData on them.
|
// Actually instance components and run ExposeData on them.
|
||||||
FinishEntitiesLoad();
|
FinishEntitiesLoad();
|
||||||
|
|
||||||
|
// Grid entities were NOT created inside ReadGridSection().
|
||||||
|
// We have to fix the created grids up with the grid entities deserialized from the map.
|
||||||
|
FixMapEntities();
|
||||||
|
|
||||||
|
// We have to attach grids to the target map here.
|
||||||
|
// If we don't, initialization & startup can fail for some entities.
|
||||||
|
AttachMapEntities();
|
||||||
|
|
||||||
// Run Initialize on all components.
|
// Run Initialize on all components.
|
||||||
FinishEntitiesInitialization();
|
FinishEntitiesInitialization();
|
||||||
|
|
||||||
@@ -280,6 +293,29 @@ namespace Robust.Server.Maps
|
|||||||
FinishEntitiesStartup();
|
FinishEntitiesStartup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AttachMapEntities()
|
||||||
|
{
|
||||||
|
var mapEntity = _mapManager.GetMapEntity(TargetMap);
|
||||||
|
|
||||||
|
foreach (var grid in Grids)
|
||||||
|
{
|
||||||
|
var entity = _serverEntityManager.GetEntity(grid.GridEntity);
|
||||||
|
entity.Transform.AttachParent(mapEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FixMapEntities()
|
||||||
|
{
|
||||||
|
foreach (var entity in Entities)
|
||||||
|
{
|
||||||
|
if (entity.TryGetComponent(out IMapGridComponent grid))
|
||||||
|
{
|
||||||
|
var castGrid = (MapGrid) grid.Grid;
|
||||||
|
castGrid.GridEntity = entity.Uid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ReadMetaSection()
|
private void ReadMetaSection()
|
||||||
{
|
{
|
||||||
var meta = RootNode.GetNode<YamlMappingNode>("meta");
|
var meta = RootNode.GetNode<YamlMappingNode>("meta");
|
||||||
@@ -340,23 +376,28 @@ namespace Robust.Server.Maps
|
|||||||
var entities = RootNode.GetNode<YamlSequenceNode>("entities");
|
var entities = RootNode.GetNode<YamlSequenceNode>("entities");
|
||||||
foreach (var entityDef in entities.Cast<YamlMappingNode>())
|
foreach (var entityDef in entities.Cast<YamlMappingNode>())
|
||||||
{
|
{
|
||||||
var type = entityDef.GetNode("type").AsString();
|
string type = null;
|
||||||
|
if (entityDef.TryGetNode("type", out var typeNode))
|
||||||
|
{
|
||||||
|
type = typeNode.AsString();
|
||||||
|
}
|
||||||
|
|
||||||
var uid = Entities.Count;
|
var uid = Entities.Count;
|
||||||
if (entityDef.TryGetNode("uid", out var uidNode))
|
if (entityDef.TryGetNode("uid", out var uidNode))
|
||||||
{
|
{
|
||||||
uid = uidNode.AsInt();
|
uid = uidNode.AsInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
var entity = _serverEntityManager.AllocEntity(type);
|
var entity = _serverEntityManager.AllocEntity(type);
|
||||||
Entities.Add(entity);
|
Entities.Add(entity);
|
||||||
UidEntityMap.Add(uid, entity.Uid);
|
UidEntityMap.Add(uid, entity.Uid);
|
||||||
|
_entitiesToDeserialize.Add((entity, entityDef));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FinishEntitiesLoad()
|
private void FinishEntitiesLoad()
|
||||||
{
|
{
|
||||||
var entityData = RootNode.GetNode<YamlSequenceNode>("entities");
|
foreach (var (entity, data) in _entitiesToDeserialize)
|
||||||
|
|
||||||
foreach (var (entity, data) in Entities.Zip(entityData, (a, b) => (a, (YamlMappingNode)b)))
|
|
||||||
{
|
{
|
||||||
CurrentReadingEntityComponents = new Dictionary<string, YamlMappingNode>();
|
CurrentReadingEntityComponents = new Dictionary<string, YamlMappingNode>();
|
||||||
if (data.TryGetNode("components", out YamlSequenceNode componentList))
|
if (data.TryGetNode("components", out YamlSequenceNode componentList))
|
||||||
@@ -478,10 +519,14 @@ namespace Robust.Server.Maps
|
|||||||
CurrentWritingEntity = entity;
|
CurrentWritingEntity = entity;
|
||||||
var mapping = new YamlMappingNode
|
var mapping = new YamlMappingNode
|
||||||
{
|
{
|
||||||
{"type", entity.Prototype.ID},
|
|
||||||
{"uid", EntityUidMap[entity.Uid].ToString(CultureInfo.InvariantCulture)}
|
{"uid", EntityUidMap[entity.Uid].ToString(CultureInfo.InvariantCulture)}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (entity.Prototype != null)
|
||||||
|
{
|
||||||
|
mapping.Add("type", entity.Prototype.ID);
|
||||||
|
}
|
||||||
|
|
||||||
var components = new YamlSequenceNode();
|
var components = new YamlSequenceNode();
|
||||||
// See engine#636 for why the Distinct() call.
|
// See engine#636 for why the Distinct() call.
|
||||||
foreach (var component in entity.GetAllComponents())
|
foreach (var component in entity.GetAllComponents())
|
||||||
@@ -514,6 +559,12 @@ namespace Robust.Server.Maps
|
|||||||
{
|
{
|
||||||
if (type == typeof(GridId))
|
if (type == typeof(GridId))
|
||||||
{
|
{
|
||||||
|
if (node.AsString() == "null")
|
||||||
|
{
|
||||||
|
obj = GridId.Nullspace;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
var val = node.AsInt();
|
var val = node.AsInt();
|
||||||
if (val >= Grids.Count)
|
if (val >= Grids.Count)
|
||||||
{
|
{
|
||||||
@@ -527,6 +578,12 @@ namespace Robust.Server.Maps
|
|||||||
}
|
}
|
||||||
if (type == typeof(EntityUid))
|
if (type == typeof(EntityUid))
|
||||||
{
|
{
|
||||||
|
if (node.AsString() == "null")
|
||||||
|
{
|
||||||
|
obj = EntityUid.Invalid;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
var val = node.AsInt();
|
var val = node.AsInt();
|
||||||
if (val >= Entities.Count)
|
if (val >= Entities.Count)
|
||||||
{
|
{
|
||||||
@@ -574,8 +631,15 @@ namespace Robust.Server.Maps
|
|||||||
case EntityUid entityUid:
|
case EntityUid entityUid:
|
||||||
if (!EntityUidMap.TryGetValue(entityUid, out var entityUidMapped))
|
if (!EntityUidMap.TryGetValue(entityUid, out var entityUidMapped))
|
||||||
{
|
{
|
||||||
Logger.WarningS("map", "Cannot write entity UID '{0}'.", entityUid);
|
// Terrible hack to mute this warning on the grids themselves when serializing blueprints.
|
||||||
break;
|
if (!IsBlueprintMode || !CurrentWritingEntity.HasComponent<MapGridComponent>() ||
|
||||||
|
CurrentWritingComponent != "Transform")
|
||||||
|
{
|
||||||
|
Logger.WarningS("map", "Cannot write entity UID '{0}'.", entityUid);
|
||||||
|
}
|
||||||
|
|
||||||
|
node = new YamlScalarNode("null");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -627,11 +691,18 @@ namespace Robust.Server.Maps
|
|||||||
|
|
||||||
public override bool IsValueDefault<T>(string field, T value)
|
public override bool IsValueDefault<T>(string field, T value)
|
||||||
{
|
{
|
||||||
|
if (CurrentWritingEntity.Prototype == null)
|
||||||
|
{
|
||||||
|
// No prototype, can't be default.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!CurrentWritingEntity.Prototype.Components.TryGetValue(CurrentWritingComponent, out var compData))
|
if (!CurrentWritingEntity.Prototype.Components.TryGetValue(CurrentWritingComponent, out var compData))
|
||||||
{
|
{
|
||||||
// This component was added mid-game.
|
// This component was added mid-game.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var testSer = YamlObjectSerializer.NewReader(compData);
|
var testSer = YamlObjectSerializer.NewReader(compData);
|
||||||
if (testSer.TryReadDataFieldCached(field, out T prototypeVal))
|
if (testSer.TryReadDataFieldCached(field, out T prototypeVal))
|
||||||
{
|
{
|
||||||
@@ -648,7 +719,7 @@ namespace Robust.Server.Maps
|
|||||||
|
|
||||||
private bool IsMapSavable(IEntity entity)
|
private bool IsMapSavable(IEntity entity)
|
||||||
{
|
{
|
||||||
if (!entity.Prototype.MapSavable || !GridIDMap.ContainsKey(entity.Transform.GridID))
|
if (entity.Prototype?.MapSavable == false || !GridIDMap.ContainsKey(entity.Transform.GridID))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -658,7 +729,7 @@ namespace Robust.Server.Maps
|
|||||||
var current = entity.Transform;
|
var current = entity.Transform;
|
||||||
while (current.Parent != null)
|
while (current.Parent != null)
|
||||||
{
|
{
|
||||||
if (!current.Parent.Owner.Prototype.MapSavable)
|
if (current.Parent.Owner.Prototype?.MapSavable == false)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ using YamlDotNet.RepresentationModel;
|
|||||||
|
|
||||||
namespace Robust.Server.Maps
|
namespace Robust.Server.Maps
|
||||||
{
|
{
|
||||||
public static class YamlGridSerializer
|
internal static class YamlGridSerializer
|
||||||
{
|
{
|
||||||
public static YamlMappingNode SerializeGrid(IMapGrid mapGrid)
|
public static YamlMappingNode SerializeGrid(IMapGrid mapGrid)
|
||||||
{
|
{
|
||||||
@@ -28,7 +28,6 @@ namespace Robust.Server.Maps
|
|||||||
info.Add("chunksize", grid.ChunkSize.ToString(CultureInfo.InvariantCulture));
|
info.Add("chunksize", grid.ChunkSize.ToString(CultureInfo.InvariantCulture));
|
||||||
info.Add("tilesize", grid.TileSize.ToString(CultureInfo.InvariantCulture));
|
info.Add("tilesize", grid.TileSize.ToString(CultureInfo.InvariantCulture));
|
||||||
info.Add("snapsize", grid.SnapSize.ToString(CultureInfo.InvariantCulture));
|
info.Add("snapsize", grid.SnapSize.ToString(CultureInfo.InvariantCulture));
|
||||||
info.Add("worldpos", $"{grid.WorldPosition.X},{grid.WorldPosition.Y}");
|
|
||||||
|
|
||||||
var chunks = grid.GetMapChunks();
|
var chunks = grid.GetMapChunks();
|
||||||
foreach (var chunk in chunks)
|
foreach (var chunk in chunks)
|
||||||
@@ -80,14 +79,13 @@ namespace Robust.Server.Maps
|
|||||||
return Convert.ToBase64String(barr);
|
return Convert.ToBase64String(barr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DeserializeGrid(IMapManager mapMan, MapId mapId, ref GridId? gridId, YamlMappingNode info,
|
public static void DeserializeGrid(IMapManagerInternal mapMan, MapId mapId, ref GridId? gridId, YamlMappingNode info,
|
||||||
YamlSequenceNode chunks, IReadOnlyDictionary<ushort, string> tileDefMapping,
|
YamlSequenceNode chunks, IReadOnlyDictionary<ushort, string> tileDefMapping,
|
||||||
ITileDefinitionManager tileDefinitionManager)
|
ITileDefinitionManager tileDefinitionManager)
|
||||||
{
|
{
|
||||||
ushort csz = 0;
|
ushort csz = 0;
|
||||||
ushort tsz = 0;
|
ushort tsz = 0;
|
||||||
float sgsz = 0.0f;
|
float sgsz = 0.0f;
|
||||||
var worldPos = Vector2.Zero;
|
|
||||||
|
|
||||||
foreach (var kvInfo in info)
|
foreach (var kvInfo in info)
|
||||||
{
|
{
|
||||||
@@ -99,11 +97,9 @@ namespace Robust.Server.Maps
|
|||||||
tsz = ushort.Parse(val);
|
tsz = ushort.Parse(val);
|
||||||
else if (key == "snapsize")
|
else if (key == "snapsize")
|
||||||
sgsz = float.Parse(val);
|
sgsz = float.Parse(val);
|
||||||
else if (key == "worldpos")
|
|
||||||
worldPos = kvInfo.Value.AsVector2();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var grid = mapMan.CreateGrid(mapId, gridId);
|
var grid = mapMan.CreateGridNoEntity(mapId, gridId);
|
||||||
|
|
||||||
gridId = grid.Index;
|
gridId = grid.Index;
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +1,23 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Robust.Shared.Animations;
|
using Robust.Shared.Animations;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
using Robust.Shared.Enums;
|
using Robust.Shared.Enums;
|
||||||
using Robust.Shared.GameObjects.Components.Map;
|
using Robust.Shared.GameObjects.Components.Map;
|
||||||
using Robust.Shared.GameObjects.EntitySystemMessages;
|
using Robust.Shared.GameObjects.EntitySystemMessages;
|
||||||
using Robust.Shared.Interfaces.GameObjects;
|
using Robust.Shared.Interfaces.GameObjects;
|
||||||
using Robust.Shared.Interfaces.GameObjects.Components;
|
using Robust.Shared.Interfaces.GameObjects.Components;
|
||||||
using Robust.Shared.Interfaces.Map;
|
using Robust.Shared.Interfaces.Map;
|
||||||
using Robust.Shared.Interfaces.Timing;
|
using Robust.Shared.Interfaces.Timing;
|
||||||
using Robust.Shared.IoC;
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Log;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Maths;
|
||||||
using Robust.Shared.Maths;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Utility;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.ViewVariables;
|
||||||
using Robust.Shared.ViewVariables;
|
|
||||||
|
|
||||||
namespace Robust.Shared.GameObjects.Components.Transform
|
namespace Robust.Shared.GameObjects.Components.Transform
|
||||||
{
|
{
|
||||||
internal class TransformComponent : Component, ITransformComponent, IComponentDebug
|
internal class TransformComponent : Component, ITransformComponent, IComponentDebug
|
||||||
{
|
{
|
||||||
@@ -33,22 +32,23 @@
|
|||||||
private Vector2 _nextPosition;
|
private Vector2 _nextPosition;
|
||||||
private Angle _nextRotation;
|
private Angle _nextRotation;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables] private readonly List<EntityUid> _children = new List<EntityUid>();
|
||||||
private readonly List<EntityUid> _children = new List<EntityUid>();
|
|
||||||
|
|
||||||
#pragma warning disable 649
|
#pragma warning disable 649
|
||||||
[Dependency] private readonly IMapManager _mapManager;
|
[Dependency] private readonly IMapManager _mapManager;
|
||||||
[Dependency] private readonly IGameTiming _gameTiming;
|
[Dependency] private readonly IGameTiming _gameTiming;
|
||||||
[Dependency] private readonly IEntityManager _entityManager;
|
[Dependency] private readonly IEntityManager _entityManager;
|
||||||
#pragma warning restore 649
|
#pragma warning restore 649
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public event EventHandler<MoveEventArgs> OnMove;
|
public event EventHandler<MoveEventArgs> OnMove;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override string Name => "Transform";
|
public override string Name => "Transform";
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public sealed override uint? NetID => NetIDs.TRANSFORM;
|
public sealed override uint? NetID => NetIDs.TRANSFORM;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public sealed override Type StateType => typeof(TransformComponentState);
|
public sealed override Type StateType => typeof(TransformComponentState);
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
get
|
get
|
||||||
{
|
{
|
||||||
// root node, grid id is undefined
|
// root node, grid id is undefined
|
||||||
if(Owner.HasComponent<IMapComponent>())
|
if (Owner.HasComponent<IMapComponent>())
|
||||||
return GridId.Nullspace;
|
return GridId.Nullspace;
|
||||||
|
|
||||||
// second level node, terminates recursion up the branch of the tree
|
// second level node, terminates recursion up the branch of the tree
|
||||||
@@ -119,6 +119,7 @@
|
|||||||
{
|
{
|
||||||
return Parent.WorldRotation + GetLocalRotation();
|
return Parent.WorldRotation + GetLocalRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetLocalRotation();
|
return GetLocalRotation();
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
@@ -158,6 +159,7 @@
|
|||||||
Matrix3.Multiply(ref myMatrix, ref parentMatrix, out var result);
|
Matrix3.Multiply(ref myMatrix, ref parentMatrix, out var result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetWorldMatrix();
|
return GetWorldMatrix();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -174,6 +176,7 @@
|
|||||||
Matrix3.Multiply(ref matP, ref myMatrix, out var result);
|
Matrix3.Multiply(ref matP, ref myMatrix, out var result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetWorldMatrixInv();
|
return GetWorldMatrixInv();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,59 +307,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public IEnumerable<ITransformComponent> Children => _children.Select(u => Owner.EntityManager.GetEntity(u).Transform);
|
public IEnumerable<ITransformComponent> Children =>
|
||||||
|
_children.Select(u => Owner.EntityManager.GetEntity(u).Transform);
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Vector2 LerpDestination => _nextPosition;
|
public Vector2 LerpDestination => _nextPosition;
|
||||||
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
// Attempt to parent itself it the defined grid.
|
|
||||||
if (!_parent.IsValid())
|
|
||||||
{
|
|
||||||
if (!Owner.HasComponent<IMapComponent>())
|
|
||||||
{
|
|
||||||
if (Owner.HasComponent<IMapGridComponent>())
|
|
||||||
{
|
|
||||||
DebugTools.Assert("This should have been set up by the map system.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Parent me to the grid comp
|
|
||||||
if (_gridID != GridId.Nullspace)
|
|
||||||
{
|
|
||||||
var mapGrid = _mapManager.GetGrid(_gridID);
|
|
||||||
if(mapGrid.IsDefaultGrid)
|
|
||||||
{
|
|
||||||
var mapEnt = _mapManager.GetMapEntity(mapGrid.ParentMapId);
|
|
||||||
Logger.WarningS("scene", $"Auto-parenting entity {Owner.Uid} to map {mapGrid.ParentMapId}'s entity {mapEnt.Uid}");
|
|
||||||
AttachParent(mapEnt);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var gridEnt = _entityManager.GetEntity(mapGrid.GridEntity);
|
|
||||||
Logger.WarningS("scene", $"Auto-parenting entity {Owner.Uid} to grid {_gridID}'s entity {gridEnt.Uid}");
|
|
||||||
AttachParent(gridEnt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DebugTools.Assert("My location is unknown!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// I am the root node of the scene graph
|
|
||||||
_gridID = GridId.Nullspace;
|
|
||||||
_localPosition = Vector2.Zero;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
base.Initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void Startup()
|
protected override void Startup()
|
||||||
{
|
{
|
||||||
@@ -403,7 +359,7 @@
|
|||||||
var newMapEntity = _mapManager.GetMapEntity(mapPos.MapId);
|
var newMapEntity = _mapManager.GetMapEntity(mapPos.MapId);
|
||||||
|
|
||||||
// this would be a no-op
|
// this would be a no-op
|
||||||
if(newMapEntity == Parent.Owner)
|
if (newMapEntity == Parent.Owner)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var concrete = (TransformComponent) Parent;
|
var concrete = (TransformComponent) Parent;
|
||||||
@@ -414,7 +370,6 @@
|
|||||||
MapPosition = mapPos;
|
MapPosition = mapPos;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Dirty();
|
Dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,6 +416,7 @@
|
|||||||
{
|
{
|
||||||
return Parent.GetMapTransform();
|
return Parent.GetMapTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,7 +437,9 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return ContainsEntity(entityTransform.Parent); //Recursively search up the entities containers for this object
|
return
|
||||||
|
ContainsEntity(entityTransform
|
||||||
|
.Parent); //Recursively search up the entities containers for this object
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,15 +448,19 @@
|
|||||||
base.ExposeData(serializer);
|
base.ExposeData(serializer);
|
||||||
|
|
||||||
serializer.DataField(ref _parent, "parent", new EntityUid());
|
serializer.DataField(ref _parent, "parent", new EntityUid());
|
||||||
serializer.DataField(ref _gridID, "grid", GridId.Nullspace);
|
|
||||||
serializer.DataField(ref _localPosition, "pos", Vector2.Zero);
|
serializer.DataField(ref _localPosition, "pos", Vector2.Zero);
|
||||||
serializer.DataField(ref _localRotation, "rot", new Angle());
|
serializer.DataField(ref _localRotation, "rot", new Angle());
|
||||||
|
|
||||||
|
if (serializer.Reading && serializer.TryReadDataField("grid", out GridId grid))
|
||||||
|
{
|
||||||
|
_gridID = grid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override ComponentState GetComponentState()
|
public override ComponentState GetComponentState()
|
||||||
{
|
{
|
||||||
return new TransformComponentState(_localPosition, GridID, LocalRotation, Parent?.Owner?.Uid);
|
return new TransformComponentState(_localPosition, LocalRotation, Parent?.Owner?.Uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@@ -527,7 +489,7 @@
|
|||||||
rebuildMatrices = true;
|
rebuildMatrices = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_localPosition != newState.LocalPosition || (!_parent.IsValid() && GridID != newState.GridID))
|
if (_localPosition != newState.LocalPosition)
|
||||||
{
|
{
|
||||||
var oldPos = GridPosition;
|
var oldPos = GridPosition;
|
||||||
if (_localPosition != newState.LocalPosition)
|
if (_localPosition != newState.LocalPosition)
|
||||||
@@ -535,11 +497,6 @@
|
|||||||
SetPosition(newState.LocalPosition);
|
SetPosition(newState.LocalPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_parent.IsValid() && GridID != newState.GridID)
|
|
||||||
{
|
|
||||||
_recurseSetGridId(newState.GridID);
|
|
||||||
}
|
|
||||||
|
|
||||||
OnMove?.Invoke(this, new MoveEventArgs(oldPos, GridPosition));
|
OnMove?.Invoke(this, new MoveEventArgs(oldPos, GridPosition));
|
||||||
rebuildMatrices = true;
|
rebuildMatrices = true;
|
||||||
}
|
}
|
||||||
@@ -556,7 +513,7 @@
|
|||||||
_nextPosition = _localPosition; // this should cause the lerp to do nothing
|
_nextPosition = _localPosition; // this should cause the lerp to do nothing
|
||||||
|
|
||||||
if (nextState != null)
|
if (nextState != null)
|
||||||
_nextRotation = ((TransformComponentState)nextState).Rotation;
|
_nextRotation = ((TransformComponentState) nextState).Rotation;
|
||||||
else
|
else
|
||||||
_nextRotation = _localRotation; // this should cause the lerp to do nothing
|
_nextRotation = _localRotation; // this should cause the lerp to do nothing
|
||||||
}
|
}
|
||||||
@@ -574,10 +531,11 @@
|
|||||||
|
|
||||||
protected virtual Vector2 GetLocalPosition()
|
protected virtual Vector2 GetLocalPosition()
|
||||||
{
|
{
|
||||||
if(_gameTiming.InSimulation || _localPosition == _nextPosition || Owner.Uid.IsClientSide())
|
if (_gameTiming.InSimulation || _localPosition == _nextPosition || Owner.Uid.IsClientSide())
|
||||||
return _localPosition;
|
return _localPosition;
|
||||||
|
|
||||||
return Vector2.Lerp(_localPosition, _nextPosition, (float) (_gameTiming.TickRemainder.TotalSeconds / _gameTiming.TickPeriod.TotalSeconds));
|
return Vector2.Lerp(_localPosition, _nextPosition,
|
||||||
|
(float) (_gameTiming.TickRemainder.TotalSeconds / _gameTiming.TickPeriod.TotalSeconds));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual Angle GetLocalRotation()
|
protected virtual Angle GetLocalRotation()
|
||||||
@@ -585,7 +543,8 @@
|
|||||||
if (_gameTiming.InSimulation || _localRotation == _nextRotation || Owner.Uid.IsClientSide())
|
if (_gameTiming.InSimulation || _localRotation == _nextRotation || Owner.Uid.IsClientSide())
|
||||||
return _localRotation;
|
return _localRotation;
|
||||||
|
|
||||||
return Angle.Lerp(_localRotation, _nextRotation, (float)(_gameTiming.TickRemainder.TotalSeconds / _gameTiming.TickPeriod.TotalSeconds));
|
return Angle.Lerp(_localRotation, _nextRotation,
|
||||||
|
(float) (_gameTiming.TickRemainder.TotalSeconds / _gameTiming.TickPeriod.TotalSeconds));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual Matrix3 GetWorldMatrix()
|
protected virtual Matrix3 GetWorldMatrix()
|
||||||
@@ -598,7 +557,7 @@
|
|||||||
var rot = GetLocalRotation().Theta;
|
var rot = GetLocalRotation().Theta;
|
||||||
|
|
||||||
var posMat = Matrix3.CreateTranslation(pos);
|
var posMat = Matrix3.CreateTranslation(pos);
|
||||||
var rotMat = Matrix3.CreateRotation((float)rot);
|
var rotMat = Matrix3.CreateRotation((float) rot);
|
||||||
|
|
||||||
Matrix3.Multiply(ref rotMat, ref posMat, out var transMat);
|
Matrix3.Multiply(ref rotMat, ref posMat, out var transMat);
|
||||||
|
|
||||||
@@ -615,7 +574,7 @@
|
|||||||
var rot = GetLocalRotation().Theta;
|
var rot = GetLocalRotation().Theta;
|
||||||
|
|
||||||
var posMat = Matrix3.CreateTranslation(pos);
|
var posMat = Matrix3.CreateTranslation(pos);
|
||||||
var rotMat = Matrix3.CreateRotation((float)rot);
|
var rotMat = Matrix3.CreateRotation((float) rot);
|
||||||
var posImat = Matrix3.Invert(posMat);
|
var posImat = Matrix3.Invert(posMat);
|
||||||
var rotImap = Matrix3.Invert(rotMat);
|
var rotImap = Matrix3.Invert(rotMat);
|
||||||
|
|
||||||
@@ -634,7 +593,7 @@
|
|||||||
var rot = _localRotation.Theta;
|
var rot = _localRotation.Theta;
|
||||||
|
|
||||||
var posMat = Matrix3.CreateTranslation(pos);
|
var posMat = Matrix3.CreateTranslation(pos);
|
||||||
var rotMat = Matrix3.CreateRotation((float)rot);
|
var rotMat = Matrix3.CreateRotation((float) rot);
|
||||||
|
|
||||||
Matrix3.Multiply(ref rotMat, ref posMat, out var transMat);
|
Matrix3.Multiply(ref rotMat, ref posMat, out var transMat);
|
||||||
|
|
||||||
@@ -669,16 +628,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void _recurseSetGridId(GridId gridId)
|
|
||||||
{
|
|
||||||
_gridID = gridId;
|
|
||||||
foreach (var child in Children)
|
|
||||||
{
|
|
||||||
var cast = (TransformComponent) child;
|
|
||||||
cast._recurseSetGridId(gridId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetDebugString()
|
public string GetDebugString()
|
||||||
{
|
{
|
||||||
return $"pos/rot/wpos/wrot: {GridPosition}/{LocalRotation}/{WorldPosition}/{WorldRotation}";
|
return $"pos/rot/wpos/wrot: {GridPosition}/{LocalRotation}/{WorldPosition}/{WorldRotation}";
|
||||||
@@ -700,8 +649,6 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly Vector2 LocalPosition;
|
public readonly Vector2 LocalPosition;
|
||||||
|
|
||||||
public readonly GridId GridID;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Current rotation offset of the entity.
|
/// Current rotation offset of the entity.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -711,14 +658,12 @@
|
|||||||
/// Constructs a new state snapshot of a TransformComponent.
|
/// Constructs a new state snapshot of a TransformComponent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="localPosition">Current position offset of this entity.</param>
|
/// <param name="localPosition">Current position offset of this entity.</param>
|
||||||
/// <param name="gridId">Current grid ID of this entity.</param>
|
|
||||||
/// <param name="rotation">Current direction offset of this entity.</param>
|
/// <param name="rotation">Current direction offset of this entity.</param>
|
||||||
/// <param name="parentId">Current parent transform of this entity.</param>
|
/// <param name="parentId">Current parent transform of this entity.</param>
|
||||||
public TransformComponentState(Vector2 localPosition, GridId gridId, Angle rotation, EntityUid? parentId)
|
public TransformComponentState(Vector2 localPosition, Angle rotation, EntityUid? parentId)
|
||||||
: base(NetIDs.TRANSFORM)
|
: base(NetIDs.TRANSFORM)
|
||||||
{
|
{
|
||||||
LocalPosition = localPosition;
|
LocalPosition = localPosition;
|
||||||
GridID = gridId;
|
|
||||||
Rotation = rotation;
|
Rotation = rotation;
|
||||||
ParentID = parentId;
|
ParentID = parentId;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -278,13 +278,13 @@ namespace Robust.Shared.GameObjects
|
|||||||
return AllocEntity(uid);
|
return AllocEntity(uid);
|
||||||
|
|
||||||
var entity = AllocEntity(prototypeName, uid);
|
var entity = AllocEntity(prototypeName, uid);
|
||||||
entity.Prototype.LoadEntity(entity, ComponentFactory, null);
|
EntityPrototype.LoadEntity(entity.Prototype, entity, ComponentFactory, null);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
private protected void LoadEntity(Entity entity, IEntityLoadContext context)
|
private protected void LoadEntity(Entity entity, IEntityLoadContext context)
|
||||||
{
|
{
|
||||||
entity.Prototype.LoadEntity(entity, ComponentFactory, context);
|
EntityPrototype.LoadEntity(entity.Prototype, entity, ComponentFactory, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private protected static void InitializeAndStartEntity(Entity entity)
|
private protected static void InitializeAndStartEntity(Entity entity)
|
||||||
|
|||||||
@@ -14,5 +14,7 @@ namespace Robust.Shared.Map
|
|||||||
/// <param name="tileRef">A reference to the new tile.</param>
|
/// <param name="tileRef">A reference to the new tile.</param>
|
||||||
/// <param name="oldTile">The old tile that got replaced.</param>
|
/// <param name="oldTile">The old tile that got replaced.</param>
|
||||||
void RaiseOnTileChanged(TileRef tileRef, Tile oldTile);
|
void RaiseOnTileChanged(TileRef tileRef, Tile oldTile);
|
||||||
|
|
||||||
|
IMapGrid CreateGridNoEntity(MapId currentMapID, GridId? gridID = null, ushort chunkSize = 16, float snapSize = 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ namespace Robust.Shared.Map
|
|||||||
_mapCreationTick.Remove(mapID);
|
_mapCreationTick.Remove(mapID);
|
||||||
|
|
||||||
var ent = _mapEntities[mapID];
|
var ent = _mapEntities[mapID];
|
||||||
if(_entityManager.TryGetEntity(ent, out var mapEnt))
|
if (_entityManager.TryGetEntity(ent, out var mapEnt))
|
||||||
mapEnt.Delete();
|
mapEnt.Delete();
|
||||||
|
|
||||||
_mapEntities.Remove(mapID);
|
_mapEntities.Remove(mapID);
|
||||||
@@ -138,13 +138,13 @@ namespace Robust.Shared.Map
|
|||||||
_mapDeletionHistory.Add((_gameTiming.CurTick, mapID));
|
_mapDeletionHistory.Add((_gameTiming.CurTick, mapID));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public MapId CreateMap(MapId? mapID = null, GridId? defaultGridID = null)
|
public MapId CreateMap(MapId? mapID = null, GridId? defaultGridID = null)
|
||||||
{
|
{
|
||||||
if (defaultGridID != null && GridExists(defaultGridID.Value))
|
if (defaultGridID != null && GridExists(defaultGridID.Value))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Grid '{defaultGridID}' already exists.");
|
throw new InvalidOperationException($"Grid '{defaultGridID}' already exists.");
|
||||||
}
|
}
|
||||||
|
|
||||||
MapId actualID;
|
MapId actualID;
|
||||||
if (mapID != null)
|
if (mapID != null)
|
||||||
{
|
{
|
||||||
@@ -190,7 +190,7 @@ namespace Robust.Shared.Map
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var newEnt = (Entity)_entityManager.CreateEntityUninitialized(null, GridCoordinates.Nullspace);
|
var newEnt = (Entity) _entityManager.CreateEntityUninitialized(null, GridCoordinates.Nullspace);
|
||||||
_mapEntities.Add(actualID, newEnt.Uid);
|
_mapEntities.Add(actualID, newEnt.Uid);
|
||||||
|
|
||||||
var mapComp = newEnt.AddComponent<MapComponent>();
|
var mapComp = newEnt.AddComponent<MapComponent>();
|
||||||
@@ -236,7 +236,7 @@ namespace Robust.Shared.Map
|
|||||||
|
|
||||||
public GridId GetDefaultGridId(MapId mapID)
|
public GridId GetDefaultGridId(MapId mapID)
|
||||||
{
|
{
|
||||||
if(_defaultGrids.TryGetValue(mapID, out var gridID))
|
if (_defaultGrids.TryGetValue(mapID, out var gridID))
|
||||||
return gridID;
|
return gridID;
|
||||||
return GridId.Nullspace; //TODO: Hack to make shutdown work
|
return GridId.Nullspace; //TODO: Hack to make shutdown work
|
||||||
}
|
}
|
||||||
@@ -247,6 +247,11 @@ namespace Robust.Shared.Map
|
|||||||
}
|
}
|
||||||
|
|
||||||
public IMapGrid CreateGrid(MapId currentMapID, GridId? gridID = null, ushort chunkSize = 16, float snapSize = 1)
|
public IMapGrid CreateGrid(MapId currentMapID, GridId? gridID = null, ushort chunkSize = 16, float snapSize = 1)
|
||||||
|
{
|
||||||
|
return CreateGridImpl(currentMapID, gridID, chunkSize, snapSize, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IMapGrid CreateGridImpl(MapId currentMapID, GridId? gridID, ushort chunkSize, float snapSize, bool createEntity)
|
||||||
{
|
{
|
||||||
GridId actualID;
|
GridId actualID;
|
||||||
if (gridID != null)
|
if (gridID != null)
|
||||||
@@ -272,7 +277,7 @@ namespace Robust.Shared.Map
|
|||||||
_grids.Add(actualID, grid);
|
_grids.Add(actualID, grid);
|
||||||
Logger.DebugS("map", $"Creating new grid {actualID}");
|
Logger.DebugS("map", $"Creating new grid {actualID}");
|
||||||
|
|
||||||
if(actualID != GridId.Nullspace) // nullspace default grid is not bound to an entity
|
if (actualID != GridId.Nullspace && createEntity) // nullspace default grid is not bound to an entity
|
||||||
{
|
{
|
||||||
// the entity may already exist from map deserialization
|
// the entity may already exist from map deserialization
|
||||||
IMapGridComponent result = null;
|
IMapGridComponent result = null;
|
||||||
@@ -292,7 +297,9 @@ namespace Robust.Shared.Map
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var newEnt = (Entity)_entityManager.CreateEntityUninitialized(null, new MapCoordinates(Vector2.Zero, currentMapID));
|
var newEnt =
|
||||||
|
(Entity) _entityManager.CreateEntityUninitialized(null,
|
||||||
|
new MapCoordinates(Vector2.Zero, currentMapID));
|
||||||
grid.GridEntity = newEnt.Uid;
|
grid.GridEntity = newEnt.Uid;
|
||||||
|
|
||||||
Logger.DebugS("map", $"Binding grid {actualID} to entity {grid.GridEntity}");
|
Logger.DebugS("map", $"Binding grid {actualID} to entity {grid.GridEntity}");
|
||||||
@@ -302,8 +309,11 @@ namespace Robust.Shared.Map
|
|||||||
|
|
||||||
newEnt.Transform.AttachParent(_entityManager.GetEntity(_mapEntities[currentMapID]));
|
newEnt.Transform.AttachParent(_entityManager.GetEntity(_mapEntities[currentMapID]));
|
||||||
|
|
||||||
newEnt.InitializeComponents();
|
if (createEntity)
|
||||||
newEnt.StartAllComponents();
|
{
|
||||||
|
newEnt.InitializeComponents();
|
||||||
|
newEnt.StartAllComponents();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,6 +321,12 @@ namespace Robust.Shared.Map
|
|||||||
return grid;
|
return grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IMapGrid CreateGridNoEntity(MapId currentMapID, GridId? gridID = null, ushort chunkSize = 16,
|
||||||
|
float snapSize = 1)
|
||||||
|
{
|
||||||
|
return CreateGridImpl(currentMapID, gridID, chunkSize, snapSize, false);
|
||||||
|
}
|
||||||
|
|
||||||
public IMapGrid GetGrid(GridId gridID)
|
public IMapGrid GetGrid(GridId gridID)
|
||||||
{
|
{
|
||||||
return _grids[gridID];
|
return _grids[gridID];
|
||||||
@@ -323,6 +339,7 @@ namespace Robust.Shared.Map
|
|||||||
grid = gridinterface;
|
grid = gridinterface;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
grid = null;
|
grid = null;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -359,7 +376,7 @@ namespace Robust.Shared.Map
|
|||||||
public void DeleteGrid(GridId gridID)
|
public void DeleteGrid(GridId gridID)
|
||||||
{
|
{
|
||||||
// nullspace grid cannot be deleted
|
// nullspace grid cannot be deleted
|
||||||
if(gridID == GridId.Nullspace)
|
if (gridID == GridId.Nullspace)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var grid = _grids[gridID];
|
var grid = _grids[gridID];
|
||||||
@@ -370,7 +387,7 @@ namespace Robust.Shared.Map
|
|||||||
if (_defaultGrids.ContainsKey(grid.ParentMapId))
|
if (_defaultGrids.ContainsKey(grid.ParentMapId))
|
||||||
_defaultGrids.Remove(grid.ParentMapId);
|
_defaultGrids.Remove(grid.ParentMapId);
|
||||||
|
|
||||||
if(_entityManager.TryGetEntity(grid.GridEntity, out var gridEnt))
|
if (_entityManager.TryGetEntity(grid.GridEntity, out var gridEnt))
|
||||||
gridEnt.Delete();
|
gridEnt.Delete();
|
||||||
|
|
||||||
OnGridRemoved?.Invoke(gridID);
|
OnGridRemoved?.Invoke(gridID);
|
||||||
|
|||||||
@@ -70,12 +70,14 @@ namespace Robust.Shared.GameObjects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public int PlacementRange { get; protected set; } = DEFAULT_RANGE;
|
public int PlacementRange { get; protected set; } = DEFAULT_RANGE;
|
||||||
|
|
||||||
private const int DEFAULT_RANGE = 200;
|
private const int DEFAULT_RANGE = 200;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set to hold snapping categories that this object has applied to it such as pipe/wire/wallmount
|
/// Set to hold snapping categories that this object has applied to it such as pipe/wire/wallmount
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly HashSet<string> _snapFlags = new HashSet<string>();
|
private readonly HashSet<string> _snapFlags = new HashSet<string>();
|
||||||
|
|
||||||
private bool _snapOverriden = false;
|
private bool _snapOverriden = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -83,6 +85,7 @@ namespace Robust.Shared.GameObjects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public Vector2i PlacementOffset { get; protected set; }
|
public Vector2i PlacementOffset { get; protected set; }
|
||||||
|
|
||||||
private bool _placementOverriden = false;
|
private bool _placementOverriden = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -102,6 +105,7 @@ namespace Robust.Shared.GameObjects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public List<EntityPrototype> Children { get; private set; }
|
public List<EntityPrototype> Children { get; private set; }
|
||||||
|
|
||||||
public bool IsRoot => Parent == null;
|
public bool IsRoot => Parent == null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -122,7 +126,10 @@ namespace Robust.Shared.GameObjects
|
|||||||
private readonly HashSet<Type> ReferenceTypes = new HashSet<Type>();
|
private readonly HashSet<Type> ReferenceTypes = new HashSet<Type>();
|
||||||
|
|
||||||
string CurrentDeserializingComponent;
|
string CurrentDeserializingComponent;
|
||||||
readonly Dictionary<string, Dictionary<(string, Type), object>> FieldCache = new Dictionary<string, Dictionary<(string, Type), object>>();
|
|
||||||
|
readonly Dictionary<string, Dictionary<(string, Type), object>> FieldCache =
|
||||||
|
new Dictionary<string, Dictionary<(string, Type), object>>();
|
||||||
|
|
||||||
readonly Dictionary<string, object> DataCache = new Dictionary<string, object>();
|
readonly Dictionary<string, object> DataCache = new Dictionary<string, object>();
|
||||||
|
|
||||||
public EntityPrototype()
|
public EntityPrototype()
|
||||||
@@ -170,8 +177,10 @@ namespace Robust.Shared.GameObjects
|
|||||||
{
|
{
|
||||||
if (ReferenceTypes.Contains(type))
|
if (ReferenceTypes.Contains(type))
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Duplicate component reference in prototype: '{type}'");
|
throw new InvalidOperationException(
|
||||||
|
$"Duplicate component reference in prototype: '{type}'");
|
||||||
}
|
}
|
||||||
|
|
||||||
ReferenceTypes.Add(type);
|
ReferenceTypes.Add(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -233,6 +242,7 @@ namespace Robust.Shared.GameObjects
|
|||||||
{
|
{
|
||||||
_snapFlags.Add(flag);
|
_snapFlags.Add(flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
_snapOverriden = true;
|
_snapOverriden = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,6 +263,7 @@ namespace Robust.Shared.GameObjects
|
|||||||
{
|
{
|
||||||
Parent.Children = new List<EntityPrototype>();
|
Parent.Children = new List<EntityPrototype>();
|
||||||
}
|
}
|
||||||
|
|
||||||
Parent.Children.Add(this);
|
Parent.Children.Add(this);
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -266,9 +277,11 @@ namespace Robust.Shared.GameObjects
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
PushInheritanceAll();
|
PushInheritanceAll();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,10 +305,12 @@ namespace Robust.Shared.GameObjects
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var target in targetList)
|
foreach (var target in targetList)
|
||||||
{
|
{
|
||||||
PushInheritance(source, target);
|
PushInheritance(source, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
newSources.AddRange(targetList);
|
newSources.AddRange(targetList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,11 +318,13 @@ namespace Robust.Shared.GameObjects
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceTargets.Clear();
|
sourceTargets.Clear();
|
||||||
foreach (var newSource in newSources)
|
foreach (var newSource in newSources)
|
||||||
{
|
{
|
||||||
sourceTargets.Add((newSource, newSource.Children));
|
sourceTargets.Add((newSource, newSource.Children));
|
||||||
}
|
}
|
||||||
|
|
||||||
newSources.Clear();
|
newSources.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -341,9 +358,11 @@ namespace Robust.Shared.GameObjects
|
|||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
target.Components[component.Key] = new YamlMappingNode(component.Value.AsEnumerable());
|
target.Components[component.Key] = new YamlMappingNode(component.Value.AsEnumerable());
|
||||||
}
|
}
|
||||||
next:;
|
|
||||||
|
next: ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy all simple data over.
|
// Copy all simple data over.
|
||||||
@@ -391,40 +410,46 @@ namespace Robust.Shared.GameObjects
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void LoadEntity(Entity entity, IComponentFactory factory, IEntityLoadContext context)
|
internal static void LoadEntity(EntityPrototype prototype, Entity entity, IComponentFactory factory,
|
||||||
|
IEntityLoadContext context)
|
||||||
{
|
{
|
||||||
YamlObjectSerializer.Context defaultContext = null;
|
YamlObjectSerializer.Context defaultContext = null;
|
||||||
if (context == null)
|
if (context == null)
|
||||||
{
|
{
|
||||||
defaultContext = new PrototypeSerializationContext(this);
|
defaultContext = new PrototypeSerializationContext(prototype);
|
||||||
}
|
}
|
||||||
foreach (var (name, data) in Components)
|
|
||||||
|
if (prototype != null)
|
||||||
{
|
{
|
||||||
var compRegistration = factory.GetRegistration(name);
|
foreach (var (name, data) in prototype.Components)
|
||||||
|
{
|
||||||
|
var compRegistration = factory.GetRegistration(name);
|
||||||
|
|
||||||
Component component;
|
Component component;
|
||||||
if (entity.TryGetComponent(compRegistration.Type, out var existingComp))
|
if (entity.TryGetComponent(compRegistration.Type, out var existingComp))
|
||||||
{
|
{
|
||||||
component = (Component) existingComp;
|
component = (Component) existingComp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
component = (Component) factory.GetComponent(name);
|
component = (Component) factory.GetComponent(name);
|
||||||
component.Owner = entity;
|
component.Owner = entity;
|
||||||
entity.AddComponent(component);
|
entity.AddComponent(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectSerializer ser;
|
ObjectSerializer ser;
|
||||||
if (context != null)
|
if (context != null)
|
||||||
{
|
{
|
||||||
ser = context.GetComponentSerializer(name, data);
|
ser = context.GetComponentSerializer(name, data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prototype.CurrentDeserializingComponent = name;
|
||||||
|
ser = YamlObjectSerializer.NewReader(data, defaultContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
component.ExposeData(ser);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
CurrentDeserializingComponent = name;
|
|
||||||
ser = YamlObjectSerializer.NewReader(data, defaultContext);
|
|
||||||
}
|
|
||||||
component.ExposeData(ser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context == null)
|
if (context == null)
|
||||||
@@ -436,12 +461,12 @@ namespace Robust.Shared.GameObjects
|
|||||||
// Components that have been ADDED NEW need to be handled too.
|
// Components that have been ADDED NEW need to be handled too.
|
||||||
foreach (var name in context.GetExtraComponentTypes())
|
foreach (var name in context.GetExtraComponentTypes())
|
||||||
{
|
{
|
||||||
if (Components.ContainsKey(name))
|
if ((prototype != null && prototype.Components.ContainsKey(name)) || name == "Transform" || name == "Metadata")
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var component = (Component)factory.GetComponent(name);
|
var component = (Component) factory.GetComponent(name);
|
||||||
component.Owner = entity;
|
component.Owner = entity;
|
||||||
var ser = context.GetComponentSerializer(name, null);
|
var ser = context.GetComponentSerializer(name, null);
|
||||||
component.ExposeData(ser);
|
component.ExposeData(ser);
|
||||||
@@ -496,6 +521,7 @@ namespace Robust.Shared.GameObjects
|
|||||||
base.SetCachedField<T>(field, value);
|
base.SetCachedField<T>(field, value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!prototype.FieldCache.TryGetValue(prototype.CurrentDeserializingComponent, out var fieldList))
|
if (!prototype.FieldCache.TryGetValue(prototype.CurrentDeserializingComponent, out var fieldList))
|
||||||
{
|
{
|
||||||
fieldList = new Dictionary<(string, Type), object>();
|
fieldList = new Dictionary<(string, Type), object>();
|
||||||
@@ -511,11 +537,12 @@ namespace Robust.Shared.GameObjects
|
|||||||
{
|
{
|
||||||
return base.TryGetCachedField<T>(field, out value);
|
return base.TryGetCachedField<T>(field, out value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prototype.FieldCache.TryGetValue(prototype.CurrentDeserializingComponent, out var dict))
|
if (prototype.FieldCache.TryGetValue(prototype.CurrentDeserializingComponent, out var dict))
|
||||||
{
|
{
|
||||||
if (dict.TryGetValue((field, typeof(T)), out var theValue))
|
if (dict.TryGetValue((field, typeof(T)), out var theValue))
|
||||||
{
|
{
|
||||||
value = (T)theValue;
|
value = (T) theValue;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -531,6 +558,7 @@ namespace Robust.Shared.GameObjects
|
|||||||
base.SetDataCache(field, value);
|
base.SetDataCache(field, value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
prototype.DataCache[field] = value;
|
prototype.DataCache[field] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -540,6 +568,7 @@ namespace Robust.Shared.GameObjects
|
|||||||
{
|
{
|
||||||
return base.TryGetDataCache(field, out value);
|
return base.TryGetDataCache(field, out value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return prototype.DataCache.TryGetValue(field, out value);
|
return prototype.DataCache.TryGetValue(field, out value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ namespace Robust.Shared
|
|||||||
IoCManager.Register<ILocalizationManager, LocalizationManager>();
|
IoCManager.Register<ILocalizationManager, LocalizationManager>();
|
||||||
IoCManager.Register<ILogManager, LogManager>();
|
IoCManager.Register<ILogManager, LogManager>();
|
||||||
IoCManager.Register<IMapManager, MapManager>();
|
IoCManager.Register<IMapManager, MapManager>();
|
||||||
|
IoCManager.Register<IMapManagerInternal, MapManager>();
|
||||||
IoCManager.Register<IModLoader, ModLoader>();
|
IoCManager.Register<IModLoader, ModLoader>();
|
||||||
IoCManager.Register<INetManager, NetManager>();
|
IoCManager.Register<INetManager, NetManager>();
|
||||||
IoCManager.Register<IPhysicsManager, PhysicsManager>();
|
IoCManager.Register<IPhysicsManager, PhysicsManager>();
|
||||||
|
|||||||
@@ -68,16 +68,16 @@ namespace Robust.UnitTesting.Client.GameObjects.Components
|
|||||||
var parentTrans = parent.Transform;
|
var parentTrans = parent.Transform;
|
||||||
var childTrans = child.Transform;
|
var childTrans = child.Transform;
|
||||||
|
|
||||||
var compState = new TransformComponent.TransformComponentState(new Vector2(5, 5), GridB.Index, new Angle(0), GridB.GridEntity);
|
var compState = new TransformComponent.TransformComponentState(new Vector2(5, 5), new Angle(0), GridB.GridEntity);
|
||||||
parentTrans.HandleComponentState(compState, null);
|
parentTrans.HandleComponentState(compState, null);
|
||||||
|
|
||||||
compState = new TransformComponent.TransformComponentState(new Vector2(6, 6), GridB.Index, new Angle(0), GridB.GridEntity);
|
compState = new TransformComponent.TransformComponentState(new Vector2(6, 6), new Angle(0), GridB.GridEntity);
|
||||||
childTrans.HandleComponentState(compState, null);
|
childTrans.HandleComponentState(compState, null);
|
||||||
// World pos should be 6, 6 now.
|
// World pos should be 6, 6 now.
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var oldWpos = childTrans.WorldPosition;
|
var oldWpos = childTrans.WorldPosition;
|
||||||
compState = new TransformComponent.TransformComponentState(new Vector2(1, 1), GridB.Index, new Angle(0), parent.Uid);
|
compState = new TransformComponent.TransformComponentState(new Vector2(1, 1), new Angle(0), parent.Uid);
|
||||||
childTrans.HandleComponentState(compState, null);
|
childTrans.HandleComponentState(compState, null);
|
||||||
var newWpos = childTrans.WorldPosition;
|
var newWpos = childTrans.WorldPosition;
|
||||||
|
|
||||||
@@ -105,11 +105,11 @@ namespace Robust.UnitTesting.Client.GameObjects.Components
|
|||||||
var node2Trans = node2.Transform;
|
var node2Trans = node2.Transform;
|
||||||
var node3Trans = node3.Transform;
|
var node3Trans = node3.Transform;
|
||||||
|
|
||||||
var compState = new TransformComponent.TransformComponentState(new Vector2(6, 6), GridB.Index, Angle.FromDegrees(135), GridB.GridEntity);
|
var compState = new TransformComponent.TransformComponentState(new Vector2(6, 6), Angle.FromDegrees(135), GridB.GridEntity);
|
||||||
node1Trans.HandleComponentState(compState, null);
|
node1Trans.HandleComponentState(compState, null);
|
||||||
compState = new TransformComponent.TransformComponentState(new Vector2(1, 1), GridB.Index, Angle.FromDegrees(45), node1.Uid);
|
compState = new TransformComponent.TransformComponentState(new Vector2(1, 1), Angle.FromDegrees(45), node1.Uid);
|
||||||
node2Trans.HandleComponentState(compState, null);
|
node2Trans.HandleComponentState(compState, null);
|
||||||
compState = new TransformComponent.TransformComponentState(new Vector2(0, 0), GridB.Index, Angle.FromDegrees(45), node2.Uid);
|
compState = new TransformComponent.TransformComponentState(new Vector2(0, 0), Angle.FromDegrees(45), node2.Uid);
|
||||||
node3Trans.HandleComponentState(compState, null);
|
node3Trans.HandleComponentState(compState, null);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|||||||
+2
-1
@@ -37,10 +37,11 @@ Contains data for all the grids. The section is an ordered sequence. Each sequen
|
|||||||
* `tilesize`: An integer representing the length of one side of a grid tile, in world units (meters).
|
* `tilesize`: An integer representing the length of one side of a grid tile, in world units (meters).
|
||||||
* `chunksize`: An integer representing the tile dimensions of a chunk in this grid. Basically, when chunksize is `x`, a single chunk contains a square region of `x` by `x` tiles.
|
* `chunksize`: An integer representing the tile dimensions of a chunk in this grid. Basically, when chunksize is `x`, a single chunk contains a square region of `x` by `x` tiles.
|
||||||
* `snapsize`: A float representing snap grid size.
|
* `snapsize`: A float representing snap grid size.
|
||||||
* `worldpos`: Position in the world of this grid.
|
|
||||||
|
|
||||||
* `chunks`: A sequence containing the actual chunk data for this grid. See below.
|
* `chunks`: A sequence containing the actual chunk data for this grid. See below.
|
||||||
|
|
||||||
|
Grids also have their **grid entity** serialized like regular entities.
|
||||||
|
|
||||||
### The `entities` Section
|
### The `entities` Section
|
||||||
|
|
||||||
Contains data for all entities on the map. Just like grids these are stored in an indexed list, and an entity declaration is pretty much just like a prototype.
|
Contains data for all entities on the map. Just like grids these are stored in an indexed list, and an entity declaration is pretty much just like a prototype.
|
||||||
|
|||||||
Reference in New Issue
Block a user