UI to edit silicon laws from admin verb (#28483)

* UI to edit silicon laws from admin verb

(peak shitcode)

* Improve UI

* Use Moderator admin flag

* Reviews
This commit is contained in:
Simon
2024-08-09 08:16:22 +02:00
committed by GitHub
parent 8d96c993a2
commit 4c4cdb5b06
11 changed files with 395 additions and 0 deletions

View File

@@ -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>

View File

@@ -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;
}
}
}

View File

@@ -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();
}
}

View File

@@ -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>

View File

@@ -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;
}
}

View 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),

View 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"),
});
}
}
}

View File

@@ -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;
}
}

View 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)]

View File

@@ -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;
}
}

View File

@@ -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...