]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
PA ui cleanup + bugfixes (#28750)
authorNemanja <98561806+EmoGarbage404@users.noreply.github.com>
Sun, 21 Jul 2024 05:27:18 +0000 (01:27 -0400)
committerGitHub <noreply@github.com>
Sun, 21 Jul 2024 05:27:18 +0000 (15:27 +1000)
* ui and visual aspect + radio

* finish jank ui shit and finish radio

* remove radio

* send it

---------

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
15 files changed:
Content.Client/ParticleAccelerator/UI/ParticleAcceleratorBoundUserInterface.cs
Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs [deleted file]
Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.xaml [new file with mode: 0644]
Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.xaml.cs [new file with mode: 0644]
Content.Server/ParticleAccelerator/Components/ParticleAcceleratorEmitterComponent.cs
Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.ControlBox.cs
Content.Server/ParticleAccelerator/EntitySystems/ParticleAcceleratorSystem.Parts.cs
Content.Server/ParticleAccelerator/Wires/ParticleAcceleratorInterfaceWireAction.cs
Content.Server/ParticleAccelerator/Wires/ParticleAcceleratorLimiterWireAction.cs
Content.Server/ParticleAccelerator/Wires/ParticleAcceleratorStrengthWireAction.cs
Resources/Locale/en-US/particle-accelerator/components/ui/particle-accelerator-control-menu.ftl
Resources/Textures/Structures/Power/Generation/PA/control_box.rsi/unlitp0.png
Resources/Textures/Structures/Power/Generation/PA/control_box.rsi/unlitp1.png
Resources/Textures/Structures/Power/Generation/PA/control_box.rsi/unlitp2.png
Resources/Textures/Structures/Power/Generation/PA/control_box.rsi/unlitp3.png

index ff1eae36f55e1872503c53996a4342c10b65f9f0..93306f2fd1ff7963ae968640c4e0a652bb47d27e 100644 (file)
@@ -1,5 +1,4 @@
 using Content.Shared.Singularity.Components;
-using Robust.Client.GameObjects;
 using Robust.Client.UserInterface;
 
 namespace Content.Client.ParticleAccelerator.UI
@@ -18,9 +17,11 @@ namespace Content.Client.ParticleAccelerator.UI
             base.Open();
 
             _menu = this.CreateWindow<ParticleAcceleratorControlMenu>();
+            _menu.SetEntity(Owner);
+
             _menu.OnOverallState += SendEnableMessage;
             _menu.OnPowerState += SendPowerStateMessage;
-            _menu.OnScanPartsRequested += SendScanPartsMessage;
+            _menu.OnScan += SendScanPartsMessage;
         }
 
         public void SendEnableMessage(bool enable)
diff --git a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.cs
deleted file mode 100644 (file)
index 05a296e..0000000
+++ /dev/null
@@ -1,526 +0,0 @@
-using System.Numerics;
-using Content.Client.Resources;
-using Content.Client.Stylesheets;
-using Content.Client.UserInterface.Controls;
-using Content.Shared.Singularity.Components;
-using Robust.Client.Animations;
-using Robust.Client.Graphics;
-using Robust.Client.ResourceManagement;
-using Robust.Client.UserInterface;
-using Robust.Client.UserInterface.Controls;
-using Robust.Client.UserInterface.CustomControls;
-using Robust.Shared.Noise;
-using Robust.Shared.Prototypes;
-using Robust.Shared.Timing;
-using static Robust.Client.UserInterface.Controls.BoxContainer;
-
-namespace Content.Client.ParticleAccelerator.UI
-{
-    public sealed class ParticleAcceleratorControlMenu : BaseWindow
-    {
-        [Dependency] private readonly IPrototypeManager _protoManager = default!;
-        [Dependency] private readonly IResourceCache _cache = default!;
-
-        private readonly ShaderInstance _greyScaleShader;
-
-        private readonly Label _drawLabel;
-        private readonly FastNoiseLite _drawNoiseGenerator;
-        private readonly Button _onButton;
-        private readonly Button _offButton;
-        private readonly Button _scanButton;
-        private readonly Label _statusLabel;
-        private readonly SpinBox _stateSpinBox;
-
-        private readonly BoxContainer _alarmControl;
-        private readonly Animation _alarmControlAnimation;
-
-        private readonly PASegmentControl _endCapTexture;
-        private readonly PASegmentControl _fuelChamberTexture;
-        private readonly PASegmentControl _controlBoxTexture;
-        private readonly PASegmentControl _powerBoxTexture;
-        private readonly PASegmentControl _emitterForeTexture;
-        private readonly PASegmentControl _emitterPortTexture;
-        private readonly PASegmentControl _emitterStarboardTexture;
-
-        private float _time;
-        private int _lastDraw;
-        private int _lastReceive;
-
-        private bool _blockSpinBox;
-        private bool _assembled;
-        private bool _shouldContinueAnimating;
-        private int _maxStrength = 3;
-
-        public event Action<bool>? OnOverallState;
-        public event Action<ParticleAcceleratorPowerState>? OnPowerState;
-        public event Action? OnScanPartsRequested;
-
-        public ParticleAcceleratorControlMenu()
-        {
-            IoCManager.InjectDependencies(this);
-            SetSize = new Vector2(400, 320);
-            _greyScaleShader = _protoManager.Index<ShaderPrototype>("Greyscale").Instance();
-
-            _drawNoiseGenerator = new();
-            _drawNoiseGenerator.SetFractalType(FastNoiseLite.FractalType.FBm);
-            _drawNoiseGenerator.SetFrequency(0.5f);
-
-            var font = _cache.GetFont("/Fonts/Boxfont-round/Boxfont Round.ttf", 13);
-            var panelTex = _cache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png");
-
-            MouseFilter = MouseFilterMode.Stop;
-
-            _alarmControlAnimation = new Animation
-            {
-                Length = TimeSpan.FromSeconds(1),
-                AnimationTracks =
-                {
-                    new AnimationTrackControlProperty
-                    {
-                        Property = nameof(Control.Visible),
-                        KeyFrames =
-                        {
-                            new AnimationTrackProperty.KeyFrame(true, 0),
-                            new AnimationTrackProperty.KeyFrame(false, 0.75f),
-                        }
-                    }
-                }
-            };
-
-            var back = new StyleBoxTexture
-            {
-                Texture = panelTex,
-                Modulate = Color.FromHex("#25252A"),
-            };
-            back.SetPatchMargin(StyleBox.Margin.All, 10);
-
-            var back2 = new StyleBoxTexture(back)
-            {
-                Modulate = Color.FromHex("#202023")
-            };
-
-            AddChild(new PanelContainer
-            {
-                PanelOverride = back,
-                MouseFilter = MouseFilterMode.Pass
-            });
-
-            _stateSpinBox = new SpinBox { Value = 0, IsValid = StrengthSpinBoxValid };
-            _stateSpinBox.InitDefaultButtons();
-            _stateSpinBox.ValueChanged += PowerStateChanged;
-            _stateSpinBox.LineEditDisabled = true;
-
-            _offButton = new Button
-            {
-                ToggleMode = false,
-                Text = Loc.GetString("particle-accelerator-control-menu-off-button"),
-                StyleClasses = { StyleBase.ButtonOpenRight },
-            };
-
-            _offButton.OnPressed += args => OnOverallState?.Invoke(false);
-
-            _onButton = new Button
-            {
-                ToggleMode = false,
-                Text = Loc.GetString("particle-accelerator-control-menu-on-button"),
-                StyleClasses = { StyleBase.ButtonOpenLeft },
-            };
-            _onButton.OnPressed += args => OnOverallState?.Invoke(true);
-
-            var closeButton = new TextureButton
-            {
-                StyleClasses = { "windowCloseButton" },
-                HorizontalAlignment = HAlignment.Right,
-                Margin = new Thickness(0, 0, 8, 0)
-            };
-            closeButton.OnPressed += args => Close();
-
-            var serviceManual = new Label
-            {
-                HorizontalAlignment = HAlignment.Center,
-                StyleClasses = { StyleBase.StyleClassLabelSubText },
-                Text = Loc.GetString("particle-accelerator-control-menu-service-manual-reference")
-            };
-            _drawLabel = new Label();
-            var imgSize = new Vector2(32, 32);
-            AddChild(new BoxContainer
-            {
-                Orientation = LayoutOrientation.Vertical,
-                Children =
-                {
-                    new Control
-                    {
-                        Margin = new Thickness(2, 2, 0, 0),
-                        Children =
-                        {
-                            new Label
-                            {
-                                Text = Loc.GetString("particle-accelerator-control-menu-device-version-label"),
-                                FontOverride = font,
-                                FontColorOverride = StyleNano.NanoGold,
-                            },
-                            closeButton
-                        }
-                    },
-                    new PanelContainer
-                    {
-                        PanelOverride = new StyleBoxFlat {BackgroundColor = StyleNano.NanoGold},
-                        MinSize = new Vector2(0, 2),
-                    },
-                    new Control
-                    {
-                        MinSize = new Vector2(0, 4)
-                    },
-
-                    new BoxContainer
-                    {
-                        Orientation = LayoutOrientation.Horizontal,
-                        VerticalExpand = true,
-                        Children =
-                        {
-                            new BoxContainer
-                            {
-                                Orientation = LayoutOrientation.Vertical,
-                                Margin = new Thickness(4, 0, 0, 0),
-                                HorizontalExpand = true,
-                                Children =
-                                {
-                                    new BoxContainer
-                                    {
-                                        Orientation = LayoutOrientation.Horizontal,
-                                        Children =
-                                        {
-                                            new Label
-                                            {
-                                                Text = Loc.GetString("particle-accelerator-control-menu-power-label") + " ",
-                                                HorizontalExpand = true,
-                                                HorizontalAlignment = HAlignment.Left,
-                                            },
-                                            _offButton,
-                                            _onButton
-                                        }
-                                    },
-                                    new BoxContainer
-                                    {
-                                        Orientation = LayoutOrientation.Horizontal,
-                                        Children =
-                                        {
-                                            new Label
-                                            {
-                                                Text = Loc.GetString("particle-accelerator-control-menu-strength-label") + " ",
-                                                HorizontalExpand = true,
-                                                HorizontalAlignment = HAlignment.Left,
-                                            },
-                                            _stateSpinBox
-                                        }
-                                    },
-                                    new Control
-                                    {
-                                        MinSize = new Vector2(0, 10),
-                                    },
-                                    _drawLabel,
-                                    new Control
-                                    {
-                                        VerticalExpand = true,
-                                    },
-                                    (_alarmControl = new BoxContainer
-                                    {
-                                        Orientation = LayoutOrientation.Vertical,
-                                        Children =
-                                        {
-                                            new Label
-                                            {
-                                                Text = Loc.GetString("particle-accelerator-control-menu-alarm-control"),
-                                                FontColorOverride = Color.Red,
-                                                Align = Label.AlignMode.Center
-                                            },
-                                            serviceManual
-                                        },
-                                        Visible = false,
-                                    }),
-                                }
-                            },
-                            new BoxContainer
-                            {
-                                Orientation = LayoutOrientation.Vertical,
-                                MinSize = new Vector2(186, 0),
-                                Children =
-                                {
-                                    (_statusLabel = new Label
-                                    {
-                                        HorizontalAlignment = HAlignment.Center
-                                    }),
-                                    new Control
-                                    {
-                                        MinSize = new Vector2(0, 20)
-                                    },
-                                    new PanelContainer
-                                    {
-                                        HorizontalAlignment = HAlignment.Center,
-                                        PanelOverride = back2,
-                                        Children =
-                                        {
-                                            new GridContainer
-                                            {
-                                                Columns = 3,
-                                                VSeparationOverride = 0,
-                                                HSeparationOverride = 0,
-                                                Children =
-                                                {
-                                                    new Control {MinSize = imgSize},
-                                                    (_endCapTexture = Segment("end_cap")),
-                                                    new Control {MinSize = imgSize},
-                                                    (_controlBoxTexture = Segment("control_box")),
-                                                    (_fuelChamberTexture = Segment("fuel_chamber")),
-                                                    new Control {MinSize = imgSize},
-                                                    new Control {MinSize = imgSize},
-                                                    (_powerBoxTexture = Segment("power_box")),
-                                                    new Control {MinSize = imgSize},
-                                                    (_emitterStarboardTexture = Segment("emitter_starboard")),
-                                                    (_emitterForeTexture = Segment("emitter_fore")),
-                                                    (_emitterPortTexture = Segment("emitter_port")),
-                                                }
-                                            }
-                                        }
-                                    },
-                                    (_scanButton = new Button
-                                    {
-                                        Text = Loc.GetString("particle-accelerator-control-menu-scan-parts-button"),
-                                        HorizontalAlignment = HAlignment.Center
-                                    })
-                                }
-                            }
-                        }
-                    },
-                    new StripeBack
-                    {
-                        Children =
-                        {
-                            new Label
-                            {
-                                Margin = new Thickness(4, 4, 0, 4),
-                                Text = Loc.GetString("particle-accelerator-control-menu-check-containment-field-warning"),
-                                HorizontalAlignment = HAlignment.Center,
-                                StyleClasses = {StyleBase.StyleClassLabelSubText},
-                            }
-                        }
-                    },
-                    new BoxContainer
-                    {
-                        Orientation = LayoutOrientation.Horizontal,
-                        Margin = new Thickness(12, 0, 0, 0),
-                        Children =
-                        {
-                            new Label
-                            {
-                                Text = Loc.GetString("particle-accelerator-control-menu-foo-bar-baz"),
-                                StyleClasses = {StyleBase.StyleClassLabelSubText}
-                            }
-                        }
-                    },
-                }
-            });
-
-            _scanButton.OnPressed += args => OnScanPartsRequested?.Invoke();
-
-            _alarmControl.AnimationCompleted += s =>
-            {
-                if (_shouldContinueAnimating)
-                {
-                    _alarmControl.PlayAnimation(_alarmControlAnimation, "warningAnim");
-                }
-                else
-                {
-                    _alarmControl.Visible = false;
-                }
-            };
-
-            PASegmentControl Segment(string name)
-            {
-                return new(this, _cache, name);
-            }
-
-            UpdateUI(false, false, false, false);
-        }
-
-        private bool StrengthSpinBoxValid(int n)
-        {
-            return n >= 0 && n <= _maxStrength && !_blockSpinBox;
-        }
-
-        private void PowerStateChanged(ValueChangedEventArgs e)
-        {
-            ParticleAcceleratorPowerState newState;
-            switch (e.Value)
-            {
-                case 0:
-                    newState = ParticleAcceleratorPowerState.Standby;
-                    break;
-                case 1:
-                    newState = ParticleAcceleratorPowerState.Level0;
-                    break;
-                case 2:
-                    newState = ParticleAcceleratorPowerState.Level1;
-                    break;
-                case 3:
-                    newState = ParticleAcceleratorPowerState.Level2;
-                    break;
-                case 4:
-                    newState = ParticleAcceleratorPowerState.Level3;
-                    break;
-                default:
-                    return;
-            }
-
-            _stateSpinBox.SetButtonDisabled(true);
-            OnPowerState?.Invoke(newState);
-        }
-
-        protected override DragMode GetDragModeFor(Vector2 relativeMousePos)
-        {
-            return DragMode.Move;
-        }
-
-        public void DataUpdate(ParticleAcceleratorUIState uiState)
-        {
-            _assembled = uiState.Assembled;
-            UpdateUI(uiState.Assembled, uiState.InterfaceBlock, uiState.Enabled,
-                uiState.WirePowerBlock);
-            _statusLabel.Text = Loc.GetString("particle-accelerator-control-menu-status-label",
-                                              ("status", Loc.GetString(uiState.Assembled ? "particle-accelerator-control-menu-status-operational" :
-                                                                                           "particle-accelerator-control-menu-status-incomplete")));
-            UpdatePowerState(uiState.State, uiState.Enabled, uiState.Assembled,
-                uiState.MaxLevel);
-            UpdatePreview(uiState);
-            _lastDraw = uiState.PowerDraw;
-            _lastReceive = uiState.PowerReceive;
-        }
-
-        private void UpdatePowerState(ParticleAcceleratorPowerState state, bool enabled, bool assembled,
-            ParticleAcceleratorPowerState maxState)
-        {
-            _stateSpinBox.OverrideValue(state switch
-            {
-                ParticleAcceleratorPowerState.Standby => 0,
-                ParticleAcceleratorPowerState.Level0 => 1,
-                ParticleAcceleratorPowerState.Level1 => 2,
-                ParticleAcceleratorPowerState.Level2 => 3,
-                ParticleAcceleratorPowerState.Level3 => 4,
-                _ => 0
-            });
-
-
-            _maxStrength = maxState == ParticleAcceleratorPowerState.Level3 ? 4 : 3;
-            if (_maxStrength > 3 && enabled && assembled)
-            {
-                _shouldContinueAnimating = true;
-                if (!_alarmControl.HasRunningAnimation("warningAnim"))
-                    _alarmControl.PlayAnimation(_alarmControlAnimation, "warningAnim");
-            }
-            else
-                _shouldContinueAnimating = false;
-        }
-
-        private void UpdateUI(bool assembled, bool blocked, bool enabled, bool powerBlock)
-        {
-            _onButton.Pressed = enabled;
-            _offButton.Pressed = !enabled;
-
-            var cantUse = !assembled || blocked || powerBlock;
-            _onButton.Disabled = cantUse;
-            _offButton.Disabled = cantUse;
-            _scanButton.Disabled = blocked;
-
-            var cantChangeLevel = !assembled || blocked;
-            _stateSpinBox.SetButtonDisabled(cantChangeLevel);
-            _blockSpinBox = cantChangeLevel;
-        }
-
-        private void UpdatePreview(ParticleAcceleratorUIState updateMessage)
-        {
-            _endCapTexture.SetPowerState(updateMessage, updateMessage.EndCapExists);
-            _controlBoxTexture.SetPowerState(updateMessage, true);
-            _fuelChamberTexture.SetPowerState(updateMessage, updateMessage.FuelChamberExists);
-            _powerBoxTexture.SetPowerState(updateMessage, updateMessage.PowerBoxExists);
-            _emitterStarboardTexture.SetPowerState(updateMessage, updateMessage.EmitterStarboardExists);
-            _emitterForeTexture.SetPowerState(updateMessage, updateMessage.EmitterForeExists);
-            _emitterPortTexture.SetPowerState(updateMessage, updateMessage.EmitterPortExists);
-        }
-
-        protected override void FrameUpdate(FrameEventArgs args)
-        {
-            base.FrameUpdate(args);
-
-            if (!_assembled)
-            {
-                _drawLabel.Text = Loc.GetString("particle-accelerator-control-menu-draw-not-available");
-                return;
-            }
-
-            _time += args.DeltaSeconds;
-
-            var watts = 0;
-            if (_lastDraw != 0)
-            {
-                var val = _drawNoiseGenerator.GetNoise(_time, 0f);
-                watts = (int) (_lastDraw + val * 5);
-            }
-
-            _drawLabel.Text = Loc.GetString("particle-accelerator-control-menu-draw",
-                                            ("watts", $"{watts:##,##0}"),
-                                            ("lastReceive", $"{_lastReceive:##,##0}"));
-        }
-
-        private sealed class PASegmentControl : Control
-        {
-            private readonly ParticleAcceleratorControlMenu _menu;
-            private readonly string _baseState;
-            private readonly TextureRect _base;
-            private readonly TextureRect _unlit;
-            private readonly RSI _rsi;
-
-            public PASegmentControl(ParticleAcceleratorControlMenu menu, IResourceCache cache, string name)
-            {
-                _menu = menu;
-                _baseState = name;
-                _rsi = cache.GetResource<RSIResource>($"/Textures/Structures/Power/Generation/PA/{name}.rsi").RSI;
-
-                AddChild(_base = new TextureRect { Texture = _rsi[$"completed"].Frame0 });
-                AddChild(_unlit = new TextureRect());
-                MinSize = _rsi.Size;
-            }
-
-            public void SetPowerState(ParticleAcceleratorUIState state, bool exists)
-            {
-                _base.ShaderOverride = exists ? null : _menu._greyScaleShader;
-                _base.ModulateSelfOverride = exists ? null : new Color(127, 127, 127);
-
-                if (!state.Enabled || !exists)
-                {
-                    _unlit.Visible = false;
-                    return;
-                }
-
-                _unlit.Visible = true;
-
-                var suffix = state.State switch
-                {
-                    ParticleAcceleratorPowerState.Standby => "_unlitp",
-                    ParticleAcceleratorPowerState.Level0 => "_unlitp0",
-                    ParticleAcceleratorPowerState.Level1 => "_unlitp1",
-                    ParticleAcceleratorPowerState.Level2 => "_unlitp2",
-                    ParticleAcceleratorPowerState.Level3 => "_unlitp3",
-                    _ => ""
-                };
-
-                if (!_rsi.TryGetState(_baseState + suffix, out var rState))
-                {
-                    _unlit.Visible = false;
-                    return;
-                }
-
-                _unlit.Texture = rState.Frame0;
-            }
-        }
-    }
-}
diff --git a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.xaml b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.xaml
new file mode 100644 (file)
index 0000000..63f1583
--- /dev/null
@@ -0,0 +1,74 @@
+<controls:FancyWindow xmlns="https://spacestation14.io"
+            xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
+            xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
+            xmlns:ui="clr-namespace:Content.Client.ParticleAccelerator.UI"
+            xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
+            Title="{Loc 'particle-accelerator-control-menu-device-version-label'}"
+            MinSize="420 320"
+            SetSize="420 320">
+    <BoxContainer Orientation="Vertical" VerticalExpand="True" Margin="0 10 0 0">
+        <BoxContainer Orientation="Horizontal" VerticalExpand="True">
+            <BoxContainer Orientation="Vertical" HorizontalExpand="True" VerticalExpand="True" Margin="10 0 10 5">
+                <BoxContainer Orientation="Horizontal">
+                    <RichTextLabel Name="StatusLabel" HorizontalExpand="True"/>
+                    <RichTextLabel Name="StatusStateLabel"/>
+                </BoxContainer>
+                <Control MinHeight="5"/>
+                <BoxContainer Orientation="Horizontal">
+                    <RichTextLabel Name="PowerLabel" Margin="0 0 20 0" HorizontalExpand="True" VerticalAlignment="Center"/>
+                    <Button Name="OffButton" ToggleMode="False" Text="{Loc 'particle-accelerator-control-menu-off-button'}" StyleClasses="OpenRight"/>
+                    <Button Name="OnButton" ToggleMode="False" Text="{Loc 'particle-accelerator-control-menu-on-button'}" StyleClasses="OpenLeft"/>
+                </BoxContainer>
+                <Control MinHeight="5"/>
+                <BoxContainer Orientation="Horizontal">
+                    <RichTextLabel Name="StrengthLabel" Margin="0 0 20 0" HorizontalExpand="True" HorizontalAlignment="Left" VerticalAlignment="Center"/>
+                    <SpinBox Name="StateSpinBox" Value="0"/>
+                </BoxContainer>
+                <Control MinHeight="5"/>
+                <BoxContainer Orientation="Horizontal">
+                    <RichTextLabel Name="DrawLabel" HorizontalExpand="True"/>
+                    <RichTextLabel Name="DrawValueLabel"/>
+                </BoxContainer>
+                <Control MinHeight="10" VerticalExpand="True"/>
+                <BoxContainer Name="AlarmControl" Orientation="Vertical" VerticalAlignment="Center" Visible="False">
+                    <RichTextLabel Name="BigAlarmLabel" HorizontalAlignment="Center"/>
+                    <RichTextLabel Name="BigAlarmLabelTwo" HorizontalAlignment="Center"/>
+                    <Label Text="{Loc 'particle-accelerator-control-menu-service-manual-reference'}" HorizontalAlignment="Center" StyleClasses="LabelSubText"/>
+                </BoxContainer>
+                <Control MinHeight="10" VerticalExpand="True"/>
+            </BoxContainer>
+            <customControls:VSeparator Margin="0 0 0 10"/>
+            <BoxContainer Orientation="Vertical" Margin="20 0 20 0" VerticalAlignment="Center">
+                <PanelContainer Name="BackPanel" HorizontalAlignment="Center">
+                    <PanelContainer.PanelOverride>
+                        <gfx:StyleBoxTexture Modulate="#202023" PatchMarginBottom="10" PatchMarginLeft="10" PatchMarginRight="10" PatchMarginTop="10"/>
+                    </PanelContainer.PanelOverride>
+                    <BoxContainer Orientation="Vertical" HorizontalExpand="True" HorizontalAlignment="Center" VerticalExpand="True">
+                        <GridContainer Columns="3" VSeparationOverride="0" HSeparationOverride="0" HorizontalAlignment="Center">
+                            <Control/>
+                            <ui:PASegmentControl Name="EndCapTexture" BaseState="end_cap"/>
+                            <Control/>
+                            <ui:PASegmentControl Name="ControlBoxTexture" BaseState="control_box"/>
+                            <ui:PASegmentControl Name="FuelChamberTexture" BaseState="fuel_chamber"/>
+                            <Control/>
+                            <Control/>
+                            <ui:PASegmentControl Name="PowerBoxTexture" BaseState="power_box"/>
+                            <Control/>
+                            <ui:PASegmentControl Name="EmitterStarboardTexture" BaseState="emitter_starboard"/>
+                            <ui:PASegmentControl Name="EmitterForeTexture" BaseState="emitter_fore"/>
+                            <ui:PASegmentControl Name="EmitterPortTexture" BaseState="emitter_port"/>
+                        </GridContainer>
+                        <Control MinHeight="5"/>
+                        <Button Name="ScanButton" Text="{Loc 'particle-accelerator-control-menu-scan-parts-button'}" HorizontalAlignment="Center"/>
+                    </BoxContainer>
+                </PanelContainer>
+            </BoxContainer>
+        </BoxContainer>
+        <controls:StripeBack>
+            <Label Text="{Loc 'particle-accelerator-control-menu-check-containment-field-warning'}" HorizontalAlignment="Center" StyleClasses="LabelSubText" Margin="4 4 0 4"/>
+        </controls:StripeBack>
+        <BoxContainer Orientation="Horizontal" Margin="12 0 0 0">
+            <Label Text="{Loc 'particle-accelerator-control-menu-foo-bar-baz'}" StyleClasses="LabelSubText"/>
+        </BoxContainer>
+    </BoxContainer>
+</controls:FancyWindow>
diff --git a/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.xaml.cs b/Content.Client/ParticleAccelerator/UI/ParticleAcceleratorControlMenu.xaml.cs
new file mode 100644 (file)
index 0000000..9c2b51d
--- /dev/null
@@ -0,0 +1,311 @@
+using System.Numerics;
+using Content.Client.Message;
+using Content.Client.Resources;
+using Content.Client.UserInterface.Controls;
+using Content.Shared.Singularity.Components;
+using Robust.Client.Animations;
+using Robust.Client.AutoGenerated;
+using Robust.Client.Graphics;
+using Robust.Client.ResourceManagement;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.XAML;
+using Robust.Shared.Noise;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Timing;
+
+namespace Content.Client.ParticleAccelerator.UI;
+
+[GenerateTypedNameReferences]
+public sealed partial class ParticleAcceleratorControlMenu : FancyWindow
+{
+    [Dependency] private readonly IResourceCache _cache = default!;
+
+    private readonly FastNoiseLite _drawNoiseGenerator;
+
+    private readonly Animation _alarmControlAnimation;
+
+    private float _time;
+    private int _lastDraw;
+    private int _lastReceive;
+
+    private bool _assembled;
+    private bool _shouldContinueAnimating;
+    private int _maxStrength = 3;
+
+    public event Action<bool>? OnOverallState;
+    public event Action? OnScan;
+    public event Action<ParticleAcceleratorPowerState>? OnPowerState;
+
+    private EntityUid _entity;
+
+    public ParticleAcceleratorControlMenu()
+    {
+        RobustXamlLoader.Load(this);
+        IoCManager.InjectDependencies(this);
+
+        _drawNoiseGenerator = new();
+        _drawNoiseGenerator.SetFractalType(FastNoiseLite.FractalType.FBm);
+        _drawNoiseGenerator.SetFrequency(0.5f);
+
+        var panelTex = _cache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png");
+
+        MouseFilter = MouseFilterMode.Stop;
+
+        _alarmControlAnimation = new Animation
+        {
+            Length = TimeSpan.FromSeconds(1),
+            AnimationTracks =
+            {
+                new AnimationTrackControlProperty
+                {
+                    Property = nameof(Visible),
+                    KeyFrames =
+                    {
+                        new AnimationTrackProperty.KeyFrame(true, 0),
+                        new AnimationTrackProperty.KeyFrame(false, 0.75f),
+                    }
+                }
+            }
+        };
+
+        if (BackPanel.PanelOverride is StyleBoxTexture tex)
+            tex.Texture = panelTex;
+
+        StatusLabel.SetMarkup(Loc.GetString("particle-accelerator-control-menu-status-label"));
+        StatusStateLabel.SetMarkup(Loc.GetString("particle-accelerator-control-menu-status-unknown"));
+        PowerLabel.SetMarkup(Loc.GetString("particle-accelerator-control-menu-power-label"));
+        StrengthLabel.SetMarkup(Loc.GetString("particle-accelerator-control-menu-strength-label"));
+        BigAlarmLabel.SetMarkup(Loc.GetString("particle-accelerator-control-menu-alarm-control-1"));
+        BigAlarmLabelTwo.SetMarkup(Loc.GetString("particle-accelerator-control-menu-alarm-control-2"));
+        DrawLabel.SetMarkup(Loc.GetString("particle-accelerator-control-menu-draw"));
+
+        StateSpinBox.IsValid = StrengthSpinBoxValid;
+        StateSpinBox.InitDefaultButtons();
+        StateSpinBox.ValueChanged += PowerStateChanged;
+        StateSpinBox.LineEditDisabled = true;
+
+        OffButton.OnPressed += _ =>
+        {
+            OnOverallState?.Invoke(false);
+        };
+
+        OnButton.OnPressed += _ =>
+        {
+            OnOverallState?.Invoke(true);
+        };
+
+        ScanButton.OnPressed += _ =>
+        {
+            OnScan?.Invoke();
+        };
+
+        AlarmControl.AnimationCompleted += _ =>
+        {
+            if (_shouldContinueAnimating)
+            {
+                AlarmControl.PlayAnimation(_alarmControlAnimation, "warningAnim");
+            }
+            else
+            {
+                AlarmControl.Visible = false;
+            }
+        };
+
+        UpdateUI(false, false, false, false);
+    }
+
+    public void SetEntity(EntityUid uid)
+    {
+        _entity = uid;
+    }
+
+    private void PowerStateChanged(ValueChangedEventArgs e)
+    {
+        ParticleAcceleratorPowerState newState;
+        switch (e.Value)
+        {
+            case 0:
+                newState = ParticleAcceleratorPowerState.Standby;
+                break;
+            case 1:
+                newState = ParticleAcceleratorPowerState.Level0;
+                break;
+            case 2:
+                newState = ParticleAcceleratorPowerState.Level1;
+                break;
+            case 3:
+                newState = ParticleAcceleratorPowerState.Level2;
+                break;
+            case 4:
+                newState = ParticleAcceleratorPowerState.Level3;
+                break;
+            default:
+                return;
+        }
+
+        StateSpinBox.SetButtonDisabled(true);
+        OnPowerState?.Invoke(newState);
+    }
+
+    private bool StrengthSpinBoxValid(int n)
+    {
+        return n >= 0 && n <= _maxStrength ;
+    }
+
+    protected override DragMode GetDragModeFor(Vector2 relativeMousePos)
+    {
+        return DragMode.Move;
+    }
+
+    public void DataUpdate(ParticleAcceleratorUIState uiState)
+    {
+        _assembled = uiState.Assembled;
+        UpdateUI(uiState.Assembled,
+            uiState.InterfaceBlock,
+            uiState.Enabled,
+            uiState.WirePowerBlock);
+        StatusStateLabel.SetMarkup(Loc.GetString(uiState.Assembled
+            ? "particle-accelerator-control-menu-status-operational"
+            : "particle-accelerator-control-menu-status-incomplete"));
+        UpdatePowerState(uiState.State, uiState.Enabled, uiState.Assembled, uiState.MaxLevel);
+        UpdatePreview(uiState);
+        _lastDraw = uiState.PowerDraw;
+        _lastReceive = uiState.PowerReceive;
+    }
+
+    private void UpdatePowerState(ParticleAcceleratorPowerState state, bool enabled, bool assembled, ParticleAcceleratorPowerState maxState)
+    {
+        var value = state switch
+        {
+            ParticleAcceleratorPowerState.Standby => 0,
+            ParticleAcceleratorPowerState.Level0 => 1,
+            ParticleAcceleratorPowerState.Level1 => 2,
+            ParticleAcceleratorPowerState.Level2 => 3,
+            ParticleAcceleratorPowerState.Level3 => 4,
+            _ => 0
+        };
+
+        StateSpinBox.OverrideValue(value);
+
+        _maxStrength = maxState == ParticleAcceleratorPowerState.Level3 ? 4 : 3;
+        if (_maxStrength > 3 && enabled && assembled)
+        {
+            _shouldContinueAnimating = true;
+            if (!AlarmControl.HasRunningAnimation("warningAnim"))
+                AlarmControl.PlayAnimation(_alarmControlAnimation, "warningAnim");
+        }
+        else
+            _shouldContinueAnimating = false;
+    }
+
+    private void UpdateUI(bool assembled, bool blocked, bool enabled, bool powerBlock)
+    {
+        OnButton.Pressed = enabled;
+        OffButton.Pressed = !enabled;
+
+        var cantUse = !assembled || blocked || powerBlock;
+        OnButton.Disabled = cantUse;
+        OffButton.Disabled = cantUse;
+        ScanButton.Disabled = blocked;
+
+        var cantChangeLevel = !assembled || blocked || !enabled || cantUse;
+        StateSpinBox.SetButtonDisabled(cantChangeLevel);
+    }
+
+    private void UpdatePreview(ParticleAcceleratorUIState updateMessage)
+    {
+        EndCapTexture.SetPowerState(updateMessage, updateMessage.EndCapExists);
+        ControlBoxTexture.SetPowerState(updateMessage, true);
+        FuelChamberTexture.SetPowerState(updateMessage, updateMessage.FuelChamberExists);
+        PowerBoxTexture.SetPowerState(updateMessage, updateMessage.PowerBoxExists);
+        EmitterStarboardTexture.SetPowerState(updateMessage, updateMessage.EmitterStarboardExists);
+        EmitterForeTexture.SetPowerState(updateMessage, updateMessage.EmitterForeExists);
+        EmitterPortTexture.SetPowerState(updateMessage, updateMessage.EmitterPortExists);
+    }
+
+    protected override void FrameUpdate(FrameEventArgs args)
+    {
+        base.FrameUpdate(args);
+
+        if (!_assembled)
+        {
+            DrawValueLabel.SetMarkup(Loc.GetString("particle-accelerator-control-menu-draw-not-available"));
+            return;
+        }
+
+        _time += args.DeltaSeconds;
+
+        var watts = 0;
+        if (_lastDraw != 0)
+        {
+            var val = _drawNoiseGenerator.GetNoise(_time, 0f);
+            watts = (int) (_lastDraw + val * 5);
+        }
+
+        DrawValueLabel.SetMarkup(Loc.GetString("particle-accelerator-control-menu-draw-value",
+            ("watts", $"{watts:##,##0}"),
+            ("lastReceive", $"{_lastReceive:##,##0}")));
+    }
+}
+
+public sealed class PASegmentControl : Control
+{
+    private readonly ShaderInstance _greyScaleShader;
+    private readonly TextureRect _base;
+    private readonly TextureRect _unlit;
+    private RSI? _rsi;
+
+    public string BaseState { get; set; } = "control_box";
+
+    public PASegmentControl()
+    {
+        _greyScaleShader = IoCManager.Resolve<IPrototypeManager>().Index<ShaderPrototype>("Greyscale").Instance();
+
+        AddChild(_base = new TextureRect());
+        AddChild(_unlit = new TextureRect());
+    }
+
+    protected override void EnteredTree()
+    {
+        base.EnteredTree();
+        _rsi = IoCManager.Resolve<IResourceCache>().GetResource<RSIResource>($"/Textures/Structures/Power/Generation/PA/{BaseState}.rsi").RSI;
+        MinSize = _rsi.Size;
+        _base.Texture = _rsi["completed"].Frame0;
+    }
+
+    public void SetPowerState(ParticleAcceleratorUIState state, bool exists)
+    {
+        _base.ShaderOverride = exists ? null : _greyScaleShader;
+        _base.ModulateSelfOverride = exists ? null : new Color(127, 127, 127);
+
+        if (!state.Enabled || !exists)
+        {
+            _unlit.Visible = false;
+            return;
+        }
+
+        _unlit.Visible = true;
+
+        var suffix = state.State switch
+        {
+            ParticleAcceleratorPowerState.Standby => "_unlitp",
+            ParticleAcceleratorPowerState.Level0 => "_unlitp0",
+            ParticleAcceleratorPowerState.Level1 => "_unlitp1",
+            ParticleAcceleratorPowerState.Level2 => "_unlitp2",
+            ParticleAcceleratorPowerState.Level3 => "_unlitp3",
+            _ => ""
+        };
+
+        if (_rsi == null)
+            return;
+
+        if (!_rsi.TryGetState(BaseState + suffix, out var rState))
+        {
+            _unlit.Visible = false;
+            return;
+        }
+
+        _unlit.Texture = rState.Frame0;
+    }
+}
index 05ab81c0f59d0228d1bbfcd06ab1620c707e9ea8..7697644a3bce5f70d2915e14333cabab803cb993 100644 (file)
@@ -1,13 +1,12 @@
-using Content.Shared.Singularity.Components;
+using Robust.Shared.Prototypes;
 
 namespace Content.Server.ParticleAccelerator.Components;
 
 [RegisterComponent]
 public sealed partial class ParticleAcceleratorEmitterComponent : Component
 {
-    [DataField("emittedPrototype")]
-    [ViewVariables(VVAccess.ReadWrite)]
-    public string EmittedPrototype = "ParticlesProjectile";
+    [DataField]
+    public EntProtoId EmittedPrototype = "ParticlesProjectile";
 
     [DataField("emitterType")]
     [ViewVariables(VVAccess.ReadWrite)]
index 80f398c0a79e65a33974503aa87044b7e68142ce..4d39a5ce305c01b7ebe8e4410099aa210ed29562 100644 (file)
@@ -101,6 +101,7 @@ public sealed partial class ParticleAcceleratorSystem
             _adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(player):player} has turned {ToPrettyString(uid)} off");
 
         comp.Enabled = false;
+        SetStrength(uid, ParticleAcceleratorPowerState.Standby, user, comp);
         UpdatePowerDraw(uid, comp);
         PowerOff(uid, comp);
         UpdateUI(uid, comp);
@@ -174,12 +175,14 @@ public sealed partial class ParticleAcceleratorSystem
                 var pos = Transform(uid);
                 if (_timing.CurTime > comp.EffectCooldown)
                 {
-                    _chat.SendAdminAlert(player, Loc.GetString("particle-accelerator-admin-power-strength-warning",
+                    _chat.SendAdminAlert(player,
+                        Loc.GetString("particle-accelerator-admin-power-strength-warning",
                         ("machine", ToPrettyString(uid)),
-                        ("powerState", strength),
+                        ("powerState", GetPANumericalLevel(strength)),
                         ("coordinates", pos.Coordinates)));
                     _audio.PlayGlobal("/Audio/Misc/adminlarm.ogg",
-                        Filter.Empty().AddPlayers(_adminManager.ActiveAdmins), false,
+                        Filter.Empty().AddPlayers(_adminManager.ActiveAdmins),
+                        false,
                         AudioParams.Default.WithVolume(-8f));
                     comp.EffectCooldown = _timing.CurTime + comp.CooldownDuration;
                 }
@@ -230,7 +233,7 @@ public sealed partial class ParticleAcceleratorSystem
         powerConsumer.DrawRate = powerDraw;
     }
 
-    private void UpdateUI(EntityUid uid, ParticleAcceleratorControlBoxComponent? comp = null)
+    public void UpdateUI(EntityUid uid, ParticleAcceleratorControlBoxComponent? comp = null)
     {
         if (!Resolve(uid, ref comp))
             return;
@@ -247,7 +250,9 @@ public sealed partial class ParticleAcceleratorSystem
             receive = powerConsumer.ReceivedPower;
         }
 
-        _uiSystem.SetUiState(uid, ParticleAcceleratorControlBoxUiKey.Key, new ParticleAcceleratorUIState(
+        _uiSystem.SetUiState(uid,
+            ParticleAcceleratorControlBoxUiKey.Key,
+            new ParticleAcceleratorUIState(
             comp.Assembled,
             comp.Enabled,
             comp.SelectedStrength,
@@ -396,4 +401,16 @@ public sealed partial class ParticleAcceleratorSystem
 
         UpdateUI(uid, comp);
     }
+
+    public static int GetPANumericalLevel(ParticleAcceleratorPowerState state)
+    {
+        return state switch
+        {
+            ParticleAcceleratorPowerState.Level0 => 1,
+            ParticleAcceleratorPowerState.Level1 => 2,
+            ParticleAcceleratorPowerState.Level2 => 3,
+            ParticleAcceleratorPowerState.Level3 => 4,
+            _ => 0
+        };
+    }
 }
index 99bb0d5cbdafc376c5c70b4e9182b78f4219b627..829de0af47076e19da13dff4527bd70df95b8d15 100644 (file)
@@ -1,10 +1,8 @@
 using System.Diagnostics.CodeAnalysis;
-using System.Numerics;
 using Content.Server.ParticleAccelerator.Components;
 using JetBrains.Annotations;
 using Robust.Shared.Map.Components;
 using Robust.Shared.Physics.Events;
-using Robust.Shared.Player;
 
 namespace Content.Server.ParticleAccelerator.EntitySystems;
 
@@ -26,8 +24,6 @@ public sealed partial class ParticleAcceleratorSystem
         if (controller.CurrentlyRescanning)
             return;
 
-        SwitchOff(uid, user, controller);
-
         var partQuery = GetEntityQuery<ParticleAcceleratorPartComponent>();
         foreach (var part in AllParts(uid, controller))
         {
@@ -45,19 +41,25 @@ public sealed partial class ParticleAcceleratorSystem
 
         var xformQuery = GetEntityQuery<TransformComponent>();
         if (!xformQuery.TryGetComponent(uid, out var xform) || !xform.Anchored)
+        {
+            SwitchOff(uid, user, controller);
             return;
+        }
 
         var gridUid = xform.GridUid;
         if (gridUid == null || gridUid != xform.ParentUid || !TryComp<MapGridComponent>(gridUid, out var grid))
+        {
+            SwitchOff(uid, user, controller);
             return;
+        }
 
         // Find fuel chamber first by scanning cardinals.
         var fuelQuery = GetEntityQuery<ParticleAcceleratorFuelChamberComponent>();
         foreach (var adjacent in _mapSystem.GetCardinalNeighborCells(gridUid.Value, grid, xform.Coordinates))
         {
             if (fuelQuery.HasComponent(adjacent)
-            && partQuery.TryGetComponent(adjacent, out var partState)
-            && partState.Master == null)
+                && partQuery.TryGetComponent(adjacent, out var partState)
+                && partState.Master == null)
             {
                 controller.FuelChamber = adjacent;
                 break;
@@ -66,7 +68,7 @@ public sealed partial class ParticleAcceleratorSystem
 
         if (controller.FuelChamber == null)
         {
-            UpdateUI(uid, controller);
+            SwitchOff(uid, user, controller);
             return;
         }
 
@@ -93,19 +95,19 @@ public sealed partial class ParticleAcceleratorSystem
         var positionForeEmitter = positionFuelChamber + offsetVect * 2;
         var positionStarboardEmitter = positionFuelChamber + offsetVect * 2 - orthoOffsetVect;
 
-        ScanPart<ParticleAcceleratorEndCapComponent>(gridUid!.Value, positionEndCap, rotation, out controller.EndCap, out var _, grid);
-        ScanPart<ParticleAcceleratorPowerBoxComponent>(gridUid!.Value, positionPowerBox, rotation, out controller.PowerBox, out var _, grid);
+        ScanPart<ParticleAcceleratorEndCapComponent>(gridUid.Value, positionEndCap, rotation, out controller.EndCap, out _, grid);
+        ScanPart<ParticleAcceleratorPowerBoxComponent>(gridUid.Value, positionPowerBox, rotation, out controller.PowerBox, out _, grid);
 
-        if (!ScanPart<ParticleAcceleratorEmitterComponent>(gridUid!.Value, positionPortEmitter, rotation, out controller.PortEmitter, out var portEmitter, grid)
-        || portEmitter!.Type != ParticleAcceleratorEmitterType.Port)
+        if (!ScanPart<ParticleAcceleratorEmitterComponent>(gridUid.Value, positionPortEmitter, rotation, out controller.PortEmitter, out var portEmitter, grid)
+        || portEmitter.Type != ParticleAcceleratorEmitterType.Port)
             controller.PortEmitter = null;
 
-        if (!ScanPart<ParticleAcceleratorEmitterComponent>(gridUid!.Value, positionForeEmitter, rotation, out controller.ForeEmitter, out var foreEmitter, grid)
-        || foreEmitter!.Type != ParticleAcceleratorEmitterType.Fore)
+        if (!ScanPart<ParticleAcceleratorEmitterComponent>(gridUid.Value, positionForeEmitter, rotation, out controller.ForeEmitter, out var foreEmitter, grid)
+        || foreEmitter.Type != ParticleAcceleratorEmitterType.Fore)
             controller.ForeEmitter = null;
 
-        if (!ScanPart<ParticleAcceleratorEmitterComponent>(gridUid!.Value, positionStarboardEmitter, rotation, out controller.StarboardEmitter, out var starboardEmitter, grid)
-        || starboardEmitter!.Type != ParticleAcceleratorEmitterType.Starboard)
+        if (!ScanPart<ParticleAcceleratorEmitterComponent>(gridUid.Value, positionStarboardEmitter, rotation, out controller.StarboardEmitter, out var starboardEmitter, grid)
+        || starboardEmitter.Type != ParticleAcceleratorEmitterType.Starboard)
             controller.StarboardEmitter = null;
 
         controller.Assembled =
@@ -157,19 +159,19 @@ public sealed partial class ParticleAcceleratorSystem
 
     private void OnComponentShutdown(EntityUid uid, ParticleAcceleratorPartComponent comp, ComponentShutdown args)
     {
-        if (EntityManager.EntityExists(comp.Master))
+        if (Exists(comp.Master))
             RescanParts(comp.Master!.Value);
     }
 
     private void BodyTypeChanged(EntityUid uid, ParticleAcceleratorPartComponent comp, ref PhysicsBodyTypeChangedEvent args)
     {
-        if (EntityManager.EntityExists(comp.Master))
+        if (Exists(comp.Master))
             RescanParts(comp.Master!.Value);
     }
 
     private void OnMoveEvent(EntityUid uid, ParticleAcceleratorPartComponent comp, ref MoveEvent args)
     {
-        if (EntityManager.EntityExists(comp.Master))
+        if (Exists(comp.Master))
             RescanParts(comp.Master!.Value);
     }
 }
index 4e70854d6b4dda70243f98aeef09f2cf107f85ce..688571d9f5a9f540a9dab4addf415bbb88957f74 100644 (file)
@@ -1,4 +1,5 @@
 using Content.Server.ParticleAccelerator.Components;
+using Content.Server.ParticleAccelerator.EntitySystems;
 using Content.Server.Wires;
 using Content.Shared.Singularity.Components;
 using Content.Shared.Wires;
@@ -19,12 +20,16 @@ public sealed partial class ParticleAcceleratorKeyboardWireAction : ComponentWir
     public override bool Cut(EntityUid user, Wire wire, ParticleAcceleratorControlBoxComponent controller)
     {
         controller.InterfaceDisabled = true;
+        var paSystem = EntityManager.System<ParticleAcceleratorSystem>();
+        paSystem.UpdateUI(wire.Owner, controller);
         return true;
     }
 
     public override bool Mend(EntityUid user, Wire wire, ParticleAcceleratorControlBoxComponent controller)
     {
         controller.InterfaceDisabled = false;
+        var paSystem = EntityManager.System<ParticleAcceleratorSystem>();
+        paSystem.UpdateUI(wire.Owner, controller);
         return true;
     }
 
index 0645944a2ac01bd23d06932792722e5b95e03804..33c8761a832a68e9ddb7f497242928e4e8e1f4fd 100644 (file)
@@ -5,7 +5,6 @@ using Content.Server.Wires;
 using Content.Shared.Popups;
 using Content.Shared.Singularity.Components;
 using Content.Shared.Wires;
-using Robust.Shared.Player;
 
 namespace Content.Server.ParticleAccelerator.Wires;
 
@@ -35,6 +34,8 @@ public sealed partial class ParticleAcceleratorLimiterWireAction : ComponentWire
     public override bool Cut(EntityUid user, Wire wire, ParticleAcceleratorControlBoxComponent controller)
     {
         controller.MaxStrength = ParticleAcceleratorPowerState.Level3;
+        var paSystem = EntityManager.System<ParticleAcceleratorSystem>();
+        paSystem.UpdateUI(wire.Owner, controller);
         return true;
     }
 
@@ -49,12 +50,14 @@ public sealed partial class ParticleAcceleratorLimiterWireAction : ComponentWire
         // Since that blocks SetStrength().
         var paSystem = EntityManager.System<ParticleAcceleratorSystem>();
         paSystem.SetStrength(wire.Owner, controller.MaxStrength, user, controller);
+        paSystem.UpdateUI(wire.Owner, controller);
         return true;
     }
 
     public override void Pulse(EntityUid user, Wire wire, ParticleAcceleratorControlBoxComponent controller)
     {
-        EntityManager.System<PopupSystem>().PopupEntity(
+        EntityManager.System<PopupSystem>()
+            .PopupEntity(
             Loc.GetString("particle-accelerator-control-box-component-wires-update-limiter-on-pulse"),
             user,
             PopupType.SmallCaution
index 1650960bd3133a097023cf1b1259b3867e1beb61..15a425f4c267bb568ef7675686b58395972364b5 100644 (file)
@@ -21,12 +21,16 @@ public sealed partial class ParticleAcceleratorStrengthWireAction : ComponentWir
     public override bool Cut(EntityUid user, Wire wire, ParticleAcceleratorControlBoxComponent controller)
     {
         controller.StrengthLocked = true;
+        var paSystem = EntityManager.System<ParticleAcceleratorSystem>();
+        paSystem.UpdateUI(wire.Owner, controller);
         return true;
     }
 
     public override bool Mend(EntityUid user, Wire wire, ParticleAcceleratorControlBoxComponent controller)
     {
         controller.StrengthLocked = false;
+        var paSystem = EntityManager.System<ParticleAcceleratorSystem>();
+        paSystem.UpdateUI(wire.Owner, controller);
         return true;
     }
 
index 6bc3ec50684a5ac49c3b99580aa63f1a49777a1f..da3221e4f85e40f05098222bf75cf641f32b82f8 100644 (file)
@@ -2,15 +2,21 @@ particle-accelerator-control-menu-on-button = On
 particle-accelerator-control-menu-off-button = Off
 particle-accelerator-control-menu-service-manual-reference = Refer to p.132 of service manual
 particle-accelerator-control-menu-device-version-label = Mark 2 Particle Accelerator
-particle-accelerator-control-menu-power-label = Power:
-particle-accelerator-control-menu-strength-label = Strength:
-particle-accelerator-control-menu-alarm-control = PARTICLE STRENGTH
-                                                  LIMITER FAILURE
+particle-accelerator-control-menu-power-label = [bold]Power:[/bold]
+particle-accelerator-control-menu-strength-label = [bold]Strength:[/bold]
+particle-accelerator-control-menu-alarm-control-1 = [bold][color=red]PARTICLE STRENGTH[/bold][/color]
+particle-accelerator-control-menu-alarm-control-2 = [bold][color=red]LIMITER FAILURE[/bold][/color]
 particle-accelerator-control-menu-scan-parts-button = Scan Parts
 particle-accelerator-control-menu-check-containment-field-warning = Ensure containment field is active before operation
 particle-accelerator-control-menu-foo-bar-baz = FOO-BAR-BAZ
-particle-accelerator-control-menu-status-label = Status: {$status}
-particle-accelerator-control-menu-status-operational = Operational
-particle-accelerator-control-menu-status-incomplete = Incomplete
-particle-accelerator-control-menu-draw-not-available = Draw: N/A
-particle-accelerator-control-menu-draw = Draw: {$watts}/{$lastReceive} 
\ No newline at end of file
+particle-accelerator-control-menu-status-label = [bold]Status:[/bold]
+particle-accelerator-control-menu-status-unknown = [font="Monospace"][color=red]Unknown[/color][/bold]
+particle-accelerator-control-menu-status-operational = [font="Monospace"][color=green]Operational[/color][/bold]
+particle-accelerator-control-menu-status-incomplete = [font="Monospace"][color=red]Incomplete[/color][/bold]
+particle-accelerator-control-menu-draw = [bold]Draw:[/bold]
+particle-accelerator-control-menu-draw-value = [font="Monospace"]{$watts}/{$lastReceive}[/font]
+particle-accelerator-control-menu-draw-not-available = [font="Monospace"][color=gray]N/A[/color][/font]
+
+particle-accelerator-radio-message-on = PA power has been switched on.
+particle-accelerator-radio-message-off = PA power has been switched off.
+particle-accelerator-radio-message-num = PA strength has been set to level {$level}.
index 45134518715dadcb1ae62811adb67907c365e707..a83b3f9e095dfb518e7245fe95739f746a76c530 100644 (file)
Binary files a/Resources/Textures/Structures/Power/Generation/PA/control_box.rsi/unlitp0.png and b/Resources/Textures/Structures/Power/Generation/PA/control_box.rsi/unlitp0.png differ
index 21f121314de16bf12e3b1770ef9f541b18f7db00..8902a538953786a1941833b854036eb5abc3a599 100644 (file)
Binary files a/Resources/Textures/Structures/Power/Generation/PA/control_box.rsi/unlitp1.png and b/Resources/Textures/Structures/Power/Generation/PA/control_box.rsi/unlitp1.png differ
index 4002ea9fb60d8fd4656e844ad1cd2e79d94c0208..f579920985fda2eec3cab2a5ee5d11b4716ab6fd 100644 (file)
Binary files a/Resources/Textures/Structures/Power/Generation/PA/control_box.rsi/unlitp2.png and b/Resources/Textures/Structures/Power/Generation/PA/control_box.rsi/unlitp2.png differ
index 63d8adc2c79d62ab45d7ef684b32e057e01a9604..129f9388f7dbc0e99f303a5b06c001a840874caa 100644 (file)
Binary files a/Resources/Textures/Structures/Power/Generation/PA/control_box.rsi/unlitp3.png and b/Resources/Textures/Structures/Power/Generation/PA/control_box.rsi/unlitp3.png differ