]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Selectable Bar Signs (#29068)
authorNemanja <98561806+EmoGarbage404@users.noreply.github.com>
Sun, 30 Jun 2024 16:20:57 +0000 (12:20 -0400)
committerGitHub <noreply@github.com>
Sun, 30 Jun 2024 16:20:57 +0000 (02:20 +1000)
* make bar sign selectable

* ajcm strongest soldier

* AJCM comes down hard for round 2

* good shit

* ok ballin

* bless'ed be the webedit

Content.Client/BarSign/BarSignSystem.cs
Content.Client/BarSign/Ui/BarSignBoundUserInterface.cs [new file with mode: 0644]
Content.Client/BarSign/Ui/BarSignMenu.xaml [new file with mode: 0644]
Content.Client/BarSign/Ui/BarSignMenu.xaml.cs [new file with mode: 0644]
Content.Server/BarSign/Systems/BarSignSystem.cs [deleted file]
Content.Shared/BarSign/BarSignComponent.cs
Content.Shared/BarSign/BarSignPrototype.cs
Content.Shared/BarSign/BarSignSystem.cs [new file with mode: 0644]
Resources/Locale/en-US/barsign/barsign-component.ftl
Resources/Prototypes/Entities/Structures/Wallmounts/Signs/bar_sign.yml
Resources/Prototypes/bar_signs.yml

index 05db00d819484b77314dad7970f26936dfabce05..9fd8ba2e4b4f9c75914427e46aae7ce445f3104c 100644 (file)
@@ -1,3 +1,4 @@
+using Content.Client.BarSign.Ui;
 using Content.Shared.BarSign;
 using Content.Shared.Power;
 using Robust.Client.GameObjects;
@@ -8,6 +9,7 @@ namespace Content.Client.BarSign;
 public sealed class BarSignSystem : VisualizerSystem<BarSignComponent>
 {
     [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
+    [Dependency] private readonly UserInterfaceSystem _ui = default!;
 
     public override void Initialize()
     {
@@ -17,6 +19,9 @@ public sealed class BarSignSystem : VisualizerSystem<BarSignComponent>
 
     private void OnAfterAutoHandleState(EntityUid uid, BarSignComponent component, ref AfterAutoHandleStateEvent args)
     {
+        if (_ui.TryGetOpenUi<BarSignBoundUserInterface>(uid, BarSignUiKey.Key, out var bui))
+            bui.Update(component.Current);
+
         UpdateAppearance(uid, component);
     }
 
@@ -34,9 +39,9 @@ public sealed class BarSignSystem : VisualizerSystem<BarSignComponent>
 
         if (powered
             && sign.Current != null
-            && _prototypeManager.TryIndex(sign.Current, out BarSignPrototype? proto))
+            && _prototypeManager.TryIndex(sign.Current, out var proto))
         {
-            sprite.LayerSetState(0, proto.Icon);
+            sprite.LayerSetSprite(0, proto.Icon);
             sprite.LayerSetShader(0, "unshaded");
         }
         else
diff --git a/Content.Client/BarSign/Ui/BarSignBoundUserInterface.cs b/Content.Client/BarSign/Ui/BarSignBoundUserInterface.cs
new file mode 100644 (file)
index 0000000..1d1280b
--- /dev/null
@@ -0,0 +1,50 @@
+using System.Linq;
+using Content.Shared.BarSign;
+using JetBrains.Annotations;
+using Robust.Shared.Prototypes;
+
+namespace Content.Client.BarSign.Ui;
+
+[UsedImplicitly]
+public sealed class BarSignBoundUserInterface(EntityUid owner, Enum uiKey) : BoundUserInterface(owner, uiKey)
+{
+    [Dependency] private readonly IPrototypeManager _prototype = default!;
+
+    private BarSignMenu? _menu;
+
+    protected override void Open()
+    {
+        base.Open();
+
+        var sign = EntMan.GetComponentOrNull<BarSignComponent>(Owner)?.Current is { } current
+            ? _prototype.Index(current)
+            : null;
+        var allSigns = Shared.BarSign.BarSignSystem.GetAllBarSigns(_prototype)
+            .OrderBy(p => Loc.GetString(p.Name))
+            .ToList();
+        _menu = new(sign, allSigns);
+
+        _menu.OnSignSelected += id =>
+        {
+            SendMessage(new SetBarSignMessage(id));
+        };
+
+        _menu.OnClose += Close;
+        _menu.OpenCentered();
+    }
+
+    public void Update(ProtoId<BarSignPrototype>? sign)
+    {
+        if (_prototype.TryIndex(sign, out var signPrototype))
+            _menu?.UpdateState(signPrototype);
+    }
+
+    protected override void Dispose(bool disposing)
+    {
+        base.Dispose(disposing);
+        if (!disposing)
+            return;
+        _menu?.Dispose();
+    }
+}
+
diff --git a/Content.Client/BarSign/Ui/BarSignMenu.xaml b/Content.Client/BarSign/Ui/BarSignMenu.xaml
new file mode 100644 (file)
index 0000000..5b1155a
--- /dev/null
@@ -0,0 +1,19 @@
+<controls:FancyWindow
+    xmlns="https://spacestation14.io"
+    xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
+    xmlns:customControls="clr-namespace:Content.Client.Administration.UI.CustomControls"
+    Title="{Loc 'barsign-ui-menu'}"
+    MinSize="280 180"
+    SetSize="280 180">
+    <BoxContainer VerticalExpand="True" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="10 5 10 10">
+        <BoxContainer Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
+            <BoxContainer Orientation="Vertical" HorizontalAlignment="Center">
+                <Label Text="{Loc 'barsign-ui-set-label'}" HorizontalAlignment="Center" StyleClasses="LabelSubText" Margin="30 0"/>
+                <customControls:HSeparator Margin="0 0 0 5"/>
+            </BoxContainer>
+            <OptionButton Name="SignOptions" HorizontalAlignment="Center" VerticalAlignment="Center" MinSize="175 60" Margin="0 0 0 20"/>
+        </BoxContainer>
+    </BoxContainer>
+</controls:FancyWindow>
+
+
diff --git a/Content.Client/BarSign/Ui/BarSignMenu.xaml.cs b/Content.Client/BarSign/Ui/BarSignMenu.xaml.cs
new file mode 100644 (file)
index 0000000..a933333
--- /dev/null
@@ -0,0 +1,50 @@
+using Content.Client.UserInterface.Controls;
+using Content.Shared.BarSign;
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.XAML;
+
+namespace Content.Client.BarSign.Ui;
+
+[GenerateTypedNameReferences]
+public sealed partial class BarSignMenu : FancyWindow
+{
+    private string? _currentId;
+
+    private readonly List<BarSignPrototype> _cachedPrototypes = new();
+
+    public event Action<string>? OnSignSelected;
+
+    public BarSignMenu(BarSignPrototype? currentSign, List<BarSignPrototype> signs)
+    {
+        RobustXamlLoader.Load(this);
+        _currentId = currentSign?.ID;
+
+        _cachedPrototypes.Clear();
+        _cachedPrototypes = signs;
+        foreach (var proto in _cachedPrototypes)
+        {
+            SignOptions.AddItem(Loc.GetString(proto.Name));
+        }
+
+        SignOptions.OnItemSelected += idx =>
+        {
+            OnSignSelected?.Invoke(_cachedPrototypes[idx.Id].ID);
+            SignOptions.SelectId(idx.Id);
+        };
+
+        if (currentSign != null)
+        {
+            var idx = _cachedPrototypes.IndexOf(currentSign);
+            SignOptions.TrySelectId(idx);
+        }
+    }
+
+    public void UpdateState(BarSignPrototype newSign)
+    {
+        if (_currentId != null && newSign.ID == _currentId)
+            return;
+        _currentId = newSign.ID;
+        var idx = _cachedPrototypes.IndexOf(newSign);
+        SignOptions.TrySelectId(idx);
+    }
+}
diff --git a/Content.Server/BarSign/Systems/BarSignSystem.cs b/Content.Server/BarSign/Systems/BarSignSystem.cs
deleted file mode 100644 (file)
index e42394f..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-using System.Linq;
-using Content.Shared.BarSign;
-using Robust.Shared.Prototypes;
-using Robust.Shared.Random;
-
-namespace Content.Server.BarSign.Systems
-{
-    public sealed class BarSignSystem : EntitySystem
-    {
-        [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
-        [Dependency] private readonly IRobustRandom _random = default!;
-        [Dependency] private readonly MetaDataSystem _metaData = default!;
-
-        public override void Initialize()
-        {
-            SubscribeLocalEvent<BarSignComponent, MapInitEvent>(OnMapInit);
-        }
-
-        private void OnMapInit(EntityUid uid, BarSignComponent component, MapInitEvent args)
-        {
-            if (component.Current != null)
-                return;
-
-            var prototypes = _prototypeManager
-                .EnumeratePrototypes<BarSignPrototype>()
-                .Where(p => !p.Hidden)
-                .ToList();
-
-            var newPrototype = _random.Pick(prototypes);
-
-            var meta = Comp<MetaDataComponent>(uid);
-            var name = newPrototype.Name != string.Empty ? newPrototype.Name : "barsign-component-name";
-            _metaData.SetEntityName(uid, Loc.GetString(name), meta);
-            _metaData.SetEntityDescription(uid, Loc.GetString(newPrototype.Description), meta);
-
-            component.Current = newPrototype.ID;
-            Dirty(uid, component);
-        }
-    }
-}
index d50726216e611b5d9dea80d078f4ca55c747c1e2..98c6e815cc823290f9a5ee40bebbbeabd7c4eb94 100644 (file)
@@ -1,10 +1,27 @@
 using Robust.Shared.GameStates;
 using Robust.Shared.Prototypes;
+using Robust.Shared.Serialization;
 
 namespace Content.Shared.BarSign;
 
 [RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true)]
 public sealed partial class BarSignComponent : Component
 {
-    [DataField, AutoNetworkedField] public ProtoId<BarSignPrototype>? Current;
+    /// <summary>
+    /// The current bar sign prototype being displayed.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public ProtoId<BarSignPrototype>? Current;
+}
+
+[Serializable, NetSerializable]
+public enum BarSignUiKey : byte
+{
+    Key
+}
+
+[Serializable, NetSerializable]
+public sealed class SetBarSignMessage(ProtoId<BarSignPrototype> sign) : BoundUserInterfaceMessage
+{
+    public ProtoId<BarSignPrototype> Sign = sign;
 }
index a0566d9f4647dbd270bad02f833e58ff5b08a977..d63ebda4a79cf55480fe93c9d0b8ea8b62d07da7 100644 (file)
@@ -1,23 +1,23 @@
 using Robust.Shared.Prototypes;
+using Robust.Shared.Utility;
 
-namespace Content.Shared.BarSign
+namespace Content.Shared.BarSign;
+
+[Prototype]
+public sealed partial class BarSignPrototype : IPrototype
 {
-    [Prototype("barSign")]
-    public sealed partial class BarSignPrototype : IPrototype
-    {
-        [ViewVariables]
-        [IdDataField]
-        public string ID { get; private set; } = default!;
+    [IdDataField, ViewVariables]
+    public string ID { get; private set; } = default!;
 
+    [DataField(required: true)]
+    public SpriteSpecifier Icon { get; private set; } = default!;
 
-        [DataField("icon")] public string Icon { get; private set; } = string.Empty;
+    [DataField]
+    public LocId Name { get; private set; } = "barsign-component-name";
 
-        [DataField("name")] public string Name { get; set; } = "";
-        [DataField("description")] public string Description { get; set; } = "";
+    [DataField]
+    public LocId Description { get; private set; }
 
-        [DataField("renameArea")]
-        public bool RenameArea { get; private set; } = true;
-        [DataField("hidden")]
-        public bool Hidden { get; private set; }
-    }
+    [DataField]
+    public bool Hidden { get; private set; }
 }
diff --git a/Content.Shared/BarSign/BarSignSystem.cs b/Content.Shared/BarSign/BarSignSystem.cs
new file mode 100644 (file)
index 0000000..bf28cfe
--- /dev/null
@@ -0,0 +1,58 @@
+using System.Linq;
+using Robust.Shared.Prototypes;
+using Robust.Shared.Random;
+
+namespace Content.Shared.BarSign;
+
+public sealed class BarSignSystem : EntitySystem
+{
+    [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
+    [Dependency] private readonly IRobustRandom _random = default!;
+    [Dependency] private readonly MetaDataSystem _metaData = default!;
+
+    public override void Initialize()
+    {
+        SubscribeLocalEvent<BarSignComponent, MapInitEvent>(OnMapInit);
+        Subs.BuiEvents<BarSignComponent>(BarSignUiKey.Key,
+            subs =>
+        {
+            subs.Event<SetBarSignMessage>(OnSetBarSignMessage);
+        });
+    }
+
+    private void OnMapInit(Entity<BarSignComponent> ent, ref MapInitEvent args)
+    {
+        if (ent.Comp.Current != null)
+            return;
+
+        var newPrototype = _random.Pick(GetAllBarSigns(_prototypeManager));
+        SetBarSign(ent, newPrototype);
+    }
+
+    private void OnSetBarSignMessage(Entity<BarSignComponent> ent, ref SetBarSignMessage args)
+    {
+        if (!_prototypeManager.TryIndex(args.Sign, out var signPrototype))
+            return;
+
+        SetBarSign(ent, signPrototype);
+    }
+
+    public void SetBarSign(Entity<BarSignComponent> ent, BarSignPrototype newPrototype)
+    {
+        var meta = MetaData(ent);
+        var name = Loc.GetString(newPrototype.Name);
+        _metaData.SetEntityName(ent, name, meta);
+        _metaData.SetEntityDescription(ent, Loc.GetString(newPrototype.Description), meta);
+
+        ent.Comp.Current = newPrototype.ID;
+        Dirty(ent);
+    }
+
+    public static List<BarSignPrototype> GetAllBarSigns(IPrototypeManager prototypeManager)
+    {
+        return prototypeManager
+            .EnumeratePrototypes<BarSignPrototype>()
+            .Where(p => !p.Hidden)
+            .ToList();
+    }
+}
index 3451d70bc9b307f675f87c0f4fd4dad5284bcc9a..cf7ddd1e246a3b8b536457fb2af64250ea1087a8 100644 (file)
@@ -1,4 +1,6 @@
 barsign-component-name = bar sign
+barsign-ui-menu = Bar Sign Configuration
+barsign-ui-set-label = Set Sign:
 
 # Bar signs prototypes
 
index 8e957abfe7f4184ba1d7e67d7dbab0fd427e0598..b2a0ffe592a06a6fe199874a2be3d0974711527f 100644 (file)
@@ -9,6 +9,7 @@
       Brute:
         collection: GlassSmash
   - type: WallMount
+    arc: 360
   - type: Sprite
     drawdepth: Objects
     sprite: Structures/Wallmounts/barsign.rsi
   - type: ApcPowerReceiver
   - type: ExtensionCableReceiver
   - type: BarSign
+  - type: InteractionOutline
+  - type: AccessReader
+    access: [["Bar"]]
+  - type: ActivatableUIRequiresPower
+  - type: ActivatableUIRequiresAccess
+  - type: ActivatableUI
+    key: enum.BarSignUiKey.Key
+  - type: UserInterface
+    interfaces:
+      enum.BarSignUiKey.Key:
+        type: BarSignBoundUserInterface
   - type: Appearance
   - type: Destructible
     thresholds:
index 8c6476831b079235241e00d00cf2c1f6249f8ad8..e3f9d30a42d8d8ab83f8d55aa04849980b1b93f0 100644 (file)
 - type: barSign
   id: Harmbaton
   name: barsign-prototype-name-harmbaton
-  icon: "theharmbaton"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: theharmbaton
   description: barsign-prototype-description-harmbaton
 
 - type: barSign
   id: TheSingulo
   name: barsign-prototype-name-singulo
-  icon: "thesingulo"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: thesingulo
   description: barsign-prototype-description-singulo
 
 - type: barSign
   id: TheDrunkCarp
   name: barsign-prototype-name-drunk-carp
-  icon: "thedrunkcarp"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: thedrunkcarp
   description: barsign-prototype-description-drunk-carp
 
 - type: barSign
   id: OfficerBeersky
   name: barsign-prototype-name-officer-beersky
-  icon: "officerbeersky"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: officerbeersky
   description: barsign-prototype-description-officer-beersky
 
 - type: barSign
   id: TheOuterSpess
   name: barsign-prototype-name-outer-spess
-  icon: "theouterspess"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: theouterspess
   description: barsign-prototype-description-outer-spess
 
 - type: barSign
   id: TheCoderbus
   name: barsign-prototype-name-coderbus
-  icon: "thecoderbus"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: thecoderbus
   description: barsign-prototype-description-coderbus
 
 - type: barSign
   id: RobustaCafe
   name: barsign-prototype-name-robusta-cafe
-  icon: "robustacafe"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: robustacafe
   description: barsign-prototype-description-robusta-cafe
 
 - type: barSign
   id: EmergencyRumParty
   name: barsign-prototype-name-emergency-rum-party
-  icon: "emergencyrumparty"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: emergencyrumparty
   description: barsign-prototype-description-emergency-rum-party
 
 - type: barSign
   id: ComboCafe
   name: barsign-prototype-name-combo-cafe
-  icon: "combocafe"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: combocafe
   description: barsign-prototype-description-combo-cafe
 
 - type: barSign
   id: TheAleNath
   name: barsign-prototype-name-ale-nath
-  icon: "thealenath"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: thealenath
   description: barsign-prototype-description-ale-nath
 
 - type: barSign
   id: TheNet
   name: barsign-prototype-name-the-net
-  icon: "thenet"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: thenet
   description: barsign-prototype-description-the-net
 
 - type: barSign
   id: MaidCafe
   name: barsign-prototype-name-maid-cafe
-  icon: "maidcafe"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: maidcafe
   description: barsign-prototype-description-maid-cafe
 
 - type: barSign
   id: MalteseFalcon
   name: barsign-prototype-name-maltese-falcon
-  icon: "maltesefalcon"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: maltesefalcon
   description: barsign-prototype-description-maltese-falcon
 
 - type: barSign
   id: TheSun
   name: barsign-prototype-name-the-sun
-  icon: "thesun"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: thesun
   description: barsign-prototype-description-the-sun
 
 - type: barSign
   id: TheBirdCage
   name: barsign-prototype-name-the-birdcage
-  icon: "birdcage"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: birdcage
   description: barsign-prototype-description-the-birdcage
 
 - type: barSign
   id: Zocalo
   name: barsign-prototype-name-zocalo
-  icon: "zocalo"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: zocalo
   description: barsign-prototype-description-zocalo
 
 - type: barSign
   id: LV426
   name: barsign-prototype-name-lv426
-  icon: "lv426"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: lv426
   description: barsign-prototype-description-lv426
 
 - type: barSign
   id: WiggleRoom
   name: barsign-prototype-name-wiggle-room
-  icon: "thewiggleroom"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: thewiggleroom
   description: barsign-prototype-description-wiggle-room
 
 - type: barSign
   id: TheLightbulb
   name: barsign-prototype-name-the-lightbulb
-  icon: "the_lightbulb"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: the_lightbulb
   description: barsign-prototype-description-the-lightbulb
 
 - type: barSign
   id: Goose
   name: barsign-prototype-name-goose
-  icon: "goose"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: goose
   description: barsign-prototype-description-goose
 
 - type: barSign
   id: EngineChange
   name: barsign-prototype-name-enginechange
-  icon: "enginechange"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: enginechange
   description: barsign-prototype-description-enginechange
 
 - type: barSign
   id: Emprah
   name: barsign-prototype-name-emprah
-  icon: "emprah"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: emprah
   description: barsign-prototype-description-emprah
 
 - type: barSign
   id: Spacebucks
   name: barsign-prototype-name-spacebucks
-  icon: "spacebucks"
+  icon:
+    sprite: Structures/Wallmounts/barsign.rsi
+    state: spacebucks
   description: barsign-prototype-description-spacebucks
-
-# Hidden signs list below this point
-- type: barSign
-  id: EmpBarSign
-  name: ""
-  icon: "empbarsign"
-  description: barsign-prototype-description-empbarsign
-  renameArea: false
-  hidden: true
-
-- type: barSign
-  id: SignOff
-  name: ""
-  icon: "empty"
-  description: barsign-prototype-description-sign-off
-  renameArea: false
-  hidden: true