From 27177069941dbd099bb517780800f271ceb72684 Mon Sep 17 00:00:00 2001 From: Debug <49997488+DebugOk@users.noreply.github.com> Date: Mon, 19 Feb 2024 22:58:14 +0100 Subject: [PATCH] Make loadacts more user friendly (#864) Allow loadacts to take a file --- Content.Client/Actions/ActionsSystem.cs | 65 ++++++++++++++++++++++ Content.Client/Commands/ActionsCommands.cs | 29 +++++++++- 2 files changed, 91 insertions(+), 3 deletions(-) diff --git a/Content.Client/Actions/ActionsSystem.cs b/Content.Client/Actions/ActionsSystem.cs index 2343b9eac15..eceeee03ad0 100644 --- a/Content.Client/Actions/ActionsSystem.cs +++ b/Content.Client/Actions/ActionsSystem.cs @@ -1,6 +1,7 @@ using System.IO; using System.Linq; using Content.Shared.Actions; +using Content.Shared.Mapping; using JetBrains.Annotations; using Robust.Client.Player; using Robust.Shared.ContentPack; @@ -310,6 +311,70 @@ public void LoadActionAssignments(string path, bool userData) AssignSlot?.Invoke(assignments); } + /// + /// Load actions and their toolbar assignments from a file. + /// DeltaV - Load from an existing yaml stream instead + /// + public void LoadActionAssignments(YamlStream stream) + { + if (_playerManager.LocalEntity is not { } user) + return; + + if (stream.Documents[0].RootNode.ToDataNode() is not SequenceDataNode sequence) + return; + + ClearAssignments?.Invoke(); + + var assignments = new List(); + var existingActions = GetClientActions(); + var existingActionsList = existingActions.ToList(); + + foreach (var entry in sequence.Sequence) + { + if (entry is not MappingDataNode map) + continue; + + if (!map.TryGet("action", out var actionNode)) + continue; + + if (!map.TryGet("name", out var nameNode)) + continue; + + var action = _serialization.Read(actionNode, notNullableOverride: true); + + // Prevent spawning actions multiple times + var existing = existingActionsList.FirstOrNull(a => + Name(a.Id) == nameNode.Value); + + EntityUid actionId; + if (existing == null) + { + actionId = Spawn(null); + AddComp(actionId, action); + _metaData.SetEntityName(actionId, nameNode.Value); + DirtyEntity(actionId); + AddActionDirect(user, actionId); + } + else + { + actionId = existing.Value.Id; + } + + if (!map.TryGet("assignments", out var assignmentNode)) + continue; + + var nodeAssignments = _serialization.Read>(assignmentNode, notNullableOverride: true); + + foreach (var index in nodeAssignments) + { + var assignment = new SlotAssignment(index.Hotbar, index.Slot, actionId); + assignments.Add(assignment); + } + } + + AssignSlot?.Invoke(assignments); + } + public record struct SlotAssignment(byte Hotbar, byte Slot, EntityUid ActionId); } } diff --git a/Content.Client/Commands/ActionsCommands.cs b/Content.Client/Commands/ActionsCommands.cs index 3d8e906e09e..b8bba00c503 100644 --- a/Content.Client/Commands/ActionsCommands.cs +++ b/Content.Client/Commands/ActionsCommands.cs @@ -1,7 +1,10 @@ +using System.IO; using Content.Client.Actions; using Content.Client.Mapping; using Content.Shared.Administration; +using Robust.Client.UserInterface; using Robust.Shared.Console; +using YamlDotNet.RepresentationModel; namespace Content.Client.Commands; @@ -34,7 +37,7 @@ public void Execute(IConsoleShell shell, string argStr, string[] args) } */ -[AnyCommand] +// [AnyCommand] DeltaV - Disable AnyCommand, require at least admin rank public sealed class LoadActionsCommand : LocalizedCommands { [Dependency] private readonly IEntitySystemManager _entitySystemManager = default!; @@ -47,7 +50,7 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args) { if (args.Length != 1) { - shell.WriteLine(Help); + LoadActs(); // DeltaV - Load from a file dialogue instead return; } @@ -60,9 +63,29 @@ public override void Execute(IConsoleShell shell, string argStr, string[] args) shell.WriteError(LocalizationManager.GetString($"cmd-{Command}-error")); } } + + /// + /// DeltaV - Load actions from a file stream instead + /// + private static async void LoadActs() + { + var fileMan = IoCManager.Resolve(); + var actMan = IoCManager.Resolve().GetEntitySystem(); + + var stream = await fileMan.OpenFile(new FileDialogFilters(new FileDialogFilters.Group("yml"))); + if (stream is null) + return; + + var reader = new StreamReader(stream); + var yamlStream = new YamlStream(); + yamlStream.Load(reader); + + actMan.LoadActionAssignments(yamlStream); + reader.Close(); + } } -[AnyCommand] +// [AnyCommand] DeltaV - Disable AnyCommand, require at least admin rank public sealed class LoadMappingActionsCommand : LocalizedCommands { [Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;