]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Station beacons (#23136)
authorNemanja <98561806+EmoGarbage404@users.noreply.github.com>
Fri, 29 Dec 2023 00:02:21 +0000 (19:02 -0500)
committerGitHub <noreply@github.com>
Fri, 29 Dec 2023 00:02:21 +0000 (17:02 -0700)
* Station beacons

* crate

* remove navmap from warp points

* ack

* oh damn

* okay emisser

18 files changed:
Content.Client/Pinpointer/UI/NavMapBeaconBoundUserInterface.cs [new file with mode: 0644]
Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml [new file with mode: 0644]
Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml.cs [new file with mode: 0644]
Content.Server/Pinpointer/NavMapSystem.cs
Content.Shared/Pinpointer/ConfigurableNavMapBeaconComponent.cs [new file with mode: 0644]
Content.Shared/Pinpointer/NavMapBeaconComponent.cs
Resources/Locale/en-US/pinpointer/station_map.ftl
Resources/Locale/en-US/prototypes/catalog/fills/crates/engineering-crates.ftl
Resources/Prototypes/Catalog/Cargo/cargo_engineering.yml
Resources/Prototypes/Catalog/Fills/Crates/engineering.yml
Resources/Prototypes/Entities/Markers/warp_point.yml
Resources/Prototypes/Entities/Objects/Devices/station_beacon.yml [new file with mode: 0644]
Resources/Prototypes/Recipes/Construction/Graphs/structures/station_beacon.yml [new file with mode: 0644]
Resources/Textures/Objects/Devices/station_beacon.rsi/assembly.png [new file with mode: 0644]
Resources/Textures/Objects/Devices/station_beacon.rsi/blink.png [new file with mode: 0644]
Resources/Textures/Objects/Devices/station_beacon.rsi/icon.png [new file with mode: 0644]
Resources/Textures/Objects/Devices/station_beacon.rsi/meta.json [new file with mode: 0644]
Resources/migration.yml

diff --git a/Content.Client/Pinpointer/UI/NavMapBeaconBoundUserInterface.cs b/Content.Client/Pinpointer/UI/NavMapBeaconBoundUserInterface.cs
new file mode 100644 (file)
index 0000000..0573d1a
--- /dev/null
@@ -0,0 +1,35 @@
+using Content.Shared.Pinpointer;
+using JetBrains.Annotations;
+
+namespace Content.Client.Pinpointer.UI;
+
+[UsedImplicitly]
+public sealed class NavMapBeaconBoundUserInterface : BoundUserInterface
+{
+    [ViewVariables]
+    private NavMapBeaconWindow? _window;
+
+    public NavMapBeaconBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
+    {
+    }
+
+    protected override void Open()
+    {
+        base.Open();
+
+        _window = new NavMapBeaconWindow(Owner);
+        _window.OpenCentered();
+        _window.OnClose += Close;
+
+        _window.OnApplyButtonPressed += (label, enabled, color) =>
+        {
+            SendMessage(new NavMapBeaconConfigureBuiMessage(label, enabled, color));
+        };
+    }
+
+    protected override void Dispose(bool disposing)
+    {
+        base.Dispose(disposing);
+        _window?.Dispose();
+    }
+}
diff --git a/Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml b/Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml
new file mode 100644 (file)
index 0000000..88c3506
--- /dev/null
@@ -0,0 +1,17 @@
+<controls:FancyWindow xmlns="https://spacestation14.io"
+                      xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls"
+                      Title="{Loc 'nav-beacon-window-title'}"
+                      MinSize="250 230"
+                      SetSize="320 230">
+    <BoxContainer Orientation="Vertical" Margin="5">
+        <BoxContainer Orientation="Horizontal">
+            <Label Text="{Loc 'nav-beacon-text-label'}" Margin="0 0 5 0"/>
+            <LineEdit Name="LabelLineEdit" HorizontalExpand="True"/>
+            <Button Name="VisibleButton" ToggleMode="True" Text="{Loc 'nav-beacon-toggle-visible'}" Margin="10 0 0 0" MinWidth="100"/>
+        </BoxContainer>
+        <ColorSelectorSliders Name="ColorSelector" Margin="0 5 0 10"/>
+        <BoxContainer HorizontalAlignment="Right" VerticalAlignment="Bottom" VerticalExpand="True">
+        <Button Name="ApplyButton" Text="{Loc 'nav-beacon-button-apply'}" HorizontalAlignment="Right"/>
+        </BoxContainer>
+    </BoxContainer>
+</controls:FancyWindow>
diff --git a/Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml.cs b/Content.Client/Pinpointer/UI/NavMapBeaconWindow.xaml.cs
new file mode 100644 (file)
index 0000000..968fe18
--- /dev/null
@@ -0,0 +1,78 @@
+using Content.Client.UserInterface.Controls;
+using Content.Shared.Pinpointer;
+using Content.Shared.Preferences;
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.XAML;
+
+namespace Content.Client.Pinpointer.UI;
+
+[GenerateTypedNameReferences]
+public sealed partial class NavMapBeaconWindow : FancyWindow
+{
+    [Dependency] private readonly IEntityManager _entityManager = default!;
+
+    private string? _defaultLabel;
+    private bool _defaultEnabled;
+    private Color _defaultColor;
+
+    public event Action<string?, bool, Color>? OnApplyButtonPressed;
+
+    public NavMapBeaconWindow(EntityUid beaconEntity)
+    {
+        RobustXamlLoader.Load(this);
+        IoCManager.InjectDependencies(this);
+
+        if (!_entityManager.TryGetComponent<NavMapBeaconComponent>(beaconEntity, out var navMap))
+            return;
+        _defaultLabel = navMap.Text;
+        _defaultEnabled = navMap.Enabled;
+        _defaultColor = navMap.Color;
+
+        UpdateVisibleButton(navMap.Enabled);
+        VisibleButton.OnPressed += args => UpdateVisibleButton(args.Button.Pressed);
+
+        LabelLineEdit.Text = navMap.Text ?? string.Empty;
+        LabelLineEdit.OnTextChanged += OnTextChanged;
+
+        ColorSelector.Color = navMap.Color;
+        ColorSelector.OnColorChanged += _ => TryEnableApplyButton();
+
+        TryEnableApplyButton();
+        ApplyButton.OnPressed += OnApplyPressed;
+    }
+
+    private void UpdateVisibleButton(bool value)
+    {
+        VisibleButton.Pressed = value;
+        VisibleButton.Text = Loc.GetString(value
+            ? "nav-beacon-toggle-visible"
+            : "nav-beacon-toggle-invisible");
+
+        TryEnableApplyButton();
+    }
+
+    private void OnTextChanged(LineEdit.LineEditEventArgs obj)
+    {
+        if (obj.Text.Length > HumanoidCharacterProfile.MaxNameLength)
+            obj.Control.Text = obj.Text.Substring(0, HumanoidCharacterProfile.MaxNameLength);
+
+        TryEnableApplyButton();
+    }
+
+    private void TryEnableApplyButton()
+    {
+        ApplyButton.Disabled = LabelLineEdit.Text == (_defaultLabel ?? string.Empty) &&
+                               VisibleButton.Pressed == _defaultEnabled &&
+                               ColorSelector.Color == _defaultColor;
+    }
+
+    private void OnApplyPressed(BaseButton.ButtonEventArgs obj)
+    {
+        _defaultLabel = LabelLineEdit.Text == string.Empty ? null : LabelLineEdit.Text;
+        _defaultEnabled = VisibleButton.Pressed;
+        _defaultColor = ColorSelector.Color;
+        OnApplyButtonPressed?.Invoke(_defaultLabel, _defaultEnabled, _defaultColor);
+        TryEnableApplyButton();
+    }
+}
index a97e664d02880ed8bf6a6942d4755e4be4e1e9be..bdf2b6409a292e1d12f21f41cb33583a7ee98f32 100644 (file)
@@ -1,5 +1,8 @@
+using Content.Server.Administration.Logs;
 using Content.Server.Station.Systems;
 using Content.Server.Warps;
+using Content.Shared.Database;
+using Content.Shared.Examine;
 using Content.Shared.Pinpointer;
 using Content.Shared.Tag;
 using Robust.Shared.GameStates;
@@ -14,6 +17,8 @@ namespace Content.Server.Pinpointer;
 /// </summary>
 public sealed class NavMapSystem : SharedNavMapSystem
 {
+    [Dependency] private readonly IAdminLogManager _adminLog = default!;
+    [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
     [Dependency] private readonly TagSystem _tags = default!;
 
     private EntityQuery<PhysicsComponent> _physicsQuery;
@@ -35,6 +40,10 @@ public sealed class NavMapSystem : SharedNavMapSystem
 
         SubscribeLocalEvent<NavMapBeaconComponent, ComponentStartup>(OnNavMapBeaconStartup);
         SubscribeLocalEvent<NavMapBeaconComponent, AnchorStateChangedEvent>(OnNavMapBeaconAnchor);
+
+        SubscribeLocalEvent<ConfigurableNavMapBeaconComponent, NavMapBeaconConfigureBuiMessage>(OnConfigureMessage);
+        SubscribeLocalEvent<ConfigurableNavMapBeaconComponent, MapInitEvent>(OnConfigurableMapInit);
+        SubscribeLocalEvent<ConfigurableNavMapBeaconComponent, ExaminedEvent>(OnConfigurableExamined);
     }
 
     private void OnStationInit(StationGridAddedEvent ev)
@@ -50,9 +59,69 @@ public sealed class NavMapSystem : SharedNavMapSystem
 
     private void OnNavMapBeaconAnchor(EntityUid uid, NavMapBeaconComponent component, ref AnchorStateChangedEvent args)
     {
+        UpdateBeaconEnabledVisuals((uid, component));
         RefreshNavGrid(uid);
     }
 
+    private void OnConfigureMessage(Entity<ConfigurableNavMapBeaconComponent> ent, ref NavMapBeaconConfigureBuiMessage args)
+    {
+        if (args.Session.AttachedEntity is not { } user)
+            return;
+
+        if (!TryComp<NavMapBeaconComponent>(ent, out var navMap))
+            return;
+
+        if (navMap.Text == args.Text &&
+            navMap.Color == args.Color &&
+            navMap.Enabled == args.Enabled)
+            return;
+
+        _adminLog.Add(LogType.Action, LogImpact.Medium,
+            $"{ToPrettyString(user):player} configured NavMapBeacon \'{ToPrettyString(ent):entity}\' with text \'{args.Text}\', color {args.Color.ToHexNoAlpha()}, and {(args.Enabled ? "enabled" : "disabled")} it.");
+
+        if (TryComp<WarpPointComponent>(ent, out var warpPoint))
+        {
+            warpPoint.Location = args.Text;
+        }
+
+        navMap.Text = args.Text;
+        navMap.Color = args.Color;
+        navMap.Enabled = args.Enabled;
+        UpdateBeaconEnabledVisuals((ent, navMap));
+        Dirty(ent, navMap);
+        RefreshNavGrid(ent);
+    }
+
+    private void OnConfigurableMapInit(Entity<ConfigurableNavMapBeaconComponent> ent, ref MapInitEvent args)
+    {
+        if (!TryComp<NavMapBeaconComponent>(ent, out var navMap))
+            return;
+
+        // We set this on mapinit just in case the text was edited via VV or something.
+        if (TryComp<WarpPointComponent>(ent, out var warpPoint))
+        {
+            warpPoint.Location = navMap.Text;
+        }
+
+        UpdateBeaconEnabledVisuals((ent, navMap));
+    }
+
+    private void OnConfigurableExamined(Entity<ConfigurableNavMapBeaconComponent> ent, ref ExaminedEvent args)
+    {
+        if (!args.IsInDetailsRange || !TryComp<NavMapBeaconComponent>(ent, out var navMap))
+            return;
+
+        args.PushMarkup(Loc.GetString("nav-beacon-examine-text",
+            ("enabled", navMap.Enabled),
+            ("color", navMap.Color.ToHexNoAlpha()),
+            ("label", navMap.Text ?? string.Empty)));
+    }
+
+    private void UpdateBeaconEnabledVisuals(Entity<NavMapBeaconComponent> ent)
+    {
+        _appearance.SetData(ent, NavMapBeaconVisuals.Enabled, ent.Comp.Enabled && Transform(ent).Anchored);
+    }
+
     /// <summary>
     /// Refreshes the grid for the corresponding beacon.
     /// </summary>
@@ -61,7 +130,7 @@ public sealed class NavMapSystem : SharedNavMapSystem
     {
         var xform = Transform(uid);
 
-        if (!CanBeacon(uid, xform) || !TryComp<NavMapComponent>(xform.GridUid, out var navMap))
+        if (!TryComp<NavMapComponent>(xform.GridUid, out var navMap))
             return;
 
         Dirty(xform.GridUid.Value, navMap);
@@ -244,6 +313,8 @@ public sealed class NavMapSystem : SharedNavMapSystem
             return;
 
         comp.Enabled = enabled;
+        UpdateBeaconEnabledVisuals((uid, comp));
+        Dirty(uid, comp);
 
         RefreshNavGrid(uid);
     }
diff --git a/Content.Shared/Pinpointer/ConfigurableNavMapBeaconComponent.cs b/Content.Shared/Pinpointer/ConfigurableNavMapBeaconComponent.cs
new file mode 100644 (file)
index 0000000..cd6744c
--- /dev/null
@@ -0,0 +1,41 @@
+using Robust.Shared.GameStates;
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Pinpointer;
+
+/// <summary>
+/// This is used for a <see cref="NavMapBeaconComponent"/> that can be configured with a UI.
+/// </summary>
+[RegisterComponent, NetworkedComponent]
+[Access(typeof(SharedNavMapSystem))]
+public sealed partial class ConfigurableNavMapBeaconComponent : Component
+{
+
+}
+
+[Serializable, NetSerializable]
+public sealed class NavMapBeaconConfigureBuiMessage : BoundUserInterfaceMessage
+{
+    public string? Text;
+    public bool Enabled;
+    public Color Color;
+
+    public NavMapBeaconConfigureBuiMessage(string? text, bool enabled, Color color)
+    {
+        Text = text;
+        Enabled = enabled;
+        Color = color;
+    }
+}
+
+[Serializable, NetSerializable]
+public enum NavMapBeaconUiKey : byte
+{
+    Key
+}
+
+[Serializable, NetSerializable]
+public enum NavMapBeaconVisuals : byte
+{
+    Enabled
+}
index 2415f92f581c157dc615ea7ecfc1b31ca6e29d3f..c3132ee37f3ac19bf164d62e9372efb0ef5d61d9 100644 (file)
@@ -1,23 +1,29 @@
+using Robust.Shared.GameStates;
+
 namespace Content.Shared.Pinpointer;
 
 /// <summary>
 /// Will show a marker on a NavMap.
 /// </summary>
-[RegisterComponent, Access(typeof(SharedNavMapSystem))]
+[RegisterComponent, NetworkedComponent, Access(typeof(SharedNavMapSystem))]
+[AutoGenerateComponentState]
 public sealed partial class NavMapBeaconComponent : Component
 {
     /// <summary>
     /// Defaults to entity name if nothing found.
     /// </summary>
     [ViewVariables(VVAccess.ReadWrite), DataField]
+    [AutoNetworkedField]
     public string? Text;
 
     [ViewVariables(VVAccess.ReadWrite), DataField]
+    [AutoNetworkedField]
     public Color Color = Color.Orange;
 
     /// <summary>
     /// Only enabled beacons can be seen on a station map.
     /// </summary>
     [ViewVariables(VVAccess.ReadWrite), DataField]
+    [AutoNetworkedField]
     public bool Enabled = true;
 }
index d8172eb7297c26b2e9fac17edb5d805207137e2a..bd20a65fac89019313e3b3592f7ce0e67edc312c 100644 (file)
@@ -1 +1,11 @@
-station-map-window-title = Station map
\ No newline at end of file
+station-map-window-title = Station map
+
+nav-beacon-window-title = Station Beacon
+nav-beacon-toggle-visible = Visible
+nav-beacon-toggle-invisible = Invisible
+nav-beacon-text-label = Label:
+nav-beacon-button-apply = Apply
+nav-beacon-examine-text = It is [color={$enabled ->
+    [true] forestgreen]on
+    *[false] crimson]off
+}[/color] and the display reads [color={$color}]"{$label}"[/color]
index 61bcd424a2bdbf3c6ac5777fe3bc6c0718438854..49bb0ecab42352ed191d454f07c066a0a5c1ff9c 100644 (file)
@@ -22,6 +22,9 @@ ent-CrateEngineeringCableBulk = Bulk cable crate
 ent-CrateEngineeringElectricalSupplies = Electrical Supplies Crate
     .desc = NT is not responsible for any workplace infighting relating to the insulated gloves included within these crates.
 
+ent-CrateEngineeringStationBeaconBundle = Station Beacon Bundle
+    .desc = A crate containing 5 station beacon assemblies for modifying the station map.
+
 ent-CrateEngineeringJetpack = Jetpack crate
     .desc = Two jetpacks for those who don't know how to use fire extinguishers.
 
index 5a801e50ab0000b3743b560c40279ace78a46524..9644dc261cf70c86a41e5993d9a31e3a4c87edad 100644 (file)
   category: Engineering
   group: market
 
+- type: cargoProduct
+  id: StationBeaconBundle
+  icon:
+    sprite: Objects/Devices/station_beacon.rsi
+    state: icon
+  product: CrateEngineeringStationBeaconBundle
+  cost: 500
+  category: Engineering
+  group: market
+
 - type: cargoProduct
   id: EngineeringJetpack
   icon:
index c0982e035b0b3c0dfea7336777c070a8a7c36c58..e33e191300b703ef2b56aab7f6a3c4b1d088b0a6 100644 (file)
       - id: ClothingHandsGlovesColorYellow
         amount: 2
 
+- type: entity
+  id: CrateEngineeringStationBeaconBundle
+  parent: CratePlastic
+  components:
+  - type: StorageFill
+    contents:
+    - id: StationBeaconPart
+      amount: 5
+
 - type: entity
   id: CrateEngineeringJetpack
   parent: CrateGenericSteel
index da109f6212bba15f7282d356edef31847e6c8461..2536fde47458f49416b319d7f1894b61d2d3265e 100644 (file)
     - state: pink
     - sprite: Objects/Weapons/Bombs/spidercharge.rsi
       state: icon
-
-# Departments
-- type: entity
-  id: WarpPointBeaconBar
-  parent: WarpPointBeacon
-  name: warp point (bar)
-  components:
-  - type: NavMapBeacon
-    text: bar
-    color: "#791500"
-  - type: WarpPoint
-    location: bar
-
-- type: entity
-  id: WarpPointBeaconCargo
-  parent: WarpPointBeacon
-  name: warp point (cargo)
-  components:
-  - type: NavMapBeacon
-    text: cargo
-    color: "#A46106"
-  - type: WarpPoint
-    location: cargo
-
-- type: entity
-  id: WarpPointBeaconCommand
-  parent: WarpPointBeacon
-  name: warp point (command)
-  components:
-  - type: NavMapBeacon
-    text: command
-    color: "#334E6D"
-  - type: WarpPoint
-    location: command
-
-- type: entity
-  id: WarpPointBeaconEngineering
-  parent: WarpPointBeacon
-  name: warp point (engineering)
-  components:
-  - type: NavMapBeacon
-    text: engineering
-    color: "#EFB341"
-  - type: WarpPoint
-    location: engineering
-
-- type: entity
-  id: WarpPointBeaconMedical
-  parent: WarpPointBeacon
-  name: warp point (medical)
-  components:
-  - type: NavMapBeacon
-    text: medical
-    color: "#52B4E9"
-  - type: WarpPoint
-    location: medical
-
-- type: entity
-  id: WarpPointBeaconNeutral
-  parent: WarpPointBeacon
-  name: warp point (neutral)
-  components:
-  - type: NavMapBeacon
-    text: neutral
-    color: "#D4D4D4"
-  - type: WarpPoint
-    location: neutral
-
-- type: entity
-  id: WarpPointBeaconScience
-  parent: WarpPointBeacon
-  name: warp point (science)
-  components:
-  - type: NavMapBeacon
-    text: science
-    color: "#D381C9"
-  - type: WarpPoint
-    location: science
-
-- type: entity
-  id: WarpPointBeaconSecurity
-  parent: WarpPointBeacon
-  name: warp point (security)
-  components:
-  - type: NavMapBeacon
-    text: security
-    color: "#DE3A3A"
-  - type: WarpPoint
-    location: security
-
-- type: entity
-  id: WarpPointBeaconService
-  parent: WarpPointBeacon
-  name: warp point (service)
-  components:
-  - type: NavMapBeacon
-    text: service
-    color: "#9FED58"
-  - type: WarpPoint
-    location: service
diff --git a/Resources/Prototypes/Entities/Objects/Devices/station_beacon.yml b/Resources/Prototypes/Entities/Objects/Devices/station_beacon.yml
new file mode 100644 (file)
index 0000000..1c2517b
--- /dev/null
@@ -0,0 +1,553 @@
+- type: entity
+  parent: BaseItem
+  id: DefaultStationBeacon
+  name: station beacon
+  description: A small device that transmits information to station maps. Can be configured.
+  placement:
+    mode: SnapgridCenter
+  suffix: General
+  components:
+  - type: Sprite
+    sprite: Objects/Devices/station_beacon.rsi
+    drawdepth: BelowFloor
+    layers:
+    - state: blink
+      map: ["base"]
+  - type: Appearance
+  - type: GenericVisualizer
+    visuals:
+      enum.NavMapBeaconVisuals.Enabled:
+        base:
+          True: {state: blink}
+          False: {state: icon}
+  - type: ConfigurableNavMapBeacon
+  - type: NavMapBeacon
+    text: general
+    color: "#D4D4D496"
+  - type: WarpPoint
+  - type: ActivatableUI
+    key: enum.NavMapBeaconUiKey.Key
+    singleUser: true
+  - type: UserInterface
+    interfaces:
+    - key: enum.NavMapBeaconUiKey.Key
+      type: NavMapBeaconBoundUserInterface
+  - type: Item
+    size: Small
+  - type: SubFloorHide
+  - type: Anchorable
+  - type: Construction
+    graph: StationBeaconPart
+    node: complete
+  - type: CollideOnAnchor
+  - type: Physics
+    canCollide: false
+    bodyType: static
+  - type: Transform
+    anchored: true
+  - type: Damageable
+    damageContainer: Inorganic
+    damageModifierSet: Metallic
+  - type: Destructible
+    thresholds:
+    - trigger: # for nukes
+        !type:DamageTrigger
+        damage: 200
+      behaviors:
+        - !type:DoActsBehavior
+          acts: ["Destruction"]
+    - trigger:
+        !type:DamageTrigger
+        damage: 100
+      behaviors:
+        - !type:PlaySoundBehavior
+          sound:
+            path: /Audio/Effects/metalbreak.ogg
+            params:
+              volume: -8
+        - !type:SpawnEntitiesBehavior
+          spawn:
+            SheetSteel1:
+              min: 1
+              max: 1
+          offset: 0
+        - !type:DoActsBehavior
+          acts: ["Breakage"]
+  - type: StaticPrice
+    price: 25
+
+- type: entity
+  parent: DefaultStationBeacon
+  id: DefaultStationBeaconUnanchored
+  suffix: General, Unanchored
+  placement:
+    mode: PlaceFree
+  components:
+  - type: Sprite
+    sprite: Objects/Devices/station_beacon.rsi
+    layers:
+    - state: icon
+      map: ["base"]
+  - type: Physics
+    canCollide: true
+    bodyType: dynamic
+  - type: Transform
+    anchored: false
+
+- type: entity
+  parent: BaseItem
+  id: StationBeaconPart
+  name: station beacon assembly
+  description: A flatpack used for constructing a station beacon.
+  components:
+  - type: Item
+    size: Small
+    sprite: Objects/Devices/station_beacon.rsi
+  - type: Sprite
+    sprite: Objects/Devices/station_beacon.rsi
+    state: assembly
+  - type: Construction
+    graph: StationBeaconPart
+    node: start
+    defaultTarget: complete
+
+# Prototypes for various default beacon configurations.
+- type: entity
+  parent: DefaultStationBeacon
+  id: DefaultStationBeaconCommand
+  suffix: Command
+  components:
+  - type: NavMapBeacon
+    text: command
+    color: "#334E6D"
+
+- type: entity
+  parent: DefaultStationBeaconCommand
+  id: DefaultStationBeaconBridge
+  suffix: Bridge
+  components:
+  - type: NavMapBeacon
+    text: bridge
+
+- type: entity
+  parent: DefaultStationBeaconCommand
+  id: DefaultStationBeaconVault
+  suffix: Vault
+  components:
+  - type: NavMapBeacon
+    text: vault
+
+- type: entity
+  parent: DefaultStationBeaconCommand
+  id: DefaultStationBeaconCaptainsQuarters
+  suffix: Captain's Quarters
+  components:
+  - type: NavMapBeacon
+    text: captain's quarters
+
+- type: entity
+  parent: DefaultStationBeaconCommand
+  id: DefaultStationBeaconHOPOffice
+  suffix: HOP's Office
+  components:
+  - type: NavMapBeacon
+    text: head of personnel’s office
+
+- type: entity
+  parent: DefaultStationBeacon
+  id: DefaultStationBeaconSecurity
+  suffix: Security
+  components:
+  - type: NavMapBeacon
+    text: security
+    color: "#DE3A3A"
+
+- type: entity
+  parent: DefaultStationBeaconSecurity
+  id: DefaultStationBeaconBrig
+  suffix: Brig
+  components:
+  - type: NavMapBeacon
+    text: brig
+
+- type: entity
+  parent: DefaultStationBeaconSecurity
+  id: DefaultStationBeaconWardensOffice
+  suffix: Warden's Office
+  components:
+  - type: NavMapBeacon
+    text: warden's office
+
+- type: entity
+  parent: DefaultStationBeaconSecurity
+  id: DefaultStationBeaconHOSRoom
+  suffix: HOS’s Room
+  components:
+  - type: NavMapBeacon
+    text: head of security’s room
+
+- type: entity
+  parent: DefaultStationBeaconSecurity
+  id: DefaultStationBeaconArmory
+  suffix: Armory
+  components:
+  - type: NavMapBeacon
+    text: armory
+
+- type: entity
+  parent: DefaultStationBeaconSecurity
+  id: DefaultStationBeaconPermaBrig
+  suffix: Perma Brig
+  components:
+  - type: NavMapBeacon
+    text: perma brig
+
+- type: entity
+  parent: DefaultStationBeaconSecurity
+  id: DefaultStationBeaconDetectiveRoom
+  suffix: Detective's Room
+  components:
+  - type: NavMapBeacon
+    text: detective's room
+
+- type: entity
+  parent: DefaultStationBeaconSecurity
+  id: DefaultStationBeaconCourtroom
+  suffix: Courtroom
+  components:
+  - type: NavMapBeacon
+    text: courtroom
+
+- type: entity
+  parent: DefaultStationBeaconSecurity
+  id: DefaultStationBeaconLawOffice
+  suffix: Law Office
+  components:
+    - type: NavMapBeacon
+      text: law office
+
+- type: entity
+  parent: DefaultStationBeacon
+  id: DefaultStationBeaconMedical
+  suffix: Medical
+  components:
+  - type: NavMapBeacon
+    text: medical
+    color: "#52B4E9"
+
+- type: entity
+  parent: DefaultStationBeaconMedical
+  id: DefaultStationBeaconMedbay
+  suffix: Medbay
+  components:
+  - type: NavMapBeacon
+    text: medbay
+
+- type: entity
+  parent: DefaultStationBeaconMedical
+  id: DefaultStationBeaconChemistry
+  suffix: Chemistry
+  components:
+  - type: NavMapBeacon
+    text: chemistry
+
+- type: entity
+  parent: DefaultStationBeaconMedical
+  id: DefaultStationBeaconCryonics
+  suffix: Cryonics
+  components:
+  - type: NavMapBeacon
+    text: cryonics
+
+- type: entity
+  parent: DefaultStationBeaconMedical
+  id: DefaultStationBeaconCMORoom
+  suffix: CMO's room
+  components:
+  - type: NavMapBeacon
+    text: chief medical officer’s room
+
+- type: entity
+  parent: DefaultStationBeaconMedical
+  id: DefaultStationBeaconMorgue
+  suffix: Morgue
+  components:
+  - type: NavMapBeacon
+    text: morgue
+
+- type: entity
+  parent: DefaultStationBeacon
+  id: DefaultStationBeaconScience
+  suffix: Science
+  components:
+  - type: NavMapBeacon
+    text: science
+    color: "#D381C9"
+
+- type: entity
+  parent: DefaultStationBeaconScience
+  id: DefaultStationBeaconRND
+  suffix: RND
+  components:
+  - type: NavMapBeacon
+    text: research & development
+
+- type: entity
+  parent: DefaultStationBeaconScience
+  id: DefaultStationBeaconServerRoom
+  suffix: Server Room
+  components:
+  - type: NavMapBeacon
+    text: server room
+
+- type: entity
+  parent: DefaultStationBeaconScience
+  id: DefaultStationBeaconRDRoom
+  suffix: RD's Room
+  components:
+  - type: NavMapBeacon
+    text: research director's room
+
+- type: entity
+  parent: DefaultStationBeaconScience
+  id: DefaultStationBeaconRobotics
+  suffix: Robotics
+  components:
+  - type: NavMapBeacon
+    text: robotics
+
+- type: entity
+  parent: DefaultStationBeaconScience
+  id: DefaultStationBeaconArtifactLab
+  suffix: Artifact Lab
+  components:
+  - type: NavMapBeacon
+    text: artifact lab
+
+- type: entity
+  parent: DefaultStationBeaconScience
+  id: DefaultStationBeaconAnomalyGenerator
+  suffix: Anomaly Generator
+  components:
+  - type: NavMapBeacon
+    text: anomaly generator
+
+- type: entity
+  parent: DefaultStationBeacon
+  id: DefaultStationBeaconSupply
+  suffix: Supply
+  components:
+  - type: NavMapBeacon
+    text: supply
+    color: "#A46106"
+
+- type: entity
+  parent: DefaultStationBeaconSupply
+  id: DefaultStationBeaconCargoReception
+  suffix: Cargo Reception
+  components:
+  - type: NavMapBeacon
+    text: cargo reception
+
+- type: entity
+  parent: DefaultStationBeaconSupply
+  id: DefaultStationBeaconCargoBay
+  suffix: Cargo Bay
+  components:
+  - type: NavMapBeacon
+    text: cargo bay
+
+- type: entity
+  parent: DefaultStationBeaconSupply
+  id: DefaultStationBeaconQMRoom
+  suffix: QM's Room
+  components:
+  - type: NavMapBeacon
+    text: quartermaster's room
+
+- type: entity
+  parent: DefaultStationBeaconSupply
+  id: DefaultStationBeaconSalvage
+  suffix: Salvage
+  components:
+  - type: NavMapBeacon
+    text: salvage
+
+- type: entity
+  parent: DefaultStationBeacon
+  id: DefaultStationBeaconEngineering
+  suffix: Engineering
+  components:
+  - type: NavMapBeacon
+    text: engineering
+    color: "#EFB341"
+
+- type: entity
+  parent: DefaultStationBeaconEngineering
+  id: DefaultStationBeaconCERoom
+  suffix: CE's Room
+  components:
+  - type: NavMapBeacon
+    text: chief engineer's room
+
+- type: entity
+  parent: DefaultStationBeaconEngineering
+  id: DefaultStationBeaconAME
+  suffix: AME
+  components:
+  - type: NavMapBeacon
+    text: AME
+
+- type: entity
+  parent: DefaultStationBeaconEngineering
+  id: DefaultStationBeaconSolars
+  suffix: Solars
+  components:
+  - type: NavMapBeacon
+    text: solars
+
+- type: entity
+  parent: DefaultStationBeaconEngineering
+  id: DefaultStationBeaconSingularity
+  suffix: Singularity
+  components:
+  - type: NavMapBeacon
+    text: singularity engine
+
+- type: entity
+  parent: DefaultStationBeaconEngineering
+  id: DefaultStationBeaconPowerBank
+  suffix: Power Bank
+  components:
+  - type: NavMapBeacon
+    text: SMES power bank
+
+- type: entity
+  parent: DefaultStationBeaconEngineering
+  id: DefaultStationBeaconTelecoms
+  suffix: Telecoms
+  components:
+  - type: NavMapBeacon
+    text: telecoms
+
+- type: entity
+  parent: DefaultStationBeaconEngineering
+  id: DefaultStationBeaconAtmospherics
+  suffix: Atmospherics
+  components:
+  - type: NavMapBeacon
+    text: atmospherics
+
+- type: entity
+  parent: DefaultStationBeaconEngineering
+  id: DefaultStationBeaconTEG
+  suffix: TEG
+  components:
+  - type: NavMapBeacon
+    text: TEG
+
+- type: entity
+  parent: DefaultStationBeaconEngineering
+  id: DefaultStationBeaconTeslaEngine
+  suffix: Tesla Engine
+  components:
+  - type: NavMapBeacon
+    text: tesla engine
+
+- type: entity
+  parent: DefaultStationBeaconEngineering
+  id: DefaultStationBeaconTechVault
+  suffix: Tech Vault
+  components:
+  - type: NavMapBeacon
+    text: tech vault
+
+- type: entity
+  parent: DefaultStationBeacon
+  id: DefaultStationBeaconService
+  suffix: Service
+  components:
+  - type: NavMapBeacon
+    text: service
+    color: "#9FED58"
+
+- type: entity
+  parent: DefaultStationBeaconService
+  id: DefaultStationBeaconKitchen
+  suffix: Kitchen
+  components:
+  - type: NavMapBeacon
+    text: kitchen
+
+- type: entity
+  parent: DefaultStationBeaconService
+  id: DefaultStationBeaconBar
+  suffix: Bar
+  components:
+  - type: NavMapBeacon
+    text: bar
+
+- type: entity
+  parent: DefaultStationBeaconService
+  id: DefaultStationBeaconBotany
+  suffix: Botany
+  components:
+  - type: NavMapBeacon
+    text: botany
+
+- type: entity
+  parent: DefaultStationBeaconService
+  id: DefaultStationBeaconJanitorsCloset
+  suffix: Janitor's Closet
+  components:
+  - type: NavMapBeacon
+    text: janitor's closet
+
+- type: entity
+  parent: DefaultStationBeacon
+  id: DefaultStationBeaconArrivals
+  suffix: Arrivals
+  components:
+  - type: NavMapBeacon
+    text: arrivals
+
+- type: entity
+  parent: DefaultStationBeacon
+  id: DefaultStationBeaconEVAStorage
+  suffix: EVA Storage
+  components:
+  - type: NavMapBeacon
+    text: EVA storage
+
+- type: entity
+  parent: DefaultStationBeacon
+  id: DefaultStationBeaconChapel
+  suffix: Chapel
+  components:
+  - type: NavMapBeacon
+    text: chapel
+
+- type: entity
+  parent: DefaultStationBeacon
+  id: DefaultStationBeaconLibrary
+  suffix: Library
+  components:
+    - type: NavMapBeacon
+      text: library
+
+- type: entity
+  parent: DefaultStationBeacon
+  id: DefaultStationBeaconToolRoom
+  suffix: Tool Room
+  components:
+  - type: NavMapBeacon
+    text: tool room
+
+- type: entity
+  parent: DefaultStationBeacon
+  id: DefaultStationBeaconDisposals
+  suffix: Disposals
+  components:
+  - type: NavMapBeacon
+    text: disposals
+
diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/structures/station_beacon.yml b/Resources/Prototypes/Recipes/Construction/Graphs/structures/station_beacon.yml
new file mode 100644 (file)
index 0000000..d9c2c2c
--- /dev/null
@@ -0,0 +1,26 @@
+- type: constructionGraph
+  id: StationBeaconPart
+  start: start
+  graph:
+    - node: start
+      edges:
+        - to: complete
+          steps:
+          - tool: Pulsing
+          completed:
+          - !type:PlaySound
+            sound: /Audio/Effects/unwrap.ogg
+
+    - node: complete
+      entity: DefaultStationBeaconUnanchored
+      edges:
+        - to: start
+          steps:
+          - tool: Welding
+            doAfter: 1
+          completed:
+          - !type:SpawnPrototype
+            prototype: SheetSteel1
+            amount: 1
+          - !type:DeleteEntity
+
diff --git a/Resources/Textures/Objects/Devices/station_beacon.rsi/assembly.png b/Resources/Textures/Objects/Devices/station_beacon.rsi/assembly.png
new file mode 100644 (file)
index 0000000..b355d05
Binary files /dev/null and b/Resources/Textures/Objects/Devices/station_beacon.rsi/assembly.png differ
diff --git a/Resources/Textures/Objects/Devices/station_beacon.rsi/blink.png b/Resources/Textures/Objects/Devices/station_beacon.rsi/blink.png
new file mode 100644 (file)
index 0000000..53fabd1
Binary files /dev/null and b/Resources/Textures/Objects/Devices/station_beacon.rsi/blink.png differ
diff --git a/Resources/Textures/Objects/Devices/station_beacon.rsi/icon.png b/Resources/Textures/Objects/Devices/station_beacon.rsi/icon.png
new file mode 100644 (file)
index 0000000..67f3f53
Binary files /dev/null and b/Resources/Textures/Objects/Devices/station_beacon.rsi/icon.png differ
diff --git a/Resources/Textures/Objects/Devices/station_beacon.rsi/meta.json b/Resources/Textures/Objects/Devices/station_beacon.rsi/meta.json
new file mode 100644 (file)
index 0000000..771ce4c
--- /dev/null
@@ -0,0 +1,26 @@
+{
+    "version": 1,
+    "license": "CC0-1.0",
+    "copyright": "Created by EmoGarbage404 (github) for SS14, based on beacon design from /tg/",
+    "size": {
+        "x": 32,
+        "y": 32
+    },
+    "states": [
+        {
+            "name": "icon"
+        },
+        {
+            "name": "blink",
+            "delays": [
+                [
+                    2.0,
+                    0.1
+                ]
+            ]
+        },
+        {
+            "name": "assembly"
+        }
+    ]
+}
index a56d3719b20b2163676ba8e8ca7278d0de5dbe64..e32905c6e1dedf7319d8e58a82cca1e0c44576e8 100644 (file)
@@ -108,3 +108,14 @@ ReagentContainerMilkOat: DrinkOatMilkCarton
 
 # 2023-12-20
 MiasmaCanister: AmmoniaCanister
+
+# 2023-12-28
+WarpPointBeaconBar: null
+WarpPointBeaconCargo: null
+WarpPointBeaconCommand: null
+WarpPointBeaconEngineering: null
+WarpPointBeaconMedical: null
+WarpPointBeaconNeutral: null
+WarpPointBeaconScience: null
+WarpPointBeaconSecurity: null
+WarpPointBeaconService: null