Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor map loading & saving #5572

Open
wants to merge 25 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,30 @@ END TEMPLATE-->

### Breaking changes

*None yet*
* `ITileDefinitionManager.AssignAlias` and general tile alias functionality has been removed. `TileAliasPrototype` still exist, but are only used during entity deserialization.
* `IMapManager.AddUninitializedMap` has been removed. Use the map-init options on `CreateMap()` instead.
* Re-using a MapId will now log a warning. This may cause some integration tests to fail if they are configured to fail
when warnings are logged.
* The minimum supported map format / version has been increased from 2 to 3.
* The server-side `MapLoaderSystem` and associated classes & structs has been moved to `Robust.Shared`, and has been significantly modified.
* The`TryLoad` and `Save` methods have been replaced with grid, map, generic entity variants. I.e, `SaveGrid`, `SaveMap`, and `SaveEntities`.
* Most of the serialization logic and methods have been moved out of `MapLoaderSystem` and into new `EntitySerializer`
and `EntityDeserializer` classes, which also replace the old `MapSerializationContext`.
* The `MapLoadOptions` class has been split into `MapLoadOptions`, `SerializationOptions`, and `DeserializationOptions`
structs.

### New features

*None yet*
* The current map format/version has increased from 6 to 7 and now contains more information to try support serialization of maps with null-space entities and full game saves.
* `IEntitySystemManager` now provides access to the system `IDependencyCollection`.

### Bugfixes

*None yet*

### Other

*None yet*
* `MapChangedEvent` has been marked as obsolete, and should be replaced with `MapCreatedEvent` and `MapRemovedEvent.

### Internal

Expand Down
2 changes: 1 addition & 1 deletion Robust.Client/GameObjects/EntitySystems/MapSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ protected override MapId GetNextMapId()
{
// Client-side map entities use negative map Ids to avoid conflict with server-side maps.
var id = new MapId(--LastMapId);
while (MapManager.MapExists(id))
while (MapExists(id) || UsedIds.Contains(id))
{
id = new MapId(--LastMapId);
}
Expand Down
95 changes: 43 additions & 52 deletions Robust.Server/Console/Commands/MapCommands.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
using System.Linq;
using System.Numerics;
using Robust.Server.GameObjects;
using Robust.Server.Maps;
using Robust.Shared.Console;
using Robust.Shared.ContentPack;
using Robust.Shared.EntitySerialization;
using Robust.Shared.EntitySerialization.Systems;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Utility;

namespace Robust.Server.Console.Commands
{
Expand Down Expand Up @@ -42,7 +43,7 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args)
return;
}

_ent.System<MapLoaderSystem>().Save(uid, args[1]);
_ent.System<MapLoaderSystem>().TrySaveGrid(uid, new ResPath(args[1]));
shell.WriteLine("Save successful. Look in the user data directory.");
}

Expand All @@ -63,7 +64,6 @@ public override CompletionResult GetCompletion(IConsoleShell shell, string[] arg
public sealed class LoadGridCommand : LocalizedCommands
{
[Dependency] private readonly IEntitySystemManager _system = default!;
[Dependency] private readonly IMapManager _map = default!;
[Dependency] private readonly IResourceManager _resource = default!;

public override string Command => "loadgrid";
Expand Down Expand Up @@ -91,13 +91,14 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args)
return;
}

if (!_map.MapExists(mapId))
var sys = _system.GetEntitySystem<SharedMapSystem>();
if (!sys.MapExists(mapId))
{
shell.WriteError("Target map does not exist.");
return;
}

var loadOptions = new MapLoadOptions();
Vector2 offset = default;
if (args.Length >= 4)
{
if (!float.TryParse(args[2], out var x))
Expand All @@ -112,9 +113,10 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args)
return;
}

loadOptions.Offset = new Vector2(x, y);
offset = new Vector2(x, y);
}

Angle rot = default;
if (args.Length >= 5)
{
if (!float.TryParse(args[4], out var rotation))
Expand All @@ -123,9 +125,10 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args)
return;
}

loadOptions.Rotation = Angle.FromDegrees(rotation);
rot = Angle.FromDegrees(rotation);
}

var opts = DeserializationOptions.Default;
if (args.Length >= 6)
{
if (!bool.TryParse(args[5], out var storeUids))
Expand All @@ -134,10 +137,11 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args)
return;
}

loadOptions.StoreMapUids = storeUids;
opts.StoreYamlUids = storeUids;
}

_system.GetEntitySystem<MapLoaderSystem>().Load(mapId, args[1], loadOptions);
var path = new ResPath(args[1]);
_system.GetEntitySystem<MapLoaderSystem>().TryLoadGrid(mapId, path, out _, opts, offset, rot);
}

public override CompletionResult GetCompletion(IConsoleShell shell, string[] args)
Expand All @@ -149,7 +153,6 @@ public override CompletionResult GetCompletion(IConsoleShell shell, string[] arg
public sealed class SaveMap : LocalizedCommands
{
[Dependency] private readonly IEntitySystemManager _system = default!;
[Dependency] private readonly IMapManager _map = default!;
[Dependency] private readonly IResourceManager _resource = default!;

public override string Command => "savemap";
Expand Down Expand Up @@ -189,29 +192,29 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args)
if (mapId == MapId.Nullspace)
return;

if (!_map.MapExists(mapId))
var sys = _system.GetEntitySystem<SharedMapSystem>();
if (!sys.MapExists(mapId))
{
shell.WriteError(Loc.GetString("cmd-savemap-not-exist"));
return;
}

if (_map.IsMapInitialized(mapId) &&
if (sys.IsInitialized(mapId) &&
( args.Length < 3 || !bool.TryParse(args[2], out var force) || !force))
{
shell.WriteError(Loc.GetString("cmd-savemap-init-warning"));
return;
}

shell.WriteLine(Loc.GetString("cmd-savemap-attempt", ("mapId", mapId), ("path", args[1])));
_system.GetEntitySystem<MapLoaderSystem>().SaveMap(mapId, args[1]);
_system.GetEntitySystem<MapLoaderSystem>().TrySaveMap(mapId, new ResPath(args[1]));
shell.WriteLine(Loc.GetString("cmd-savemap-success"));
}
}

public sealed class LoadMap : LocalizedCommands
{
[Dependency] private readonly IEntitySystemManager _system = default!;
[Dependency] private readonly IMapManager _map = default!;
[Dependency] private readonly IResourceManager _resource = default!;

public override string Command => "loadmap";
Expand Down Expand Up @@ -267,61 +270,49 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args)
return;
}

if (_map.MapExists(mapId))
var sys = _system.GetEntitySystem<SharedMapSystem>();
if (sys.MapExists(mapId))
{
shell.WriteError(Loc.GetString("cmd-loadmap-exists", ("mapId", mapId)));
return;
}

var loadOptions = new MapLoadOptions();

float x = 0, y = 0;
if (args.Length >= 3)
float x = 0;
if (args.Length >= 3 && !float.TryParse(args[2], out x))
{
if (!float.TryParse(args[2], out x))
{
shell.WriteError(Loc.GetString("cmd-parse-failure-float", ("arg", args[2])));
return;
}
shell.WriteError(Loc.GetString("cmd-parse-failure-float", ("arg", args[2])));
return;
}

if (args.Length >= 4)
float y = 0;
if (args.Length >= 4 && !float.TryParse(args[3], out y))
{

if (!float.TryParse(args[3], out y))
{
shell.WriteError(Loc.GetString("cmd-parse-failure-float", ("arg", args[3])));
return;
}
shell.WriteError(Loc.GetString("cmd-parse-failure-float", ("arg", args[3])));
return;
}
var offset = new Vector2(x, y);

loadOptions.Offset = new Vector2(x, y);

if (args.Length >= 5)
float rotation = 0;
if (args.Length >= 5 && !float.TryParse(args[4], out rotation))
{
if (!float.TryParse(args[4], out var rotation))
{
shell.WriteError(Loc.GetString("cmd-parse-failure-float", ("arg", args[4])));
return;
}

loadOptions.Rotation = new Angle(rotation);
shell.WriteError(Loc.GetString("cmd-parse-failure-float", ("arg", args[4])));
return;
}
var rot = new Angle(rotation);

if (args.Length >= 6)
bool storeUids = false;
if (args.Length >= 6 && !bool.TryParse(args[5], out storeUids))
{
if (!bool.TryParse(args[5], out var storeUids))
{
shell.WriteError(Loc.GetString("cmd-parse-failure-bool", ("arg", args[5])));
return;
}

loadOptions.StoreMapUids = storeUids;
shell.WriteError(Loc.GetString("cmd-parse-failure-bool", ("arg", args[5])));
return;
}

_system.GetEntitySystem<MapLoaderSystem>().TryLoad(mapId, args[1], out _, loadOptions);
var opts = new DeserializationOptions {StoreYamlUids = storeUids};

var path = new ResPath(args[1]);
_system.GetEntitySystem<MapLoaderSystem>().TryLoadMapWithId(mapId, path, out _, out _, opts, offset, rot);

if (_map.MapExists(mapId))
if (sys.MapExists(mapId))
shell.WriteLine(Loc.GetString("cmd-loadmap-success", ("mapId", mapId), ("path", args[1])));
else
shell.WriteLine(Loc.GetString("cmd-loadmap-error", ("path", args[1])));
Expand Down
Loading
Loading