Skip to content

Commit

Permalink
Add mapping editor (#23427)
Browse files Browse the repository at this point in the history
* Add mapping editor (DeltaV-Station#757)

* Remove mapping actions, never again

* Cleanup actions system

* Jarvis, remove all references to CM14

* Fix InventoryUIController crashing when an InventoryGui is not found

* Rename mapping1 to mapping

* Clean up context calls

* Add doc comments

* Add delegate for hiding decals in the mapping screen

* Jarvis mission failed

* a

* Add test

* Fix not flushing save stream in mapping manager

* change

* Fix verbs

* fixes

* localise

---------

Co-authored-by: DrSmugleaf <[email protected]>
Co-authored-by: metalgearsloth <[email protected]>
Co-authored-by: metalgearsloth <[email protected]>
Co-authored-by: Pieter-Jan Briers <[email protected]>
  • Loading branch information
5 people authored and VMSolidus committed Jan 18, 2025
1 parent fbc9cc7 commit cb6a090
Show file tree
Hide file tree
Showing 36 changed files with 2,023 additions and 45 deletions.
2 changes: 1 addition & 1 deletion Content.Client/Actions/ActionsSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ public void LoadActionAssignments(string path, bool userData)
continue;

var action = _serialization.Read<BaseActionComponent>(actionNode, notNullableOverride: true);
var actionId = Spawn(null);
var actionId = Spawn();
AddComp(actionId, action);
AddActionDirect(user, actionId);

Expand Down
24 changes: 0 additions & 24 deletions Content.Client/Commands/ActionsCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,27 +84,3 @@ private static async void LoadActs()
reader.Close();
}
}

[AnyCommand]
public sealed class LoadMappingActionsCommand : LocalizedCommands
{
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;

public const string CommandName = "loadmapacts";

public override string Command => CommandName;

public override string Help => LocalizationManager.GetString($"cmd-{Command}-help", ("command", Command));

public override void Execute(IConsoleShell shell, string argStr, string[] args)
{
try
{
_entitySystemManager.GetEntitySystem<MappingSystem>().LoadMappingActions();
}
catch
{
shell.WriteError(LocalizationManager.GetString($"cmd-{Command}-error"));
}
}
}
7 changes: 5 additions & 2 deletions Content.Client/Commands/MappingClientSideSetupCommand.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using Content.Client.Mapping;
using Content.Client.Markers;
using JetBrains.Annotations;
using Robust.Client.Graphics;
using Robust.Client.State;
using Robust.Shared.Console;

namespace Content.Client.Commands;
Expand All @@ -10,6 +12,7 @@ internal sealed class MappingClientSideSetupCommand : LocalizedCommands
{
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
[Dependency] private readonly ILightManager _lightManager = default!;
[Dependency] private readonly IStateManager _stateManager = default!;

public override string Command => "mappingclientsidesetup";

Expand All @@ -21,8 +24,8 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args)
{
_entitySystemManager.GetEntitySystem<MarkerSystem>().MarkersVisible = true;
_lightManager.Enabled = false;
shell.ExecuteCommand(ShowSubFloorForever.CommandName);
shell.ExecuteCommand(LoadMappingActionsCommand.CommandName);
shell.ExecuteCommand("showsubfloorforever");
_stateManager.RequestStateChange<MappingState>();
}
}
}
Expand Down
38 changes: 36 additions & 2 deletions Content.Client/ContextMenu/UI/ContextMenuUIController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Threading;
using Content.Client.CombatMode;
using Content.Client.Gameplay;
using Content.Client.Mapping;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controllers;
using Timer = Robust.Shared.Timing.Timer;
Expand All @@ -16,7 +17,7 @@ namespace Content.Client.ContextMenu.UI
/// <remarks>
/// This largely involves setting up timers to open and close sub-menus when hovering over other menu elements.
/// </remarks>
public sealed class ContextMenuUIController : UIController, IOnStateEntered<GameplayState>, IOnStateExited<GameplayState>, IOnSystemChanged<CombatModeSystem>
public sealed class ContextMenuUIController : UIController, IOnStateEntered<GameplayState>, IOnStateExited<GameplayState>, IOnSystemChanged<CombatModeSystem>, IOnStateEntered<MappingState>, IOnStateExited<MappingState>
{
public static readonly TimeSpan HoverDelay = TimeSpan.FromSeconds(0.2);

Expand All @@ -42,18 +43,51 @@ public sealed class ContextMenuUIController : UIController, IOnStateEntered<Game
public Action<ContextMenuElement>? OnSubMenuOpened;
public Action<ContextMenuElement, GUIBoundKeyEventArgs>? OnContextKeyEvent;

private bool _setup;

public void OnStateEntered(GameplayState state)
{
Setup();
}

public void OnStateExited(GameplayState state)
{
Shutdown();
}

public void OnStateEntered(MappingState state)
{
Setup();
}

public void OnStateExited(MappingState state)
{
Shutdown();
}

public void Setup()
{
if (_setup)
return;

_setup = true;

RootMenu = new(this, null);
RootMenu.OnPopupHide += Close;
Menus.Push(RootMenu);
}

public void OnStateExited(GameplayState state)
public void Shutdown()
{
if (!_setup)
return;

_setup = false;

Close();
RootMenu.OnPopupHide -= Close;
RootMenu.Dispose();
RootMenu = default!;
}

/// <summary>
Expand Down
6 changes: 4 additions & 2 deletions Content.Client/Decals/Overlays/DecalPlacementOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Robust.Client.Input;
using Robust.Shared.Enums;
using Robust.Shared.Map;
using Robust.Shared.Prototypes;

namespace Content.Client.Decals.Overlays;

Expand All @@ -16,14 +17,15 @@ public sealed class DecalPlacementOverlay : Overlay
private readonly SharedTransformSystem _transform;
private readonly SpriteSystem _sprite;

public override OverlaySpace Space => OverlaySpace.WorldSpace;
public override OverlaySpace Space => OverlaySpace.WorldSpaceEntities;

public DecalPlacementOverlay(DecalPlacementSystem placement, SharedTransformSystem transform, SpriteSystem sprite)
{
IoCManager.InjectDependencies(this);
_placement = placement;
_transform = transform;
_sprite = sprite;
ZIndex = 1000;
}

protected override void Draw(in OverlayDrawArgs args)
Expand Down Expand Up @@ -55,7 +57,7 @@ protected override void Draw(in OverlayDrawArgs args)

if (snap)
{
localPos = (Vector2) localPos.Floored() + grid.TileSizeHalfVector;
localPos = localPos.Floored() + grid.TileSizeHalfVector;
}

// Nothing uses snap cardinals so probably don't need preview?
Expand Down
9 changes: 6 additions & 3 deletions Content.Client/IoC/ClientContentIoC.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@
using Content.Client.DiscordAuth;
using Content.Client.JoinQueue;
using Content.Client.Eui;
using Content.Client.Fullscreen;
using Content.Client.GhostKick;
using Content.Client.Guidebook;
using Content.Client.Launcher;
using Content.Client.Mapping;
using Content.Client.Parallax.Managers;
using Content.Client.Players.PlayTimeTracking;
using Content.Client.Replay;
using Content.Client.Screenshot;
using Content.Client.Fullscreen;
using Content.Client.Stylesheets;
using Content.Client.Viewport;
using Content.Client.Voting;
using Content.Shared.Administration.Logs;
using Content.Client.Guidebook;
using Content.Client.Lobby;
using Content.Client.Players.RateLimiting;
using Content.Client.Replay;
Expand All @@ -26,7 +28,6 @@
using Content.Shared.Players.RateLimiting;
using Robust.Client.GameObjects;


namespace Content.Client.IoC
{
internal static class ClientContentIoC
Expand Down Expand Up @@ -61,6 +62,8 @@ public static void Register()
collection.Register<PlayerRateLimitManager>();
collection.Register<SharedPlayerRateLimitManager, PlayerRateLimitManager>();
collection.Register<NanoChatSystem>();
collection.Register<MappingManager>();
collection.Register<DebugMonitorManager>();
}
}
}
8 changes: 8 additions & 0 deletions Content.Client/Mapping/MappingActionsButton.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<mapping:MappingActionsButton
xmlns="https://spacestation14.io"
xmlns:mapping="clr-namespace:Content.Client.Mapping"
StyleClasses="ButtonSquare" ToggleMode="True" SetSize="32 32" Margin="0 0 5 0"
TooltipDelay="0">
<TextureRect Name="Texture" Access="Public" Stretch="Scale" SetSize="16 16"
HorizontalAlignment="Center" VerticalAlignment="Center" />
</mapping:MappingActionsButton>
15 changes: 15 additions & 0 deletions Content.Client/Mapping/MappingActionsButton.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;

namespace Content.Client.Mapping;

[GenerateTypedNameReferences]
public sealed partial class MappingActionsButton : Button
{
public MappingActionsButton()
{
RobustXamlLoader.Load(this);
}
}

4 changes: 4 additions & 0 deletions Content.Client/Mapping/MappingDoNotMeasure.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<mapping:MappingDoNotMeasure
xmlns="https://spacestation14.io"
xmlns:mapping="clr-namespace:Content.Client.Mapping">
</mapping:MappingDoNotMeasure>
21 changes: 21 additions & 0 deletions Content.Client/Mapping/MappingDoNotMeasure.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Numerics;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.XAML;

namespace Content.Client.Mapping;

[GenerateTypedNameReferences]
public sealed partial class MappingDoNotMeasure : Control
{
public MappingDoNotMeasure()
{
RobustXamlLoader.Load(this);
}

protected override Vector2 MeasureOverride(Vector2 availableSize)
{
return Vector2.Zero;
}
}

69 changes: 69 additions & 0 deletions Content.Client/Mapping/MappingManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Content.Shared.Mapping;
using Robust.Client.UserInterface;
using Robust.Shared.Network;

namespace Content.Client.Mapping;

public sealed class MappingManager : IPostInjectInit
{
[Dependency] private readonly IFileDialogManager _file = default!;
[Dependency] private readonly IClientNetManager _net = default!;

private Stream? _saveStream;
private MappingMapDataMessage? _mapData;

public void PostInject()
{
_net.RegisterNetMessage<MappingSaveMapMessage>();
_net.RegisterNetMessage<MappingSaveMapErrorMessage>(OnSaveError);
_net.RegisterNetMessage<MappingMapDataMessage>(OnMapData);
}

private void OnSaveError(MappingSaveMapErrorMessage message)
{
_saveStream?.DisposeAsync();
_saveStream = null;
}

private async void OnMapData(MappingMapDataMessage message)
{
if (_saveStream == null)
{
_mapData = message;
return;
}

await _saveStream.WriteAsync(Encoding.ASCII.GetBytes(message.Yml));
await _saveStream.DisposeAsync();

_saveStream = null;
_mapData = null;
}

public async Task SaveMap()
{
if (_saveStream != null)
await _saveStream.DisposeAsync();

var request = new MappingSaveMapMessage();
_net.ClientSendMessage(request);

var path = await _file.SaveFile();
if (path is not { fileStream: var stream })
return;

if (_mapData != null)
{
await stream.WriteAsync(Encoding.ASCII.GetBytes(_mapData.Yml));
_mapData = null;
await stream.FlushAsync();
await stream.DisposeAsync();
return;
}

_saveStream = stream;
}
}
Loading

0 comments on commit cb6a090

Please sign in to comment.