]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
UI to edit silicon laws from admin verb (#28483)
authorSimon <63975668+Simyon264@users.noreply.github.com>
Fri, 9 Aug 2024 06:16:22 +0000 (08:16 +0200)
committerGitHub <noreply@github.com>
Fri, 9 Aug 2024 06:16:22 +0000 (16:16 +1000)
* UI to edit silicon laws from admin verb

(peak shitcode)

* Improve UI

* Use Moderator admin flag

* Reviews

Content.Client/Silicons/Laws/SiliconLawEditUi/SiliconLawContainer.xaml [new file with mode: 0644]
Content.Client/Silicons/Laws/SiliconLawEditUi/SiliconLawContainer.xaml.cs [new file with mode: 0644]
Content.Client/Silicons/Laws/SiliconLawEditUi/SiliconLawEui.cs [new file with mode: 0644]
Content.Client/Silicons/Laws/SiliconLawEditUi/SiliconLawUi.xaml [new file with mode: 0644]
Content.Client/Silicons/Laws/SiliconLawEditUi/SiliconLawUi.xaml.cs [new file with mode: 0644]
Content.Client/Stylesheets/StyleNano.cs
Content.Server/Administration/Systems/AdminVerbSystem.cs
Content.Server/Silicons/Laws/SiliconLawEui.cs [new file with mode: 0644]
Content.Server/Silicons/Laws/SiliconLawSystem.cs
Content.Shared/Silicons/Laws/SiliconLawEditEuiState.cs [new file with mode: 0644]
Resources/Locale/en-US/administration/ui/silicon-law-ui.ftl [new file with mode: 0644]

diff --git a/Content.Client/Silicons/Laws/SiliconLawEditUi/SiliconLawContainer.xaml b/Content.Client/Silicons/Laws/SiliconLawEditUi/SiliconLawContainer.xaml
new file mode 100644 (file)
index 0000000..1bcac4b
--- /dev/null
@@ -0,0 +1,31 @@
+<BoxContainer
+    xmlns="https://spacestation14.io"
+    xmlns:graphics="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
+    xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
+    HorizontalExpand="True"
+    Orientation="Vertical"
+    >
+    <customControls:HSeparator></customControls:HSeparator>
+    <BoxContainer>
+        <Label StyleClasses="SiliconLawPositionLabel" Name="PositionText" Margin="5 0 0 0"></Label>
+        <PanelContainer
+            Margin="20 10 0 0"
+            MinHeight="128"
+        >
+            <PanelContainer.PanelOverride>
+                <graphics:StyleBoxFlat BackgroundColor="#1B1B1B"></graphics:StyleBoxFlat>
+            </PanelContainer.PanelOverride>
+            <BoxContainer Orientation="Horizontal" SeparationOverride="5">
+                <TextEdit Name="LawContent" HorizontalExpand="True" Editable="True" MinWidth="500" MinHeight="80"></TextEdit>
+            </BoxContainer>
+        </PanelContainer>
+    </BoxContainer>
+    <BoxContainer Orientation="Horizontal" Margin="0 5 0 0" MaxHeight="64" Align="Begin">
+        <Button Name="MoveUp" Text="{Loc silicon-law-ui-minus-one}" StyleClasses="OpenRight"></Button>
+        <Button Name="MoveDown" Text="{Loc silicon-law-ui-plus-one}" StyleClasses="OpenLeft"></Button>
+        <CheckBox Name="Corrupted" Text="{Loc silicon-law-ui-check-corrupted}" ToolTip="{Loc silicon-law-ui-check-corrupted-tooltip}"></CheckBox>
+    </BoxContainer>
+    <BoxContainer Orientation="Horizontal" Align="End" Margin="0 10 5 10">
+        <Button Name="Delete" Text="{Loc silicon-law-ui-delete}" ModulateSelfOverride="Red"></Button>
+    </BoxContainer>
+</BoxContainer>
diff --git a/Content.Client/Silicons/Laws/SiliconLawEditUi/SiliconLawContainer.xaml.cs b/Content.Client/Silicons/Laws/SiliconLawEditUi/SiliconLawContainer.xaml.cs
new file mode 100644 (file)
index 0000000..2e44b82
--- /dev/null
@@ -0,0 +1,61 @@
+using Content.Shared.Silicons.Laws;
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.XAML;
+using Robust.Shared.Utility;
+
+namespace Content.Client.Silicons.Laws.SiliconLawEditUi;
+
+[GenerateTypedNameReferences]
+public sealed partial class SiliconLawContainer : BoxContainer
+{
+    public const string StyleClassSiliconLawPositionLabel = "SiliconLawPositionLabel";
+
+    public static readonly string CorruptedString =
+        Loc.GetString("ion-storm-law-scrambled-number", ("length", 5));
+
+    private SiliconLaw? _law;
+
+    public event Action<SiliconLaw>? MoveLawUp;
+    public event Action<SiliconLaw>? MoveLawDown;
+    public event Action<SiliconLaw>? DeleteAction;
+
+
+    public SiliconLawContainer()
+    {
+        RobustXamlLoader.Load(this);
+
+        MoveUp.OnPressed += _ => MoveLawUp?.Invoke(_law!);
+        MoveDown.OnPressed += _ => MoveLawDown?.Invoke(_law!);
+        Corrupted.OnPressed += _ =>
+        {
+            if (Corrupted.Pressed)
+            {
+                _law!.LawIdentifierOverride = CorruptedString;
+            }
+            else
+            {
+                _law!.LawIdentifierOverride = null;
+            }
+        };
+
+        LawContent.OnTextChanged += _ => _law!.LawString = Rope.Collapse(LawContent.TextRope).Trim();
+        LawContent.Placeholder = new Rope.Leaf(Loc.GetString("silicon-law-ui-placeholder"));
+        Delete.OnPressed += _ => DeleteAction?.Invoke(_law!);
+    }
+
+    public void SetLaw(SiliconLaw law)
+    {
+        _law = law;
+        LawContent.TextRope = new Rope.Leaf(Loc.GetString(law.LawString));
+        PositionText.Text = law.Order.ToString();
+        if (!string.IsNullOrEmpty(law.LawIdentifierOverride))
+        {
+            Corrupted.Pressed = true;
+        }
+        else
+        {
+            Corrupted.Pressed = false;
+        }
+    }
+}
diff --git a/Content.Client/Silicons/Laws/SiliconLawEditUi/SiliconLawEui.cs b/Content.Client/Silicons/Laws/SiliconLawEditUi/SiliconLawEui.cs
new file mode 100644 (file)
index 0000000..a4d59d1
--- /dev/null
@@ -0,0 +1,38 @@
+using Content.Client.Eui;
+using Content.Shared.Eui;
+using Content.Shared.Silicons.Laws;
+
+namespace Content.Client.Silicons.Laws.SiliconLawEditUi;
+
+public sealed class SiliconLawEui : BaseEui
+{
+    public readonly EntityManager _entityManager = default!;
+
+    private SiliconLawUi _siliconLawUi;
+    private EntityUid _target;
+
+    public SiliconLawEui()
+    {
+        _entityManager = IoCManager.Resolve<EntityManager>();
+
+        _siliconLawUi = new SiliconLawUi();
+        _siliconLawUi.OnClose += () => SendMessage(new CloseEuiMessage());
+        _siliconLawUi.Save.OnPressed += _ => SendMessage(new SiliconLawsSaveMessage(_siliconLawUi.GetLaws(), _entityManager.GetNetEntity(_target)));
+    }
+
+    public override void HandleState(EuiStateBase state)
+    {
+        if (state is not SiliconLawsEuiState s)
+        {
+            return;
+        }
+
+        _target = _entityManager.GetEntity(s.Target);
+        _siliconLawUi.SetLaws(s.Laws);
+    }
+
+    public override void Opened()
+    {
+        _siliconLawUi.OpenCentered();
+    }
+}
diff --git a/Content.Client/Silicons/Laws/SiliconLawEditUi/SiliconLawUi.xaml b/Content.Client/Silicons/Laws/SiliconLawEditUi/SiliconLawUi.xaml
new file mode 100644 (file)
index 0000000..19dcbac
--- /dev/null
@@ -0,0 +1,22 @@
+<controls:FancyWindow
+    xmlns="https://spacestation14.io"
+    xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
+    Title="{Loc silicon-law-ui-title}"
+    MinSize="560 400"
+>
+    <!-->
+    this shit does not layout properly unless I put the horizontal boxcontainer inside of a vertical one
+    ????
+    <!-->
+    <BoxContainer Orientation="Vertical">
+        <BoxContainer Orientation="Horizontal" Align="End">
+            <Button Name="NewLawButton" Text="{Loc silicon-law-ui-new-law}" MaxSize="256 64" StyleClasses="OpenRight"></Button>
+            <Button Name="Save" Text="{Loc silicon-law-ui-save}" MaxSize="256 64" Access="Public" StyleClasses="OpenLeft"></Button>
+        </BoxContainer>
+    </BoxContainer>
+    <BoxContainer Orientation="Vertical" Margin="4 60 0 0">
+        <ScrollContainer VerticalExpand="True" HorizontalExpand="True" HScrollEnabled="False">
+            <BoxContainer Orientation="Vertical" Name="LawContainer" Access="Public" VerticalExpand="True" />
+        </ScrollContainer>
+    </BoxContainer>
+</controls:FancyWindow>
diff --git a/Content.Client/Silicons/Laws/SiliconLawEditUi/SiliconLawUi.xaml.cs b/Content.Client/Silicons/Laws/SiliconLawEditUi/SiliconLawUi.xaml.cs
new file mode 100644 (file)
index 0000000..372961e
--- /dev/null
@@ -0,0 +1,89 @@
+using System.Linq;
+using Content.Client.UserInterface.Controls;
+using Content.Shared.FixedPoint;
+using Content.Shared.Silicons.Laws;
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.XAML;
+
+namespace Content.Client.Silicons.Laws.SiliconLawEditUi;
+
+[GenerateTypedNameReferences]
+public sealed partial class SiliconLawUi : FancyWindow
+{
+    private List<SiliconLaw> _laws = new();
+
+    public SiliconLawUi()
+    {
+        RobustXamlLoader.Load(this);
+        NewLawButton.OnPressed += _ => AddNewLaw();
+    }
+
+    private void AddNewLaw()
+    {
+        var newLaw = new SiliconLaw();
+        newLaw.Order = FixedPoint2.New(_laws.Count + 1);
+        _laws.Add(newLaw);
+        SetLaws(_laws);
+    }
+
+    public void SetLaws(List<SiliconLaw> sLaws)
+    {
+        _laws = sLaws;
+        LawContainer.RemoveAllChildren();
+        foreach (var law in sLaws.OrderBy(l => l.Order))
+        {
+            var lawControl = new SiliconLawContainer();
+            lawControl.SetLaw(law);
+            lawControl.MoveLawDown += MoveLawDown;
+            lawControl.MoveLawUp += MoveLawUp;
+            lawControl.DeleteAction += DeleteLaw;
+
+            LawContainer.AddChild(lawControl);
+        }
+    }
+
+    public void DeleteLaw(SiliconLaw law)
+    {
+        _laws.Remove(law);
+        SetLaws(_laws);
+    }
+
+    public void MoveLawDown(SiliconLaw law)
+    {
+        if (_laws.Count == 0)
+        {
+            return;
+        }
+
+        var index = _laws.IndexOf(law);
+        if (index == -1)
+        {
+            return;
+        }
+
+        _laws[index].Order += FixedPoint2.New(1);
+        SetLaws(_laws);
+    }
+
+    public void MoveLawUp(SiliconLaw law)
+    {
+        if (_laws.Count == 0)
+        {
+            return;
+        }
+
+        var index = _laws.IndexOf(law);
+        if (index == -1)
+        {
+            return;
+        }
+
+        _laws[index].Order += FixedPoint2.New(-1);
+        SetLaws(_laws);
+    }
+
+    public List<SiliconLaw> GetLaws()
+    {
+        return _laws;
+    }
+}
index 0c04a550597e370a0ebffb4cfebccc412f3d7e28..0bd75003a209fef43c2d7b3ccaae4ad43d4012a8 100644 (file)
@@ -4,6 +4,7 @@ using Content.Client.ContextMenu.UI;
 using Content.Client.Examine;
 using Content.Client.PDA;
 using Content.Client.Resources;
+using Content.Client.Silicons.Laws.SiliconLawEditUi;
 using Content.Client.UserInterface.Controls;
 using Content.Client.UserInterface.Controls.FancyTree;
 using Content.Client.Verbs.UI;
@@ -1613,6 +1614,10 @@ namespace Content.Client.Stylesheets
                     {
                         BackgroundColor = FancyTreeSelectedRowColor,
                     }),
+
+                // Silicon law edit ui
+                Element<Label>().Class(SiliconLawContainer.StyleClassSiliconLawPositionLabel)
+                    .Prop(Label.StylePropertyFontColor, NanoGold),
                 // Pinned button style
                 new StyleRule(
                     new SelectorElement(typeof(TextureButton), new[] { StyleClassPinButtonPinned }, null, null),
index 6198611ac8f244b16bcb9cf5c5fa2670f95a531c..6123bba8deeb5d9ceb64b18a9b316e64d90a0843 100644 (file)
@@ -35,6 +35,9 @@ using Robust.Shared.Toolshed;
 using Robust.Shared.Utility;
 using System.Linq;
 using System.Numerics;
+using Content.Server.Silicons.Laws;
+using Content.Shared.Silicons.Laws.Components;
+using Robust.Server.Player;
 using Robust.Shared.Physics.Components;
 using static Content.Shared.Configurable.ConfigurationComponent;
 
@@ -68,6 +71,8 @@ namespace Content.Server.Administration.Systems
         [Dependency] private readonly StationSpawningSystem _spawning = default!;
         [Dependency] private readonly ExamineSystemShared _examine = default!;
         [Dependency] private readonly AdminFrozenSystem _freeze = default!;
+        [Dependency] private readonly IPlayerManager _playerManager = default!;
+        [Dependency] private readonly SiliconLawSystem _siliconLawSystem = default!;
 
         private readonly Dictionary<ICommonSession, List<EditSolutionsEui>> _openSolutionUis = new();
 
@@ -338,6 +343,25 @@ namespace Content.Server.Administration.Systems
                     Impact = LogImpact.Low
                 });
 
+                if (TryComp<SiliconLawBoundComponent>(args.Target, out var lawBoundComponent))
+                {
+                    args.Verbs.Add(new Verb()
+                    {
+                        Text = Loc.GetString("silicon-law-ui-verb"),
+                        Category = VerbCategory.Admin,
+                        Act = () =>
+                        {
+                            var ui = new SiliconLawEui(_siliconLawSystem, EntityManager, _adminManager);
+                            if (!_playerManager.TryGetSessionByEntity(args.User, out var session))
+                            {
+                                return;
+                            }
+                            _euiManager.OpenEui(ui, session);
+                            ui.UpdateLaws(lawBoundComponent, args.Target);
+                        },
+                        Icon = new SpriteSpecifier.Rsi(new ResPath("/Textures/Interface/Actions/actions_borg.rsi"), "state-laws"),
+                    });
+                }
             }
         }
 
diff --git a/Content.Server/Silicons/Laws/SiliconLawEui.cs b/Content.Server/Silicons/Laws/SiliconLawEui.cs
new file mode 100644 (file)
index 0000000..d5a5c4f
--- /dev/null
@@ -0,0 +1,70 @@
+using Content.Server.Administration.Managers;
+using Content.Server.EUI;
+using Content.Shared.Administration;
+using Content.Shared.Eui;
+using Content.Shared.Silicons.Laws;
+using Content.Shared.Silicons.Laws.Components;
+
+namespace Content.Server.Silicons.Laws;
+
+public sealed class SiliconLawEui : BaseEui
+{
+    private readonly SiliconLawSystem _siliconLawSystem;
+    private readonly EntityManager _entityManager;
+    private readonly IAdminManager _adminManager;
+
+    private List<SiliconLaw> _laws = new();
+    private ISawmill _sawmill = default!;
+    private EntityUid _target;
+
+    public SiliconLawEui(SiliconLawSystem siliconLawSystem, EntityManager entityManager, IAdminManager manager)
+    {
+        _siliconLawSystem = siliconLawSystem;
+        _adminManager = manager;
+        _entityManager = entityManager;
+        _sawmill = Logger.GetSawmill("silicon-law-eui");
+    }
+
+    public override EuiStateBase GetNewState()
+    {
+        return new SiliconLawsEuiState(_laws, _entityManager.GetNetEntity(_target));
+    }
+
+    public void UpdateLaws(SiliconLawBoundComponent? lawBoundComponent, EntityUid player)
+    {
+        if (!IsAllowed())
+            return;
+
+        var laws = _siliconLawSystem.GetLaws(player, lawBoundComponent);
+        _laws = laws.Laws;
+        _target = player;
+        StateDirty();
+    }
+
+    public override void HandleMessage(EuiMessageBase msg)
+    {
+        if (msg is not SiliconLawsSaveMessage message)
+        {
+            return;
+        }
+
+        if (!IsAllowed())
+            return;
+
+        var player = _entityManager.GetEntity(message.Target);
+
+        _siliconLawSystem.SetLaws(message.Laws, player);
+    }
+
+    private bool IsAllowed()
+    {
+        var adminData = _adminManager.GetAdminData(Player);
+        if (adminData == null || !adminData.HasFlag(AdminFlags.Moderator))
+        {
+            _sawmill.Warning("Player {0} tried to open / use silicon law UI without permission.", Player.UserId);
+            return false;
+        }
+
+        return true;
+    }
+}
index bc7a7b35c27cd8dc14da38f764b54460d9503fba..0c0f68c23f352e4199d7b776a79cf95cb1fb423f 100644 (file)
@@ -22,6 +22,7 @@ using Robust.Server.GameObjects;
 using Robust.Shared.Player;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Toolshed;
+using Robust.Shared.Utility;
 
 namespace Content.Server.Silicons.Laws;
 
@@ -278,6 +279,21 @@ public sealed class SiliconLawSystem : SharedSiliconLawSystem
 
         return laws;
     }
+
+    /// <summary>
+    /// Set the laws of a silicon entity while notifying the player.
+    /// </summary>
+    public void SetLaws(List<SiliconLaw> newLaws, EntityUid target)
+    {
+        if (!TryComp<SiliconLawProviderComponent>(target, out var component))
+            return;
+
+        if (component.Lawset == null)
+            component.Lawset = new SiliconLawset();
+
+        component.Lawset.Laws = newLaws;
+        NotifyLawsChanged(target);
+    }
 }
 
 [ToolshedCommand, AdminCommand(AdminFlags.Admin)]
diff --git a/Content.Shared/Silicons/Laws/SiliconLawEditEuiState.cs b/Content.Shared/Silicons/Laws/SiliconLawEditEuiState.cs
new file mode 100644 (file)
index 0000000..b5b3583
--- /dev/null
@@ -0,0 +1,29 @@
+using Content.Shared.Eui;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Silicons.Laws;
+
+[Serializable, NetSerializable]
+public sealed class SiliconLawsEuiState : EuiStateBase
+{
+    public List<SiliconLaw> Laws { get; }
+    public NetEntity Target { get; }
+    public SiliconLawsEuiState(List<SiliconLaw> laws, NetEntity target)
+    {
+        Laws = laws;
+        Target = target;
+    }
+}
+
+[Serializable, NetSerializable]
+public sealed class SiliconLawsSaveMessage : EuiMessageBase
+{
+    public List<SiliconLaw> Laws { get; }
+    public NetEntity Target { get; }
+
+    public SiliconLawsSaveMessage(List<SiliconLaw> laws, NetEntity target)
+    {
+        Laws = laws;
+        Target = target;
+    }
+}
diff --git a/Resources/Locale/en-US/administration/ui/silicon-law-ui.ftl b/Resources/Locale/en-US/administration/ui/silicon-law-ui.ftl
new file mode 100644 (file)
index 0000000..0a68d08
--- /dev/null
@@ -0,0 +1,10 @@
+silicon-law-ui-verb = Manage laws
+silicon-law-ui-title = Silicon laws
+silicon-law-ui-new-law = New law
+silicon-law-ui-save = Save changes
+silicon-law-ui-plus-one = +1
+silicon-law-ui-minus-one = -1
+silicon-law-ui-delete = Delete
+silicon-law-ui-check-corrupted = Corrupted law
+silicon-law-ui-check-corrupted-tooltip = If the law identifier should be set as 'corrupted', so symbols shuffling around.
+silicon-law-ui-placeholder = Type here to change law text...