Skip to content

Commit

Permalink
Add mapping editor (new-frontiers-14#757)
Browse files Browse the repository at this point in the history
  • Loading branch information
DrSmugleaf authored and dvir001 committed Jan 2, 2024
1 parent e95111e commit c126434
Show file tree
Hide file tree
Showing 29 changed files with 1,839 additions and 4 deletions.
4 changes: 3 additions & 1 deletion Content.Client/Commands/MappingClientSideSetupCommand.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using JetBrains.Annotations;
using System;
using Content.Client._CM14.Mapping;
using Content.Client.Markers;
using Robust.Client.Graphics;
using Robust.Client.State;
using Robust.Shared.Console;
using Robust.Shared.GameObjects;

Expand All @@ -27,7 +29,7 @@ public void Execute(IConsoleShell shell, string argStr, string[] args)
EntitySystem.Get<MarkerSystem>().MarkersVisible = true;
mgr.Enabled = false;
shell.ExecuteCommand("showsubfloorforever");
shell.ExecuteCommand("loadmapacts");
IoCManager.Resolve<IStateManager>().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
@@ -1,5 +1,6 @@
using System.Numerics;
using System.Threading;
using Content.Client._CM14.Mapping;
using Content.Client.CombatMode;
using Content.Client.Gameplay;
using Robust.Client.UserInterface;
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
2 changes: 2 additions & 0 deletions Content.Client/IoC/ClientContentIoC.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Content.Client._CM14.Mapping;
using Content.Client.Administration.Managers;
using Content.Client.Changelog;
using Content.Client.Chat.Managers;
Expand Down Expand Up @@ -49,6 +50,7 @@ public static void Register()
IoCManager.Register<JobRequirementsManager>();
IoCManager.Register<DocumentParsingManager>();
IoCManager.Register<ContentReplayPlaybackManager, ContentReplayPlaybackManager>();
IoCManager.Register<MappingManager>();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ private void UnloadGui()

private void LoadGui()
{
DebugTools.Assert(_window == null);
UnloadGui();
_window = UIManager.CreateWindow<ActionsWindow>();
LayoutContainer.SetAnchorPreset(_window, LayoutContainer.LayoutPreset.CenterTop);

Expand Down
8 changes: 8 additions & 0 deletions Content.Client/_CM14/Mapping/MappingActionsButton.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<controls:MappingActionsButton
xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client._CM14.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" />
</controls:MappingActionsButton>
15 changes: 15 additions & 0 deletions Content.Client/_CM14/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._CM14.Mapping;

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

5 changes: 5 additions & 0 deletions Content.Client/_CM14/Mapping/MappingDoNotMeasure.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<controls:MappingDoNotMeasure
xmlns="https://spacestation14.io"
xmlns:controls="clr-namespace:Content.Client._CM14.Mapping">

</controls:MappingDoNotMeasure>
21 changes: 21 additions & 0 deletions Content.Client/_CM14/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._CM14.Mapping;

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

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

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

namespace Content.Client._CM14.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.DisposeAsync();
return;
}

_saveStream = stream;
}
}
87 changes: 87 additions & 0 deletions Content.Client/_CM14/Mapping/MappingOverlay.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Input;
using Robust.Client.Player;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.Enums;
using Robust.Shared.Prototypes;
using static Content.Client._CM14.Mapping.MappingState;

namespace Content.Client._CM14.Mapping;

public sealed class MappingOverlay : Overlay
{
[Dependency] private readonly IEntityManager _entities = default!;
[Dependency] private readonly IInputManager _input = default!;
[Dependency] private readonly IPlayerManager _player = default!;
[Dependency] private readonly IPrototypeManager _prototypes = default!;
[Dependency] private readonly IUserInterfaceManager _ui = default!;

// 1 off in case something else uses these colors since we use them to compare
private static readonly Color PickColor = new(1, 255, 0);
private static readonly Color DeleteColor = new(255, 1, 0);

private readonly Dictionary<EntityUid, Color> _oldColors = new();

private readonly MappingState _state;
private readonly ShaderInstance _shader;

public override OverlaySpace Space => OverlaySpace.WorldSpace;

public MappingOverlay(MappingState state)
{
IoCManager.InjectDependencies(this);

_state = state;
_shader = _prototypes.Index<ShaderPrototype>("unshaded").Instance();
}

protected override void Draw(in OverlayDrawArgs args)
{
foreach (var (id, color) in _oldColors)
{
if (!_entities.TryGetComponent(id, out SpriteComponent? sprite))
continue;

if (sprite.Color == DeleteColor || sprite.Color == PickColor)
sprite.Color = color;
}

_oldColors.Clear();

if (_player.LocalEntity == null)
return;

var handle = args.WorldHandle;
handle.UseShader(_shader);

switch (_state.State)
{
case CursorState.Pick:
{
if (_state.GetHoveredEntity() is { } entity &&
_entities.TryGetComponent(entity, out SpriteComponent? sprite))
{
_oldColors[entity] = sprite.Color;
sprite.Color = PickColor;
}

break;
}
case CursorState.Delete:
{
if (_state.GetHoveredEntity() is { } entity &&
_entities.TryGetComponent(entity, out SpriteComponent? sprite))
{
_oldColors[entity] = sprite.Color;
sprite.Color = DeleteColor;
}

break;
}
}

handle.UseShader(null);
}
}
17 changes: 17 additions & 0 deletions Content.Client/_CM14/Mapping/MappingPrototype.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Robust.Shared.Prototypes;

namespace Content.Client._CM14.Mapping;

public sealed class MappingPrototype
{
public readonly IPrototype? Prototype;
public readonly string Name;
public List<MappingPrototype>? Parents;
public List<MappingPrototype>? Children;

public MappingPrototype(IPrototype? prototype, string name)
{
Prototype = prototype;
Name = name;
}
}
21 changes: 21 additions & 0 deletions Content.Client/_CM14/Mapping/MappingPrototypeList.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<cc:MappingPrototypeList
xmlns="https://spacestation14.io"
xmlns:cc="clr-namespace:Content.Client._CM14.Mapping">
<BoxContainer Orientation="Vertical">
<BoxContainer Orientation="Horizontal">
<Button Name="CollapseAllButton" Access="Public" Text="-"
StyleClasses="ButtonSquare" ToolTip="Collapse All" TooltipDelay="0" />
<LineEdit Name="SearchBar" HorizontalExpand="True" Access="Public" />
<Button Name="ClearSearchButton" Access="Public" Text="X"
StyleClasses="ButtonSquare" />
</BoxContainer>
<ScrollContainer Name="ScrollContainer" Access="Public" VerticalExpand="True"
ReserveScrollbarSpace="True">
<BoxContainer Name="PrototypeList" Access="Public" Orientation="Vertical" />
<PrototypeListContainer Name="SearchList" Access="Public" Visible="False" />
</ScrollContainer>
<cc:MappingDoNotMeasure Visible="False">
<cc:MappingSpawnButton Name="MeasureButton" Access="Public" />
</cc:MappingDoNotMeasure>
</BoxContainer>
</cc:MappingPrototypeList>
Loading

0 comments on commit c126434

Please sign in to comment.