From: SlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com> Date: Mon, 12 Jan 2026 02:47:47 +0000 (+0100) Subject: Add the ability for station maps to track grids they are not on (#41248) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=435b7d5cf89897476ee60995a14944c6ed8dd1a1;p=space-station-14.git Add the ability for station maps to track grids they are not on (#41248) * Initial commit * Accidentally included the nukie map changes * Fix the gridcheck * Addressing review * Review change * Review comments --- diff --git a/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs b/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs index 3d1eb1723c..49b383a7d7 100644 --- a/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs +++ b/Content.Client/Pinpointer/UI/StationMapBoundUserInterface.cs @@ -17,7 +17,11 @@ public sealed class StationMapBoundUserInterface : BoundUserInterface base.Open(); EntityUid? gridUid = null; - if (EntMan.TryGetComponent(Owner, out var xform)) + if (EntMan.TryGetComponent(Owner, out var comp) && comp.TargetGrid != null) + { + gridUid = comp.TargetGrid; + } + else if (EntMan.TryGetComponent(Owner, out var xform)) { gridUid = xform.GridUid; } @@ -30,8 +34,8 @@ public sealed class StationMapBoundUserInterface : BoundUserInterface { stationName = gridMetaData.EntityName; } - - if (EntMan.TryGetComponent(Owner, out var comp) && comp.ShowLocation) + + if (comp != null && comp.ShowLocation) _window.Set(stationName, gridUid, Owner); else _window.Set(stationName, gridUid, null); diff --git a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs index c669ca5278..0dc906738f 100644 --- a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs @@ -86,6 +86,8 @@ public sealed class NukeopsRuleSystem : GameRuleSystem return; component.TargetStation = RobustRandom.Pick(eligible); + var ev = new NukeopsTargetStationSelectedEvent(uid, component.TargetStation); + RaiseLocalEvent(ref ev); } #region Event Handlers @@ -549,3 +551,20 @@ public sealed class NukeopsRuleSystem : GameRuleSystem return null; } } + +/// +/// Raised when a station has been assigned as a target for the NukeOps rule. +/// +[ByRefEvent] +public readonly struct NukeopsTargetStationSelectedEvent(EntityUid ruleEntity, EntityUid? targetStation) +{ + /// + /// The entity containing the NukeOps gamerule. + /// + public readonly EntityUid RuleEntity = ruleEntity; + + /// + /// The target station, if it exists. + /// + public readonly EntityUid? TargetStation = targetStation; +} diff --git a/Content.Server/Pinpointer/StationMapSystem.cs b/Content.Server/Pinpointer/StationMapSystem.cs index c8e5b22617..bf2d2e2817 100644 --- a/Content.Server/Pinpointer/StationMapSystem.cs +++ b/Content.Server/Pinpointer/StationMapSystem.cs @@ -1,7 +1,10 @@ +using Content.Server.GameTicking; +using Content.Server.GameTicking.Rules; +using Content.Server.GameTicking.Rules.Components; using Content.Shared.PowerCell; using Content.Shared.Pinpointer; +using Content.Shared.Station; using Robust.Server.GameObjects; -using Robust.Shared.Player; namespace Content.Server.Pinpointer; @@ -9,12 +12,18 @@ public sealed class StationMapSystem : EntitySystem { [Dependency] private readonly UserInterfaceSystem _ui = default!; [Dependency] private readonly PowerCellSystem _cell = default!; + [Dependency] private readonly SharedStationSystem _station = default!; + [Dependency] private readonly SharedTransformSystem _xform = default!; + [Dependency] private readonly GameTicker _gameTicker = default!; public override void Initialize() { base.Initialize(); + SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnUserParentChanged); + SubscribeLocalEvent(OnNukeopsStationSelected); + Subs.BuiEvents(StationMapUiKey.Key, subs => { subs.Event(OnStationMapOpened); @@ -22,6 +31,33 @@ public sealed class StationMapSystem : EntitySystem }); } + private void OnMapInit(Entity ent, ref MapInitEvent args) + { + if (!ent.Comp.InitializeWithStation) + return; + + // If we ever find a need to make more exceptions like this, just turn this into an event. + if (HasComp(ent)) + { + foreach (var rule in _gameTicker.GetActiveGameRules()) + { + if (TryComp(rule, out var nukeopsRule) && nukeopsRule.TargetStation != null) + { + ent.Comp.TargetGrid = _station.GetLargestGrid((nukeopsRule.TargetStation.Value, null)); + Dirty(ent); + return; + } + } + } + + var station = _station.GetStationInMap(_xform.GetMapId(ent.Owner)); + if (station != null) + { + ent.Comp.TargetGrid = _station.GetLargestGrid((station.Value, null)); + Dirty(ent); + } + } + private void OnStationMapClosed(EntityUid uid, StationMapComponent component, BoundUIClosedEvent args) { if (!Equals(args.UiKey, StationMapUiKey.Key)) @@ -43,4 +79,19 @@ public sealed class StationMapSystem : EntitySystem var comp = EnsureComp(args.Actor); comp.Map = uid; } + + private void OnNukeopsStationSelected(Entity ent, ref NukeopsTargetStationSelectedEvent args) + { + if (args.TargetStation == null) + return; + + if (!TryComp(ent, out var stationMap) || !TryComp(args.RuleEntity, out var ruleGrids)) + return; + + if (Transform(ent).MapID != ruleGrids.Map) + return; + + stationMap.TargetGrid = _station.GetLargestGrid((args.TargetStation.Value, null)); + Dirty(ent); + } } diff --git a/Content.Shared/Pinpointer/NukeopsStationMapComponent.cs b/Content.Shared/Pinpointer/NukeopsStationMapComponent.cs new file mode 100644 index 0000000000..2b57959f9e --- /dev/null +++ b/Content.Shared/Pinpointer/NukeopsStationMapComponent.cs @@ -0,0 +1,10 @@ +namespace Content.Shared.Pinpointer; + +/// +/// Used to indicate that an entity with the StationMapComponent should be updated to target the TargetStation of NukeopsRuleComponent. +/// Uses the most recent active NukeopsRule when spawned, or the NukeopsRule which spawned the grid that the entity is on. +/// +[RegisterComponent] +public sealed partial class NukeopsStationMapComponent : Component +{ +} diff --git a/Content.Shared/Pinpointer/StationMapComponent.cs b/Content.Shared/Pinpointer/StationMapComponent.cs index 07cc99605e..bba46215d7 100644 --- a/Content.Shared/Pinpointer/StationMapComponent.cs +++ b/Content.Shared/Pinpointer/StationMapComponent.cs @@ -1,11 +1,27 @@ +using Robust.Shared.GameStates; + namespace Content.Shared.Pinpointer; -[RegisterComponent] +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] public sealed partial class StationMapComponent : Component { /// /// Whether or not to show the user's location on the map. /// - [DataField] + [DataField, AutoNetworkedField] public bool ShowLocation = true; + + /// + /// If true, when this entity initializes it will target and remember the station grid of the map the entity is in. + /// If there is no station, the entity will target a random station in the current session. + /// + [DataField] + public bool InitializeWithStation = false; + + /// + /// The target grid that the map will display. + /// If null, it will display the user's current grid. + /// + [DataField, AutoNetworkedField] + public EntityUid? TargetGrid; } diff --git a/Resources/Prototypes/Entities/Objects/Devices/station_map.yml b/Resources/Prototypes/Entities/Objects/Devices/station_map.yml index e440cec09a..8724a4060b 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/station_map.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/station_map.yml @@ -52,3 +52,37 @@ id: HandheldStationMapUnpowered parent: BaseHandheldStationMap suffix: Handheld, Always Powered + +- type: entity + parent: HandheldStationMap + id: HandheldStationMapStatic + suffix: Handheld, Works Off-Station + components: + - type: StationMap + initializeWithStation: true + +- type: entity + parent: HandheldStationMap + id: HandheldStationMapNukeops + name: target station map + suffix: Handheld, NukeOps + description: Displays a readout of the target station. + components: + - type: Sprite + sprite: Objects/Devices/tablets.rsi + layers: + - state: tablet + - state: syndie + shader: unshaded + - type: Item + sprite: Objects/Devices/tablets.rsi + inhandVisuals: + left: + - state: inhand-left-syndie + right: + - state: inhand-right-syndie + - type: StationMap + showLocation: false + initializeWithStation: true + - type: NukeopsStationMap + diff --git a/Resources/Textures/Objects/Devices/tablets.rsi/inhand-left-syndie.png b/Resources/Textures/Objects/Devices/tablets.rsi/inhand-left-syndie.png new file mode 100644 index 0000000000..2bff1528e7 Binary files /dev/null and b/Resources/Textures/Objects/Devices/tablets.rsi/inhand-left-syndie.png differ diff --git a/Resources/Textures/Objects/Devices/tablets.rsi/inhand-right-syndie.png b/Resources/Textures/Objects/Devices/tablets.rsi/inhand-right-syndie.png new file mode 100644 index 0000000000..89e389cdb2 Binary files /dev/null and b/Resources/Textures/Objects/Devices/tablets.rsi/inhand-right-syndie.png differ diff --git a/Resources/Textures/Objects/Devices/tablets.rsi/meta.json b/Resources/Textures/Objects/Devices/tablets.rsi/meta.json index 5c572d32e4..224ccf739c 100644 --- a/Resources/Textures/Objects/Devices/tablets.rsi/meta.json +++ b/Resources/Textures/Objects/Devices/tablets.rsi/meta.json @@ -1,7 +1,7 @@ { "version": 1, "license": "CC-BY-SA-3.0", - "copyright": "Taken from Baystation12 at https://github.com/Baystation12/Baystation12/tree/17e84546562b97d775cb26790a08e6d87e7f8077 and heavily modified by Flareguy for Space Station 14. Inhands by carousel", + "copyright": "Taken from Baystation12 at https://github.com/Baystation12/Baystation12/tree/17e84546562b97d775cb26790a08e6d87e7f8077 and heavily modified by Flareguy for Space Station 14. Inhands by carousel. Syndie versions modified from generic by SlamBamActionman", "size": { "x": 32, "y": 32 @@ -29,6 +29,23 @@ { "name": "inhand-right", "directions": 4 + }, + { + "name": "syndie", + "delays": [ + [ + 0.3, + 0.3 + ] + ] + }, + { + "name": "inhand-left-syndie", + "directions": 4 + }, + { + "name": "inhand-right-syndie", + "directions": 4 } ] } diff --git a/Resources/Textures/Objects/Devices/tablets.rsi/syndie.png b/Resources/Textures/Objects/Devices/tablets.rsi/syndie.png new file mode 100644 index 0000000000..1c288c8bf6 Binary files /dev/null and b/Resources/Textures/Objects/Devices/tablets.rsi/syndie.png differ