Allow maps to be saved (#3055)

* Allow maps to be saved

* I hate myself

* fix?

* Fix maybe?
This commit is contained in:
metalgearsloth
2022-07-25 15:30:20 +10:00
committed by GitHub
parent fc10adfb03
commit db3f3e5b32
13 changed files with 110 additions and 42 deletions

View File

@@ -16,11 +16,10 @@ namespace Robust.Client.Physics
SimulateWorld(frameTime, _gameTiming.InPrediction);
}
protected override void HandleMapCreated(MapChangedEvent eventArgs)
protected override void OnMapAdded(ref MapChangedEvent eventArgs)
{
if (eventArgs.Map == MapId.Nullspace) return;
var mapUid = MapManager.GetMapEntityId(eventArgs.Map);
EntityManager.AddComponent<PhysicsMapComponent>(mapUid);
EnsureComp<PhysicsMapComponent>(MapManager.GetMapEntityId(eventArgs.Map));
}
}
}

View File

@@ -37,11 +37,10 @@ namespace Robust.Server.GameObjects
collideComp.BodyType = BodyType.Static;
}
protected override void HandleMapCreated(MapChangedEvent eventArgs)
protected override void OnMapAdded(ref MapChangedEvent eventArgs)
{
if (eventArgs.Map == MapId.Nullspace) return;
var mapUid = MapManager.GetMapEntityIdOrThrow(eventArgs.Map);
EntityManager.AddComponent<PhysicsMapComponent>(mapUid);
EnsureComp<PhysicsMapComponent>(MapManager.GetMapEntityId(eventArgs.Map));
}
/// <inheritdoc />

View File

@@ -1,4 +1,5 @@
using Robust.Shared.GameObjects;
using Robust.Shared.Prototypes;
namespace Robust.Server.GameObjects
{
@@ -11,6 +12,8 @@ namespace Robust.Server.GameObjects
void FinishEntityLoad(EntityUid entity, IEntityLoadContext? context = null);
void FinishEntityLoad(EntityUid entity, EntityPrototype? prototype, IEntityLoadContext? context = null);
void FinishEntityInitialization(EntityUid entity, MetaDataComponent? meta = null);
void FinishEntityStartup(EntityUid entity);

View File

@@ -52,6 +52,11 @@ namespace Robust.Server.GameObjects
LoadEntity(entity, context);
}
void IServerEntityManagerInternal.FinishEntityLoad(EntityUid entity, EntityPrototype? prototype, IEntityLoadContext? context)
{
LoadEntity(entity, context, prototype);
}
void IServerEntityManagerInternal.FinishEntityInitialization(EntityUid entity, MetaDataComponent? meta)
{
InitializeEntity(entity, meta);

View File

@@ -152,6 +152,8 @@ namespace Robust.Server.Maps
{
Logger.InfoS("map", $"Saving map {mapId} to {yamlPath}");
var context = new MapContext(_mapManager, _tileDefinitionManager, _serverEntityManager, _prototypeManager, _serializationManager, _componentFactory);
context.MapId = mapId;
foreach (var grid in _mapManager.GetAllMapGrids(mapId))
{
context.RegisterGrid(grid);
@@ -247,6 +249,11 @@ namespace Robust.Server.Maps
private readonly IComponentFactory _componentFactory;
private readonly MapLoadOptions? _loadOptions;
/// <summary>
/// If we're using savemap and not savebp then save everything on map.
/// </summary>
internal MapId? MapId { get; set; }
private readonly Dictionary<GridId, int> GridIDMap = new();
public readonly List<MapGrid> Grids = new();
private readonly List<GridId> _readGridIndices = new();
@@ -263,6 +270,7 @@ namespace Robust.Server.Maps
private readonly MappingDataNode RootNode;
public readonly MapId TargetMap;
private EntityUid? TargetMapUid;
private Dictionary<string, MappingDataNode>? CurrentReadingEntityComponents;
@@ -602,12 +610,22 @@ namespace Robust.Server.Maps
private void AttachMapEntities()
{
var mapEntity = _mapManager.GetMapEntityIdOrThrow(TargetMap);
EntityUid mapEntity;
if (TargetMapUid != null)
{
mapEntity = TargetMapUid.Value;
_mapManager.SetMapEntity(TargetMap, TargetMapUid.Value);
}
else
{
mapEntity = _mapManager.GetMapEntityIdOrThrow(TargetMap);
}
foreach (var grid in Grids)
{
var transform = _xformQuery!.Value.GetComponent(grid.GridEntityId);
if (transform.Parent != null)
if (transform.ParentUid.IsValid())
continue;
var mapOffset = transform.LocalPosition;
@@ -619,6 +637,7 @@ namespace Robust.Server.Maps
private void FixMapEntities()
{
var pvs = EntitySystem.Get<PVSSystem>();
foreach (var grid in Grids)
{
pvs?.EntityPVSCollection.UpdateIndex(grid.GridEntityId);
@@ -730,6 +749,9 @@ namespace Robust.Server.Maps
private void FinishEntitiesLoad()
{
var mapQuery = _serverEntityManager.GetEntityQuery<MapComponent>();
var metaQuery = _serverEntityManager.GetEntityQuery<MetaDataComponent>();
foreach (var (entity, data) in _entitiesToDeserialize)
{
CurrentReadingEntityComponents = new Dictionary<string, MappingDataNode>();
@@ -739,11 +761,18 @@ namespace Robust.Server.Maps
{
var datanode = compData.Copy();
datanode.Remove("type");
CurrentReadingEntityComponents[((ValueDataNode)compData["type"]).Value] = datanode;
var value = ((ValueDataNode)compData["type"]).Value;
CurrentReadingEntityComponents[value] = datanode;
}
}
_serverEntityManager.FinishEntityLoad(entity, this);
_serverEntityManager.FinishEntityLoad(entity, metaQuery.GetComponent(entity).EntityPrototype, this);
if (mapQuery.HasComponent(entity))
{
DebugTools.Assert(TargetMapUid == null);
TargetMapUid = entity;
}
}
}
@@ -870,7 +899,7 @@ namespace Robust.Server.Maps
foreach (var entity in _serverEntityManager.GetEntities())
{
var currentTransform = transformCompQuery.GetComponent(entity);
if (!GridIDMap.ContainsKey(currentTransform.GridID)) continue;
if ((MapId != null && currentTransform.MapID != MapId) || (MapId == null && !GridIDMap.ContainsKey(currentTransform.GridID))) continue;
var currentEntity = entity;

View File

@@ -469,7 +469,7 @@ namespace Robust.Shared.GameObjects
var entity = AllocEntity(prototypeName, out var metadata, uid);
try
{
EntityPrototype.LoadEntity(metadata.EntityPrototype, entity, ComponentFactory, PrototypeManager, this, _serManager, null);
EntityPrototype.LoadEntity(metadata.EntityPrototype, entity, ComponentFactory, this, _serManager, null);
return entity;
}
catch (Exception e)
@@ -483,7 +483,12 @@ namespace Robust.Shared.GameObjects
private protected void LoadEntity(EntityUid entity, IEntityLoadContext? context)
{
EntityPrototype.LoadEntity(GetComponent<MetaDataComponent>(entity).EntityPrototype, entity, ComponentFactory, PrototypeManager, this, _serManager, context);
EntityPrototype.LoadEntity(GetComponent<MetaDataComponent>(entity).EntityPrototype, entity, ComponentFactory, this, _serManager, context);
}
private protected void LoadEntity(EntityUid entity, IEntityLoadContext? context, EntityPrototype? prototype)
{
EntityPrototype.LoadEntity(prototype, entity, ComponentFactory, this, _serManager, context);
}
private void InitializeAndStartEntity(EntityUid entity, MapId mapId)

View File

@@ -16,7 +16,7 @@ namespace Robust.Shared.GameObjects
{
base.Initialize();
SubscribeLocalEvent<MapComponent, ComponentInit>(OnMapAdded);
SubscribeLocalEvent<MapComponent, ComponentInit>(OnMapInit);
SubscribeLocalEvent<MapComponent, ComponentShutdown>(OnMapRemoved);
SubscribeLocalEvent<MapGridComponent, ComponentAdd>(OnGridAdd);
@@ -25,46 +25,42 @@ namespace Robust.Shared.GameObjects
SubscribeLocalEvent<MapGridComponent, ComponentShutdown>(OnGridRemove);
}
private void OnMapAdded(EntityUid uid, MapComponent component, ComponentInit args)
private void OnMapInit(EntityUid uid, MapComponent component, ComponentInit args)
{
var msg = new MapChangedEvent(component.WorldMap, true);
EntityManager.EventBus.RaiseLocalEvent(uid, msg, true);
RaiseLocalEvent(uid, msg, true);
}
private void OnMapRemoved(EntityUid uid, MapComponent component, ComponentShutdown args)
{
var msg = new MapChangedEvent(component.WorldMap, false);
EntityManager.EventBus.RaiseLocalEvent(uid, msg, true);
RaiseLocalEvent(uid, msg, true);
}
private void OnGridAdd(EntityUid uid, MapGridComponent component, ComponentAdd args)
{
// GridID is not set yet so we don't include it.
var msg = new GridAddEvent(uid);
EntityManager.EventBus.RaiseLocalEvent(uid, msg, true);
RaiseLocalEvent(uid, msg, true);
}
private void OnGridInit(EntityUid uid, MapGridComponent component, ComponentInit args)
{
#pragma warning disable CS0618
var msg = new GridInitializeEvent(uid, component.GridIndex);
#pragma warning restore CS0618
EntityManager.EventBus.RaiseLocalEvent(uid, msg, true);
RaiseLocalEvent(uid, msg, true);
}
private void OnGridStartup(EntityUid uid, MapGridComponent component, ComponentStartup args)
{
#pragma warning disable CS0618
var msg = new GridStartupEvent(uid, component.GridIndex);
#pragma warning restore CS0618
EntityManager.EventBus.RaiseLocalEvent(uid, msg, true);
RaiseLocalEvent(uid, msg, true);
}
private void OnGridRemove(EntityUid uid, MapGridComponent component, ComponentShutdown args)
{
#pragma warning disable CS0618
EntityManager.EventBus.RaiseLocalEvent(uid, new GridRemovalEvent(uid, component.GridIndex), true);
#pragma warning restore CS0618
RaiseLocalEvent(uid, new GridRemovalEvent(uid, component.GridIndex), true);
MapManager.OnComponentRemoved(component);
}
}

View File

@@ -63,7 +63,7 @@ namespace Robust.Shared.GameObjects
SubscribeLocalEvent<MapChangedEvent>(ev =>
{
if (ev.Created)
HandleMapCreated(ev);
OnMapAdded(ref ev);
});
SubscribeLocalEvent<GridInitializeEvent>(HandleGridInit);
@@ -252,7 +252,7 @@ namespace Robust.Shared.GameObjects
bodyQuery.TryGetComponent(child, out var childBody);
RecursiveMapUpdate(childXform, childBody, newMapId, newBroadphase, newMap, oldMap, oldMoveBuffer, bodyQuery, xformQuery, fixturesQuery, jointQuery, broadQuery);
}
}
}
@@ -273,7 +273,7 @@ namespace Robust.Shared.GameObjects
configManager.UnsubValueChanged(CVars.AutoClearForces, OnAutoClearChange);
}
protected abstract void HandleMapCreated(MapChangedEvent eventArgs);
protected abstract void OnMapAdded(ref MapChangedEvent eventArgs);
private void OnWake(ref PhysicsWakeEvent @event)
{

View File

@@ -219,8 +219,10 @@ internal partial class MapManager
public IEnumerable<IMapGrid> GetAllMapGrids(MapId mapId)
{
var xformQuery = EntityManager.GetEntityQuery<TransformComponent>();
return EntityManager.EntityQuery<IMapGridComponent>(true)
.Where(c => c.Grid.ParentMapId == mapId)
.Where(c => xformQuery.GetComponent(c.Grid.GridEntityId).MapID == mapId)
.Select(c => c.Grid);
}

View File

@@ -1,6 +1,5 @@
using System.Collections.Generic;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Utility;
@@ -11,9 +10,14 @@ internal partial class MapManager
{
// TODO: Move IMapManager stuff to the system
private Dictionary<MapId, B2DynamicTree<MapGrid>> _gridTrees = new();
private Dictionary<MapId, HashSet<IMapGrid>> _movedGrids = new();
// Gets the grids that have moved this tick until broadphase has run.
/// <summary>
/// Gets the grids that have moved this tick until broadphase has run.
/// </summary>
/// <param name="mapId"></param>
/// <returns></returns>
public HashSet<IMapGrid> GetMovedGrids(MapId mapId)
{
return _movedGrids[mapId];

View File

@@ -56,7 +56,9 @@ internal partial class MapManager
public void TrueDeleteMap(MapId mapId)
{
// grids are cached because Delete modifies collection
foreach (var grid in GetAllMapGrids(mapId).ToList())
var grids = GetAllMapGrids(mapId).ToList();
foreach (var grid in grids)
{
DeleteGrid(grid.Index);
}
@@ -123,9 +125,20 @@ internal partial class MapManager
}
}
MapComponent? mapComp;
// If this is being done as part of maploader then we want to copy the preinit state across mainly.
bool preInit = false;
bool paused = false;
// remove existing graph
if (_mapEntities.TryGetValue(mapId, out var oldEntId))
{
if (EntityManager.TryGetComponent(oldEntId, out mapComp))
{
preInit = mapComp.MapPreInit;
paused = mapComp.MapPaused;
}
//Note: EntityUid.Invalid gets passed in here
//Note: This prevents setting a subgraph as the root, since the subgraph will be deleted
EntityManager.DeleteEntity(oldEntId);
@@ -133,11 +146,15 @@ internal partial class MapManager
else
_mapEntities.Add(mapId, EntityUid.Invalid);
var raiseEvent = false;
// re-use or add map component
if (!EntityManager.TryGetComponent(newMapEntity, out MapComponent? mapComp))
if (!EntityManager.TryGetComponent(newMapEntity, out mapComp))
mapComp = EntityManager.AddComponent<MapComponent>(newMapEntity);
else
{
raiseEvent = true;
if (mapComp.WorldMap != mapId)
{
Logger.WarningS("map",
@@ -148,8 +165,19 @@ internal partial class MapManager
Logger.DebugS("map", $"Setting map {mapId} entity to {newMapEntity}");
// set as new map entity
mapComp.MapPreInit = preInit;
mapComp.MapPaused = paused;
mapComp.WorldMap = mapId;
_mapEntities[mapId] = newMapEntity;
// Yeah this sucks but I just want to save maps for now, deal.
if (raiseEvent)
{
OnMapCreatedGridTree(new MapEventArgs(mapId));
var ev = new MapChangedEvent(mapId, true);
EntityManager.EventBus.RaiseLocalEvent(newMapEntity, ev, true);
}
}
/// <inheritdoc />

View File

@@ -38,9 +38,10 @@ namespace Robust.Shared.Physics
* Hence we need to check which broadphases it does intersect and checkar for colliding bodies.
*/
// We keep 2 move buffers as we need to handle the broadphase moving behavior first.
// This is because we'll chuck anything the broadphase moves over onto the movebuffer so contacts can be generated.
private Dictionary<MapId, Dictionary<FixtureProxy, Box2>> _moveBuffer = new();
/// <summary>
/// Keep a buffer of everything that moved in a tick. This will be used to check for physics contacts.
/// </summary>
private readonly Dictionary<MapId, Dictionary<FixtureProxy, Box2>> _moveBuffer = new();
// Caching for FindNewContacts
private Dictionary<FixtureProxy, HashSet<FixtureProxy>> _pairBuffer = new(64);
@@ -66,7 +67,7 @@ namespace Robust.Shared.Physics
UpdatesAfter.Add(typeof(SharedTransformSystem));
SubscribeLocalEvent<BroadphaseComponent, ComponentAdd>(OnBroadphaseAdd);
SubscribeLocalEvent<GridAddEvent>(OnGridAdd);
SubscribeLocalEvent<GridInitializeEvent>(OnGridAdd);
SubscribeLocalEvent<CollisionChangeEvent>(OnPhysicsUpdate);
@@ -866,9 +867,9 @@ namespace Robust.Shared.Physics
_moveBuffer.Remove(e.Map);
}
private void OnGridAdd(GridAddEvent ev)
private void OnGridAdd(GridInitializeEvent ev)
{
EntityManager.EnsureComponent<BroadphaseComponent>(ev.EntityUid);
EnsureComp<BroadphaseComponent>(ev.EntityUid);
}
private void OnBroadphaseAdd(EntityUid uid, BroadphaseComponent component, ComponentAdd args)

View File

@@ -247,7 +247,6 @@ namespace Robust.Shared.Prototypes
EntityPrototype? prototype,
EntityUid entity,
IComponentFactory factory,
IPrototypeManager prototypeManager,
IEntityManager entityManager,
ISerializationManager serManager,
IEntityLoadContext? context) //yeah officer this method right here
@@ -260,8 +259,6 @@ namespace Robust.Shared.Prototypes
if (prototype != null)
{
prototypeManager.TryGetMapping(typeof(EntityPrototype), prototype.ID, out var prototypeData);
foreach (var (name, entry) in prototype.Components)
{
var fullData = entry.Mapping;