]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Move some Station methods into shared (#38976)
authorNemanja <98561806+EmoGarbage404@users.noreply.github.com>
Fri, 8 Aug 2025 15:22:34 +0000 (11:22 -0400)
committerGitHub <noreply@github.com>
Fri, 8 Aug 2025 15:22:34 +0000 (11:22 -0400)
41 files changed:
Content.Client/Administration/UI/Tabs/ObjectsTab/ObjectsTab.xaml.cs
Content.Client/Station/StationSystem.cs
Content.IntegrationTests/Tests/Station/EvacShuttleTest.cs
Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs
Content.Server/Anomaly/AnomalySystem.Generator.cs
Content.Server/Cargo/Components/StationCargoOrderDatabaseComponent.cs
Content.Server/Cargo/Systems/CargoSystem.Orders.cs
Content.Server/Cargo/Systems/CargoSystem.Telepad.cs
Content.Server/Chat/Systems/ChatSystem.cs
Content.Server/Commands/ContentCompletionHelper.cs
Content.Server/CrewManifest/CrewManifestSystem.cs
Content.Server/GameTicking/Rules/DragonRuleSystem.cs
Content.Server/GameTicking/Rules/GameRuleSystem.Utility.cs
Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs
Content.Server/GameTicking/Rules/RoundstartStationVariationRuleSystem.cs
Content.Server/GameTicking/Rules/VariationPass/BaseEntityReplaceVariationPassSystem.cs
Content.Server/GameTicking/Rules/VariationPass/EntitySpawnVariationPassSystem.cs
Content.Server/GameTicking/Rules/VariationPass/PuddleMessVariationPassSystem.cs
Content.Server/GameTicking/Rules/ZombieRuleSystem.cs
Content.Server/Maps/GameMapPrototype.cs
Content.Server/Nuke/Commands/SendNukeCodesCommand.cs
Content.Server/Nuke/NukeCodePaperSystem.cs
Content.Server/RoundEnd/RoundEndSystem.cs
Content.Server/Salvage/SalvageSystem.Runner.cs
Content.Server/Shuttles/Systems/ArrivalsSystem.cs
Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs
Content.Server/Shuttles/Systems/ShuttleSystem.GridFill.cs
Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs
Content.Server/Station/Commands/StationCommand.cs
Content.Server/Station/Events/StationPostInitEvent.cs
Content.Server/Station/Systems/StationBiomeSystem.cs
Content.Server/Station/Systems/StationNameSystem.cs
Content.Server/Station/Systems/StationSystem.cs
Content.Server/StationEvents/Events/AnomalySpawnRule.cs
Content.Server/StationEvents/Events/CargoGiftsRule.cs
Content.Server/StationEvents/Events/MeteorSwarmSystem.cs
Content.Server/StationEvents/Events/SpaceSpawnRule.cs
Content.Shared/Station/Components/StationDataComponent.cs [moved from Content.Server/Station/Components/StationDataComponent.cs with 55% similarity]
Content.Shared/Station/SharedStationSystem.Tracker.cs [new file with mode: 0644]
Content.Shared/Station/SharedStationSystem.cs
Content.Shared/Station/StationConfig.cs [moved from Content.Server/Station/StationConfig.cs with 59% similarity]

index 59e0e6040b768a3bf421b7c898dd4706afa483d8..de9ccbbf50ce5e44c4b795c9b62f11d499ff1b51 100644 (file)
@@ -76,7 +76,7 @@ public sealed partial class ObjectsTab : Control
         switch (selection)
         {
             case ObjectsTabSelection.Stations:
-                entities.AddRange(_entityManager.EntitySysManager.GetEntitySystem<StationSystem>().Stations);
+                entities.AddRange(_entityManager.EntitySysManager.GetEntitySystem<StationSystem>().GetStationNames());
                 break;
             case ObjectsTabSelection.Grids:
             {
index 5a4a1853d2464e8eab9215b31ef63789486b503b..e1ccd14d7be53d0fc36438e8057c67ce39d32ace 100644 (file)
@@ -2,34 +2,5 @@
 
 namespace Content.Client.Station;
 
-/// <summary>
-/// This handles letting the client know stations are a thing. Only really used by an admin menu.
-/// </summary>
-public sealed partial class StationSystem : SharedStationSystem
-{
-    private readonly List<(string Name, NetEntity Entity)> _stations = new();
-
-    /// <summary>
-    /// All stations that currently exist.
-    /// </summary>
-    /// <remarks>
-    /// I'd have this just invoke an entity query, but we're on the client and the client barely knows about stations.
-    /// </remarks>
-    // TODO: Stations have a global PVS override now, this can probably be changed into a query.
-    public IReadOnlyList<(string Name, NetEntity Entity)> Stations => _stations;
-
-    /// <inheritdoc/>
-    public override void Initialize()
-    {
-        base.Initialize();
-
-        SubscribeNetworkEvent<StationsUpdatedEvent>(StationsUpdated);
-    }
-
-    private void StationsUpdated(StationsUpdatedEvent ev)
-    {
-        _stations.Clear();
-        // TODO this needs to be done in component states and with the Ensure() methods
-        _stations.AddRange(ev.Stations);
-    }
-}
+/// <inheritdoc/>
+public sealed partial class StationSystem : SharedStationSystem;
index 9e925a451a5338e485f74300ec9775b1582e5cce..02552669f7a3eb1ba1d8215d5d179ef8fcc826ac 100644 (file)
@@ -2,9 +2,9 @@ using System.Linq;
 using Content.Server.GameTicking;
 using Content.Server.Shuttles.Components;
 using Content.Server.Shuttles.Systems;
-using Content.Server.Station.Components;
 using Content.Shared.CCVar;
 using Content.Shared.Shuttles.Components;
+using Content.Shared.Station.Components;
 using Robust.Shared.GameObjects;
 using Robust.Shared.Map.Components;
 
index 6e88d59be66f6d7fad20acfa95ff5abc19db6eca..44795d1fb261f6069f937cf02b4216848b37dc5f 100644 (file)
@@ -2,15 +2,12 @@ using System.Diagnostics.CodeAnalysis;
 using System.Linq;
 using System.Numerics;
 using Content.Server.Administration.Components;
-using Content.Server.Atmos;
-using Content.Server.Atmos.Components;
 using Content.Server.Cargo.Components;
 using Content.Server.Doors.Systems;
 using Content.Server.Hands.Systems;
 using Content.Server.Power.Components;
 using Content.Server.Power.EntitySystems;
 using Content.Server.Stack;
-using Content.Server.Station.Components;
 using Content.Server.Station.Systems;
 using Content.Server.Weapons.Ranged.Systems;
 using Content.Shared.Access;
@@ -28,6 +25,7 @@ using Content.Shared.Hands.Components;
 using Content.Shared.Inventory;
 using Content.Shared.PDA;
 using Content.Shared.Stacks;
+using Content.Shared.Station.Components;
 using Content.Shared.Verbs;
 using Content.Shared.Weapons.Ranged.Components;
 using Robust.Server.Physics;
index 1b88429204916c21324192e71e943bd49adfb596..46ad9278f8a16cf2e7fa9f61ed84be99f131c163 100644 (file)
@@ -1,6 +1,5 @@
 using Content.Server.Anomaly.Components;
 using Content.Server.Power.EntitySystems;
-using Content.Server.Station.Components;
 using Content.Shared.Anomaly;
 using Content.Shared.CCVar;
 using Content.Shared.Materials;
@@ -164,8 +163,7 @@ public sealed partial class AnomalySystem
         var xform = Transform(uid);
 
         if (_station.GetStationInMap(xform.MapID) is not { } station ||
-            !TryComp<StationDataComponent>(station, out var data) ||
-            _station.GetLargestGrid(data) is not { } grid)
+            _station.GetLargestGrid(station) is not { } grid)
         {
             if (xform.GridUid == null)
                 return;
index 37d0f5b7d1c3b786897df39994ecaefa7cff1634..56401602b31d25e6ff20f23c0292aa51fd3fa645 100644 (file)
@@ -1,8 +1,8 @@
 using System.Linq;
-using Content.Server.Station.Components;
 using Content.Shared.Cargo;
 using Content.Shared.Cargo.Components;
 using Content.Shared.Cargo.Prototypes;
+using Content.Shared.Station.Components;
 using Robust.Shared.Prototypes;
 
 namespace Content.Server.Cargo.Components;
index 862bf1f096c24add0d686dbb4e66b0e7f7b51e5b..febe093d98a78356d3f4d69310a855f2e1aa6b8b 100644 (file)
@@ -1,7 +1,6 @@
 using System.Diagnostics.CodeAnalysis;
 using System.Linq;
 using Content.Server.Cargo.Components;
-using Content.Server.Station.Components;
 using Content.Shared.Cargo;
 using Content.Shared.Cargo.BUI;
 using Content.Shared.Cargo.Components;
@@ -13,8 +12,8 @@ using Content.Shared.IdentityManagement;
 using Content.Shared.Interaction;
 using Content.Shared.Labels.Components;
 using Content.Shared.Paper;
+using Content.Shared.Station.Components;
 using JetBrains.Annotations;
-using Robust.Shared.Audio;
 using Robust.Shared.Map;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Timing;
index 25fb514db6dbdb700271a13b43095e6149460453..9e5c20e8c9cffd7483f0a66720a0c6e2834ee2a0 100644 (file)
@@ -3,11 +3,11 @@ using System.Linq;
 using Content.Server.Cargo.Components;
 using Content.Server.Power.Components;
 using Content.Server.Power.EntitySystems;
-using Content.Server.Station.Components;
 using Content.Shared.Cargo;
 using Content.Shared.Cargo.Components;
 using Content.Shared.DeviceLinking;
 using Content.Shared.Power;
+using Content.Shared.Station.Components;
 using Robust.Shared.Audio;
 using Robust.Shared.Random;
 using Robust.Shared.Utility;
index d49da57801472997932d5d78707c22ca62c29629..7ff12595d11bad5c86aa490c8a2697529c4dfe01 100644 (file)
@@ -7,7 +7,6 @@ using Content.Server.Chat.Managers;
 using Content.Server.GameTicking;
 using Content.Server.Speech.EntitySystems;
 using Content.Server.Speech.Prototypes;
-using Content.Server.Station.Components;
 using Content.Server.Station.Systems;
 using Content.Shared.ActionBlocker;
 using Content.Shared.Administration;
@@ -21,6 +20,7 @@ using Content.Shared.Mobs.Systems;
 using Content.Shared.Players;
 using Content.Shared.Players.RateLimiting;
 using Content.Shared.Radio;
+using Content.Shared.Station.Components;
 using Content.Shared.Whitelist;
 using Robust.Server.Player;
 using Robust.Shared.Audio;
index f843d84a626b33b73ee6514315ca1bd8da9290f7..bc80b287622beefac102a1d1b6cc98ba8d991d99 100644 (file)
@@ -1,4 +1,4 @@
-using Content.Server.Station.Components;
+using Content.Shared.Station.Components;
 using Robust.Shared.Console;
 
 namespace Content.Server.Commands;
index d8e0858ce019eb671b3890f3d0ea83393d12afe0..448e2fff20abf6fb063c4e8e3ff206e158452c1c 100644 (file)
@@ -1,7 +1,6 @@
 using System.Linq;
 using Content.Server.Administration;
 using Content.Server.EUI;
-using Content.Server.Station.Components;
 using Content.Server.Station.Systems;
 using Content.Server.StationRecords;
 using Content.Server.StationRecords.Systems;
@@ -10,12 +9,12 @@ using Content.Shared.CCVar;
 using Content.Shared.CrewManifest;
 using Content.Shared.GameTicking;
 using Content.Shared.Roles;
+using Content.Shared.Station.Components;
 using Content.Shared.StationRecords;
 using Robust.Shared.Configuration;
 using Robust.Shared.Console;
 using Robust.Shared.Player;
 using Robust.Shared.Prototypes;
-using Robust.Shared.Utility;
 
 namespace Content.Server.CrewManifest;
 
index de13218568e441ae3de2ec665ca1b5e339a6c30d..964b248beb757a2e17d969324c59e09b4995c5e4 100644 (file)
@@ -1,11 +1,8 @@
 using Content.Server.Antag;
-using Content.Server.Dragon;
 using Content.Server.GameTicking.Rules.Components;
 using Content.Server.Mind;
 using Content.Server.Roles;
-using Content.Server.Station.Components;
 using Content.Server.Station.Systems;
-using Content.Shared.CharacterInfo;
 using Content.Shared.Localizations;
 using Robust.Server.GameObjects;
 
@@ -56,10 +53,9 @@ public sealed class DragonRuleSystem : GameRuleSystem<DragonRuleComponent>
 
         var dragonXform = Transform(dragon);
 
-        var station = _station.GetStationInMap(dragonXform.MapID);
         EntityUid? stationGrid = null;
-        if (TryComp<StationDataComponent>(station, out var stationData))
-            stationGrid = _station.GetLargestGrid(stationData);
+        if (_station.GetStationInMap(dragonXform.MapID) is { } station)
+            stationGrid = _station.GetLargestGrid(station);
 
         if (stationGrid is not null)
         {
index 33ee91f8a5a5b4a09e3794a7a8ef7a179a0416b6..cd93eae502bf126f3bdd9b83a3491075afd96052 100644 (file)
@@ -1,14 +1,12 @@
 using System.Diagnostics.CodeAnalysis;
 using System.Linq;
-using Content.Server.GameTicking.Rules.Components;
 using Content.Server.Station.Components;
 using Content.Shared.GameTicking.Components;
 using Content.Shared.Random.Helpers;
-using Robust.Server.GameObjects;
+using Content.Shared.Station.Components;
 using Robust.Shared.Collections;
 using Robust.Shared.Map;
 using Robust.Shared.Map.Components;
-using Robust.Shared.Random;
 
 namespace Content.Server.GameTicking.Rules;
 
index f687c9dcc79e8f56566c6c171e26518f97a24e4e..17d9e4c8478734179c74831c83ff6eeaa130aa0d 100644 (file)
@@ -24,6 +24,7 @@ using Robust.Shared.Map;
 using Robust.Shared.Random;
 using Robust.Shared.Utility;
 using System.Linq;
+using Content.Shared.Station.Components;
 using Content.Shared.Store.Components;
 using Robust.Shared.Prototypes;
 
index 570889155b328cc8d185ffdbeb6420ce17175cf3..66f0d1f22c7fdc45b0cb3991ed5feaf5177c0c1b 100644 (file)
@@ -1,11 +1,10 @@
-using System.Linq;
-using Content.Server.GameTicking.Rules.Components;
+using Content.Server.GameTicking.Rules.Components;
 using Content.Server.Shuttles.Systems;
 using Content.Server.Station.Components;
 using Content.Server.Station.Events;
 using Content.Shared.GameTicking.Components;
+using Content.Shared.Station.Components;
 using Content.Shared.Storage;
-using Robust.Shared.Prototypes;
 using Robust.Shared.Random;
 
 namespace Content.Server.GameTicking.Rules;
index 00b2546e785b16ef81c50d9c27383bb70d8540c2..1a5b97c3275532df6d6363e22198012c876805a7 100644 (file)
@@ -58,7 +58,7 @@ public abstract class BaseEntityReplaceVariationPassSystem<TEntComp, TGameRuleCo
             Transform(newEnt).LocalRotation = rot;
         }
 
-        Log.Debug($"Entity replacement took {stopwatch.Elapsed} with {Stations.GetTileCount(args.Station)} tiles");
+        Log.Debug($"Entity replacement took {stopwatch.Elapsed} with {Stations.GetTileCount(args.Station.AsNullable())} tiles");
     }
 
     private void QueueReplace(Entity<TransformComponent> ent, List<EntitySpawnEntry> replacements)
index 7247bd98aa0b375744cab79903928cc4903ee7f7..462c89e016e9c7d63fb68b5b31c506011afaf901 100644 (file)
@@ -9,7 +9,7 @@ public sealed class EntitySpawnVariationPassSystem : VariationPassSystem<EntityS
 {
     protected override void ApplyVariation(Entity<EntitySpawnVariationPassComponent> ent, ref StationVariationPassEvent args)
     {
-        var totalTiles = Stations.GetTileCount(args.Station);
+        var totalTiles = Stations.GetTileCount(args.Station.AsNullable());
 
         var dirtyMod = Random.NextGaussian(ent.Comp.TilesPerEntityAverage, ent.Comp.TilesPerEntityStdDev);
         var trashTiles = Math.Max((int) (totalTiles * (1 / dirtyMod)), 0);
index 41cdbd87f8cc4a8a97c99b190e785518f35f87c8..2895416a7f0d483fe9024d0fbba32cd6d2e3700c 100644 (file)
@@ -15,7 +15,7 @@ public sealed class PuddleMessVariationPassSystem : VariationPassSystem<PuddleMe
 
     protected override void ApplyVariation(Entity<PuddleMessVariationPassComponent> ent, ref StationVariationPassEvent args)
     {
-        var totalTiles = Stations.GetTileCount(args.Station);
+        var totalTiles = Stations.GetTileCount(args.Station.AsNullable());
 
         if (!_proto.TryIndex(ent.Comp.RandomPuddleSolutionFill, out var proto))
             return;
index a38940c667e2f44deff5d7a05c51b0039a7ac876..9fab98446afbc5cf4e4d1dd590fd4d98d5928522 100644 (file)
@@ -4,7 +4,6 @@ using Content.Server.GameTicking.Rules.Components;
 using Content.Server.Popups;
 using Content.Server.Roles;
 using Content.Server.RoundEnd;
-using Content.Server.Station.Components;
 using Content.Server.Station.Systems;
 using Content.Server.Zombies;
 using Content.Shared.GameTicking.Components;
@@ -190,7 +189,7 @@ public sealed class ZombieRuleSystem : GameRuleSystem<ZombieRuleComponent>
         {
             foreach (var station in _station.GetStationsSet())
             {
-                if (TryComp<StationDataComponent>(station, out var data) && _station.GetLargestGrid(data) is { } grid)
+                if (_station.GetLargestGrid(station) is { } grid)
                     stationGrids.Add(grid);
             }
         }
index f0f40fe06d8e32f863e04be828ee92a13d3ec7e7..df9046652b276c67467b24c04652e3d28bed2564 100644 (file)
@@ -1,9 +1,8 @@
-using Content.Server.Station;
 using JetBrains.Annotations;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Utility;
 using System.Diagnostics;
-using System.Numerics;
+using Content.Shared.Station;
 
 namespace Content.Server.Maps;
 
index 8ac4f95a972586078ee423064185b000e2b3804d..e44811a835f8a8c21a062c430981d82b724281c6 100644 (file)
@@ -1,6 +1,6 @@
 using Content.Server.Administration;
-using Content.Server.Station.Components;
 using Content.Shared.Administration;
+using Content.Shared.Station.Components;
 using Robust.Shared.Console;
 
 namespace Content.Server.Nuke.Commands;
index aac2d2361d09c14d18eb04025e23ee5353a3c970..af6751ed714450903a58ffb8dd66313cfee26f3a 100644 (file)
@@ -2,9 +2,9 @@ using System.Diagnostics.CodeAnalysis;
 using Content.Server.Chat.Systems;
 using Content.Server.Fax;
 using Content.Shared.Fax.Components;
-using Content.Server.Station.Components;
 using Content.Server.Station.Systems;
 using Content.Shared.Paper;
+using Content.Shared.Station.Components;
 using Robust.Shared.Random;
 using Robust.Shared.Utility;
 
index 2d4f582bfcc52df5b5e11b07b33e227666d5c77b..a464796a74eb1047f8529236e9bc0da6ec20a87a 100644 (file)
@@ -9,7 +9,6 @@ using Content.Server.GameTicking;
 using Content.Server.Screens.Components;
 using Content.Server.Shuttles.Components;
 using Content.Server.Shuttles.Systems;
-using Content.Server.Station.Components;
 using Content.Server.Station.Systems;
 using Content.Shared.Database;
 using Content.Shared.DeviceNetwork;
@@ -20,6 +19,7 @@ using Robust.Shared.Player;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Timing;
 using Content.Shared.DeviceNetwork.Components;
+using Content.Shared.Station.Components;
 using Timer = Robust.Shared.Timing.Timer;
 
 namespace Content.Server.RoundEnd
@@ -97,10 +97,10 @@ namespace Content.Server.RoundEnd
         /// </summary>
         public EntityUid? GetStation()
         {
-            AllEntityQuery<StationEmergencyShuttleComponent, StationDataComponent>().MoveNext(out _, out _, out var data);
+            AllEntityQuery<StationEmergencyShuttleComponent, StationDataComponent>().MoveNext(out var uid, out _, out var data);
             if (data == null)
                 return null;
-            var targetGrid = _stationSystem.GetLargestGrid(data);
+            var targetGrid = _stationSystem.GetLargestGrid((uid, data));
             return targetGrid == null ? null : Transform(targetGrid.Value).MapUid;
         }
 
index 9050db3971d104932e06ea29040d22645086f54e..ceee9c378445c7fdc53be2826cc576de36a60da2 100644 (file)
@@ -2,7 +2,6 @@ using System.Numerics;
 using Content.Server.Salvage.Expeditions;
 using Content.Server.Shuttles.Components;
 using Content.Server.Shuttles.Events;
-using Content.Server.Station.Components;
 using Content.Shared.Chat;
 using Content.Shared.Humanoid;
 using Content.Shared.Mobs.Components;
@@ -10,6 +9,7 @@ using Content.Shared.Mobs.Systems;
 using Content.Shared.Salvage.Expeditions;
 using Content.Shared.Shuttles.Components;
 using Content.Shared.Localizations;
+using Content.Shared.Station.Components;
 using Robust.Shared.Map.Components;
 using Robust.Shared.Player;
 
index aa1c2e6dff105134303eed9d98c177bc97b2500f..20976ca0195f9ef0e57fbadefc6c0a57b69640cb 100644 (file)
@@ -11,7 +11,6 @@ using Content.Server.Shuttles.Components;
 using Content.Server.Shuttles.Events;
 using Content.Server.Spawners.Components;
 using Content.Server.Spawners.EntitySystems;
-using Content.Server.Station.Components;
 using Content.Server.Station.Events;
 using Content.Server.Station.Systems;
 using Content.Shared.Administration;
@@ -224,7 +223,7 @@ public sealed class ArrivalsSystem : EntitySystem
 
             if (component.FirstRun)
             {
-                var station = _station.GetLargestGrid(Comp<StationDataComponent>(component.Station));
+                var station = _station.GetLargestGrid(component.Station);
                 sourceMap = station == null ? null : Transform(station.Value)?.MapUid;
                 arrivalsDelay += RoundStartFTLDuration;
                 component.FirstRun = false;
@@ -470,7 +469,7 @@ public sealed class ArrivalsSystem : EntitySystem
         {
             while (query.MoveNext(out var uid, out var comp, out var shuttle, out var xform))
             {
-                if (comp.NextTransfer > curTime || !TryComp<StationDataComponent>(comp.Station, out var data))
+                if (comp.NextTransfer > curTime)
                     continue;
 
                 var tripTime = _shuttles.DefaultTravelTime + _shuttles.DefaultStartupTime;
@@ -486,7 +485,7 @@ public sealed class ArrivalsSystem : EntitySystem
                 // Go to station
                 else
                 {
-                    var targetGrid = _station.GetLargestGrid(data);
+                    var targetGrid = _station.GetLargestGrid(comp.Station);
 
                     if (targetGrid != null)
                         _shuttles.FTLToDock(uid, shuttle, targetGrid.Value);
index 9eff1455f9b0bfe29132eeea514730e34dee2e49..53714c846a3d1ac10244ed090a72136e9aea67ab 100644 (file)
@@ -14,7 +14,6 @@ using Content.Server.RoundEnd;
 using Content.Server.Screens.Components;
 using Content.Server.Shuttles.Components;
 using Content.Server.Shuttles.Events;
-using Content.Server.Station.Components;
 using Content.Server.Station.Events;
 using Content.Server.Station.Systems;
 using Content.Shared.Access.Systems;
@@ -181,7 +180,7 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
             return;
         }
 
-        var targetGrid = _station.GetLargestGrid(Comp<StationDataComponent>(station.Value));
+        var targetGrid = _station.GetLargestGrid(station.Value);
         if (targetGrid == null)
             return;
 
@@ -270,7 +269,7 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
             return null;
         }
 
-        var targetGrid = _station.GetLargestGrid(Comp<StationDataComponent>(stationUid));
+        var targetGrid = _station.GetLargestGrid(stationUid);
 
         // UHH GOOD LUCK
         if (targetGrid == null)
index a794ee0104216d13837972f4f076d8a8a3cddbe5..2e6ebe396c55fba6c66ac9d2428ea5cd9eed806f 100644 (file)
@@ -1,9 +1,7 @@
 using System.Numerics;
 using Content.Server.Shuttles.Components;
-using Content.Server.Station.Components;
 using Content.Server.Station.Events;
 using Content.Shared.CCVar;
-using Content.Shared.Salvage;
 using Content.Shared.Shuttles.Components;
 using Content.Shared.Station.Components;
 using Robust.Shared.Collections;
@@ -62,10 +60,7 @@ public sealed partial class ShuttleSystem
         if (!_cfg.GetCVar(CCVars.GridFill))
             return;
 
-        if (!TryComp(uid, out StationDataComponent? dataComp))
-            return;
-
-        var targetGrid = _station.GetLargestGrid(dataComp);
+        var targetGrid = _station.GetLargestGrid(uid);
 
         if (targetGrid == null)
             return;
@@ -165,12 +160,7 @@ public sealed partial class ShuttleSystem
         if (!_cfg.GetCVar(CCVars.GridFill))
             return;
 
-        if (!TryComp<StationDataComponent>(uid, out var data))
-        {
-            return;
-        }
-
-        var targetGrid = _station.GetLargestGrid(data);
+        var targetGrid = _station.GetLargestGrid(uid);
 
         if (targetGrid == null)
             return;
index 9c69422797eefb902d535d81a69342ab5da304ea..7090ca77ef5264446b2dea8519a485f6a93ef923 100644 (file)
@@ -1,15 +1,13 @@
 using System.Numerics;
 using Content.Server.Administration.Logs;
 using Content.Server.Singularity.Events;
-using Content.Server.Station.Components;
 using Content.Shared.Database;
-using Content.Shared.Ghost;
 using Content.Shared.Mind.Components;
 using Content.Shared.Singularity.Components;
 using Content.Shared.Singularity.EntitySystems;
+using Content.Shared.Station.Components;
 using Content.Shared.Tag;
 using Robust.Shared.Containers;
-using Robust.Shared.GameObjects;
 using Robust.Shared.Map;
 using Robust.Shared.Map.Components;
 using Robust.Shared.Physics.Components;
index 8fe8c67646d540e46774969c05719c946220fd06..f9dcb83d933af891ce850d12aeb79bb68e0586b5 100644 (file)
@@ -2,12 +2,12 @@ using System.Diagnostics;
 using System.Linq;
 using Content.Server.Administration;
 using Content.Server.Cargo.Systems;
-using Content.Server.Station.Components;
 using Content.Server.Station.Systems;
 using Content.Shared.Administration;
+using Content.Shared.Station;
+using Content.Shared.Station.Components;
 using Robust.Shared.Toolshed;
 using Robust.Shared.Toolshed.Errors;
-using Robust.Shared.Toolshed.Syntax;
 using Robust.Shared.Utility;
 
 namespace Content.Server.Station.Commands;
@@ -54,7 +54,7 @@ public sealed class StationsCommand : ToolshedCommand
     public EntityUid? LargestGrid([PipedArgument] EntityUid input)
     {
         _station ??= GetSys<StationSystem>();
-        return _station.GetLargestGrid(Comp<StationDataComponent>(input));
+        return _station.GetLargestGrid(input);
     }
 
     [CommandImplementation("largestgrid")]
index 54b8eeeb312739dad8562d58694d0a8ac71148e2..934d482bf2951c7c2410081ce1447720458918f1 100644 (file)
@@ -1,4 +1,4 @@
-using Content.Server.Station.Components;
+using Content.Shared.Station.Components;
 
 namespace Content.Server.Station.Events;
 
index c12e2f47e4822692cddfd9520db69c7d5e62c9f9..61bc70794a4aba26d10a291ea097c894fb7df158 100644 (file)
@@ -20,12 +20,10 @@ public sealed partial class StationBiomeSystem : EntitySystem
 
     private void OnStationPostInit(Entity<StationBiomeComponent> map, ref StationPostInitEvent args)
     {
-        if (!TryComp(map, out StationDataComponent? dataComp))
+        var station = _station.GetLargestGrid(map.Owner);
+        if (station == null)
             return;
 
-        var station = _station.GetLargestGrid(dataComp);
-        if (station == null) return;
-
         var mapId = Transform(station.Value).MapID;
         var mapUid = _map.GetMapOrInvalid(mapId);
 
index fbbf690465c917e7cdb0a1b087d2868cdb072511..ea17830a479994239793c149e8cb1c69a29b88ae 100644 (file)
@@ -1,4 +1,5 @@
 using Content.Server.Station.Components;
+using Content.Shared.Station.Components;
 
 namespace Content.Server.Station.Systems;
 
index 456d3c6b802f08a798657e61690360a34f5b2060..7100c6144f2d563b5c617206f102df176994f2e4 100644 (file)
@@ -3,20 +3,16 @@ using Content.Server.Chat.Systems;
 using Content.Server.GameTicking;
 using Content.Server.Station.Components;
 using Content.Server.Station.Events;
-using Content.Shared.CCVar;
 using Content.Shared.Station;
 using Content.Shared.Station.Components;
 using JetBrains.Annotations;
-using Robust.Server.GameObjects;
 using Robust.Server.GameStates;
 using Robust.Server.Player;
 using Robust.Shared.Collections;
-using Robust.Shared.Configuration;
 using Robust.Shared.Enums;
 using Robust.Shared.Map;
 using Robust.Shared.Map.Components;
 using Robust.Shared.Player;
-using Robust.Shared.Random;
 using Robust.Shared.Utility;
 
 namespace Content.Server.Station.Systems;
@@ -34,7 +30,6 @@ public sealed partial class StationSystem : SharedStationSystem
     [Dependency] private readonly ChatSystem _chatSystem = default!;
     [Dependency] private readonly SharedTransformSystem _transform = default!;
     [Dependency] private readonly MetaDataSystem _metaData = default!;
-    [Dependency] private readonly MapSystem _map = default!;
     [Dependency] private readonly PvsOverrideSystem _pvsOverride = default!;
 
     private ISawmill _sawmill = default!;
@@ -42,8 +37,8 @@ public sealed partial class StationSystem : SharedStationSystem
     private EntityQuery<MapGridComponent> _gridQuery;
     private EntityQuery<TransformComponent> _xformQuery;
 
-    private ValueList<MapId> _mapIds = new();
-    private ValueList<(Box2Rotated Bounds, MapId MapId)> _gridBounds = new();
+    private ValueList<MapId> _mapIds;
+    private ValueList<(Box2Rotated Bounds, MapId MapId)> _gridBounds;
 
     /// <inheritdoc/>
     public override void Initialize()
@@ -79,6 +74,7 @@ public sealed partial class StationSystem : SharedStationSystem
             return;
 
         stationData.Grids.Remove(uid);
+        Dirty(uid, component);
     }
 
     public override void Shutdown()
@@ -193,44 +189,6 @@ public sealed partial class StationSystem : SharedStationSystem
 
     #endregion Event handlers
 
-    /// <summary>
-    /// Gets the largest member grid from a station.
-    /// </summary>
-    public EntityUid? GetLargestGrid(StationDataComponent component)
-    {
-        EntityUid? largestGrid = null;
-        Box2 largestBounds = new Box2();
-
-        foreach (var gridUid in component.Grids)
-        {
-            if (!TryComp<MapGridComponent>(gridUid, out var grid) ||
-                grid.LocalAABB.Size.LengthSquared() < largestBounds.Size.LengthSquared())
-                continue;
-
-            largestBounds = grid.LocalAABB;
-            largestGrid = gridUid;
-        }
-
-        return largestGrid;
-    }
-
-    /// <summary>
-    /// Returns the total number of tiles contained in the station's grids.
-    /// </summary>
-    public int GetTileCount(StationDataComponent component)
-    {
-        var count = 0;
-        foreach (var gridUid in component.Grids)
-        {
-            if (!TryComp<MapGridComponent>(gridUid, out var grid))
-                continue;
-
-            count += _map.GetAllTiles(gridUid, grid).Count();
-        }
-
-        return count;
-    }
-
     /// <summary>
     /// Tries to retrieve a filter for everything in the station the source is on.
     /// </summary>
@@ -384,6 +342,7 @@ public sealed partial class StationSystem : SharedStationSystem
         var stationMember = EnsureComp<StationMemberComponent>(mapGrid);
         stationMember.Station = station;
         stationData.Grids.Add(mapGrid);
+        Dirty(station, stationData);
 
         RaiseLocalEvent(station, new StationGridAddedEvent(mapGrid, station, false), true);
 
@@ -407,6 +366,7 @@ public sealed partial class StationSystem : SharedStationSystem
 
         RemComp<StationMemberComponent>(mapGrid);
         stationData.Grids.Remove(mapGrid);
+        Dirty(station, stationData);
 
         RaiseLocalEvent(station, new StationGridRemovedEvent(mapGrid, station), true);
         _sawmill.Info($"Removing grid {mapGrid} from station {Name(station)} ({station})");
@@ -450,110 +410,6 @@ public sealed partial class StationSystem : SharedStationSystem
 
         QueueDel(station);
     }
-
-    public EntityUid? GetOwningStation(EntityUid? entity, TransformComponent? xform = null)
-    {
-        if (entity == null)
-            return null;
-
-        return GetOwningStation(entity.Value, xform);
-    }
-
-    /// <summary>
-    /// Gets the station that "owns" the given entity (essentially, the station the grid it's on is attached to)
-    /// </summary>
-    /// <param name="entity">Entity to find the owner of.</param>
-    /// <param name="xform">Resolve pattern, transform of the entity.</param>
-    /// <returns>The owning station, if any.</returns>
-    /// <remarks>
-    /// This does not remember what station an entity started on, it simply checks where it is currently located.
-    /// </remarks>
-    public EntityUid? GetOwningStation(EntityUid entity, TransformComponent? xform = null)
-    {
-        if (!Resolve(entity, ref xform))
-            throw new ArgumentException("Tried to use an abstract entity!", nameof(entity));
-
-        if (TryComp<StationDataComponent>(entity, out _))
-        {
-            // We are the station, just return ourselves.
-            return entity;
-        }
-
-        if (TryComp<MapGridComponent>(entity, out _))
-        {
-            // We are the station, just check ourselves.
-            return CompOrNull<StationMemberComponent>(entity)?.Station;
-        }
-
-        if (xform.GridUid == EntityUid.Invalid)
-        {
-            Log.Debug("Unable to get owning station - GridUid invalid.");
-            return null;
-        }
-
-        return CompOrNull<StationMemberComponent>(xform.GridUid)?.Station;
-    }
-
-    public List<EntityUid> GetStations()
-    {
-        var stations = new List<EntityUid>();
-        var query = EntityQueryEnumerator<StationDataComponent>();
-        while (query.MoveNext(out var uid, out _))
-        {
-            stations.Add(uid);
-        }
-
-        return stations;
-    }
-
-    public HashSet<EntityUid> GetStationsSet()
-    {
-        var stations = new HashSet<EntityUid>();
-        var query = EntityQueryEnumerator<StationDataComponent>();
-        while (query.MoveNext(out var uid, out _))
-        {
-            stations.Add(uid);
-        }
-
-        return stations;
-    }
-
-    public List<(string Name, NetEntity Entity)> GetStationNames()
-    {
-        var stations = GetStationsSet();
-        var stats = new List<(string Name, NetEntity Station)>();
-
-        foreach (var weh in stations)
-        {
-            stats.Add((MetaData(weh).EntityName, GetNetEntity(weh)));
-        }
-
-        return stats;
-    }
-
-    /// <summary>
-    /// Returns the first station that has a grid in a certain map.
-    /// If the map has no stations, null is returned instead.
-    /// </summary>
-    /// <remarks>
-    /// If there are multiple stations on a map it is probably arbitrary which one is returned.
-    /// </remarks>
-    public EntityUid? GetStationInMap(MapId map)
-    {
-        var query = EntityQueryEnumerator<StationDataComponent>();
-        while (query.MoveNext(out var uid, out var data))
-        {
-            foreach (var gridUid in data.Grids)
-            {
-                if (Transform(gridUid).MapID == map)
-                {
-                    return uid;
-                }
-            }
-        }
-
-        return null;
-    }
 }
 
 /// <summary>
index 06da91e256933a130becd226eb2163d957411967..4c9cfd87ea90915731d7200e2b3278e3d50bbeef 100644 (file)
@@ -1,7 +1,7 @@
 using Content.Server.Anomaly;
-using Content.Server.Station.Components;
 using Content.Server.StationEvents.Components;
-using Content.Shared.GameTicking.Components;
+using Content.Shared.GameTicking.Components;
+using Content.Shared.Station.Components;
 
 namespace Content.Server.StationEvents.Events;
 
@@ -31,7 +31,7 @@ public sealed class AnomalySpawnRule : StationEventSystem<AnomalySpawnRuleCompon
         if (!TryComp<StationDataComponent>(chosenStation, out var stationData))
             return;
 
-        var grid = StationSystem.GetLargestGrid(stationData);
+        var grid = StationSystem.GetLargestGrid((chosenStation.Value, stationData));
 
         if (grid is null)
             return;
index 91baf2ecad9581852c7ef95ca218437941c602f6..d38de1e0d80d948a201b7361fdbcf805a830c771 100644 (file)
@@ -2,9 +2,9 @@ using System.Linq;
 using Content.Server.Cargo.Components;
 using Content.Server.Cargo.Systems;
 using Content.Server.GameTicking;
-using Content.Server.Station.Components;
 using Content.Server.StationEvents.Components;
 using Content.Shared.GameTicking.Components;
+using Content.Shared.Station.Components;
 using Robust.Shared.Prototypes;
 
 namespace Content.Server.StationEvents.Events;
index 948fedf6fc1b3fd5ab82ad7c2b21e3edc53106c5..e1987789b62d734d74a0993103b2742f672590dd 100644 (file)
@@ -1,7 +1,6 @@
 using System.Numerics;
 using Content.Server.Chat.Systems;
 using Content.Server.GameTicking.Rules;
-using Content.Server.Station.Components;
 using Content.Server.Station.Systems;
 using Content.Server.StationEvents.Components;
 using Content.Shared.GameTicking.Components;
@@ -49,7 +48,7 @@ public sealed class MeteorSwarmSystem : GameRuleSystem<MeteorSwarmComponent>
             return;
 
         var station = RobustRandom.Pick(_station.GetStations());
-        if (_station.GetLargestGrid(Comp<StationDataComponent>(station)) is not { } grid)
+        if (_station.GetLargestGrid(station) is not { } grid)
             return;
 
         var mapId = Transform(grid).MapID;
index 6fccaaa5cfcbb8751324c9c2243cc8c9c27bbd3e..08e43b4c68d7f879c49361c6daae6ac8975997d0 100644 (file)
@@ -1,6 +1,4 @@
 using Content.Server.Antag;
-using Content.Server.GameTicking.Rules.Components;
-using Content.Server.Station.Components;
 using Content.Server.StationEvents.Components;
 using Content.Shared.GameTicking.Components;
 using Robust.Shared.Map;
@@ -32,10 +30,8 @@ public sealed class SpaceSpawnRule : StationEventSystem<SpaceSpawnRuleComponent>
             return;
         }
 
-        var stationData = Comp<StationDataComponent>(station.Value);
-
         // find a station grid
-        var gridUid = StationSystem.GetLargestGrid(stationData);
+        var gridUid = StationSystem.GetLargestGrid(station.Value);
         if (gridUid == null || !TryComp<MapGridComponent>(gridUid, out var grid))
         {
             Sawmill.Warning("Chosen station has no grids, cannot pick location for {ToPrettyString(uid):rule}");
similarity index 55%
rename from Content.Server/Station/Components/StationDataComponent.cs
rename to Content.Shared/Station/Components/StationDataComponent.cs
index d154c6936dd48d092119d5bfeb367d4f7bc325d8..ef01525d31f8dd83c7dfd9f762a5424f1e9c0de6 100644 (file)
@@ -1,26 +1,23 @@
-using Content.Server.Shuttles.Systems;
-using Content.Server.Station.Systems;
-using Robust.Shared.Serialization.TypeSerializers.Implementations;
-using Robust.Shared.Utility;
+using Robust.Shared.GameStates;
 
-namespace Content.Server.Station.Components;
+namespace Content.Shared.Station.Components;
 
 /// <summary>
 /// Stores core information about a station, namely its config and associated grids.
 /// All station entities will have this component.
 /// </summary>
-[RegisterComponent, Access(typeof(StationSystem))]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(SharedStationSystem))]
 public sealed partial class StationDataComponent : Component
 {
     /// <summary>
     /// The game map prototype, if any, associated with this station.
     /// </summary>
-    [DataField("stationConfig")]
-    public StationConfig? StationConfig = null;
+    [DataField]
+    public StationConfig? StationConfig;
 
     /// <summary>
     /// List of all grids this station is part of.
     /// </summary>
-    [DataField("grids")]
+    [DataField, AutoNetworkedField]
     public HashSet<EntityUid> Grids = new();
 }
diff --git a/Content.Shared/Station/SharedStationSystem.Tracker.cs b/Content.Shared/Station/SharedStationSystem.Tracker.cs
new file mode 100644 (file)
index 0000000..770420d
--- /dev/null
@@ -0,0 +1,88 @@
+using Content.Shared.Station.Components;
+using JetBrains.Annotations;
+using Robust.Shared.Map;
+
+namespace Content.Shared.Station;
+
+public abstract partial class SharedStationSystem
+{
+    private void InitializeTracker()
+    {
+        SubscribeLocalEvent<StationTrackerComponent, MapInitEvent>(OnTrackerMapInit);
+        SubscribeLocalEvent<StationTrackerComponent, ComponentRemove>(OnTrackerRemove);
+        SubscribeLocalEvent<StationTrackerComponent, GridUidChangedEvent>(OnTrackerGridChanged);
+        SubscribeLocalEvent<StationTrackerComponent, MetaFlagRemoveAttemptEvent>(OnMetaFlagRemoveAttempt);
+    }
+
+    private void OnTrackerMapInit(Entity<StationTrackerComponent> ent, ref MapInitEvent args)
+    {
+        _meta.AddFlag(ent, MetaDataFlags.ExtraTransformEvents);
+        UpdateStationTracker(ent.AsNullable());
+    }
+
+    private void OnTrackerRemove(Entity<StationTrackerComponent> ent, ref ComponentRemove args)
+    {
+        _meta.RemoveFlag(ent, MetaDataFlags.ExtraTransformEvents);
+    }
+
+    private void OnTrackerGridChanged(Entity<StationTrackerComponent> ent, ref GridUidChangedEvent args)
+    {
+        UpdateStationTracker((ent, ent.Comp, args.Transform));
+    }
+
+    private void OnMetaFlagRemoveAttempt(Entity<StationTrackerComponent> ent, ref MetaFlagRemoveAttemptEvent args)
+    {
+        if ((args.ToRemove & MetaDataFlags.ExtraTransformEvents) != 0 &&
+            ent.Comp.LifeStage <= ComponentLifeStage.Running)
+        {
+            args.ToRemove &= ~MetaDataFlags.ExtraTransformEvents;
+        }
+    }
+
+    /// <summary>
+    /// Updates the station tracker component based on entity's current location.
+    /// </summary>
+    [PublicAPI]
+    public void UpdateStationTracker(Entity<StationTrackerComponent?, TransformComponent?> ent)
+    {
+        if (!Resolve(ent, ref ent.Comp1))
+            return;
+
+        var xform = ent.Comp2;
+
+        if (!_xformQuery.Resolve(ent, ref xform))
+            return;
+
+        // Entity is in nullspace or not on a grid
+        if (xform.MapID == MapId.Nullspace || xform.GridUid == null)
+        {
+            SetStation(ent, null);
+            return;
+        }
+
+        // Check if the grid is part of a station
+        if (!_stationMemberQuery.TryGetComponent(xform.GridUid.Value, out var stationMember))
+        {
+            SetStation(ent, null);
+            return;
+        }
+
+        SetStation(ent, stationMember.Station);
+    }
+
+    /// <summary>
+    /// Sets the station for a StationTrackerComponent.
+    /// </summary>
+    [PublicAPI]
+    public void SetStation(Entity<StationTrackerComponent?> ent, EntityUid? station)
+    {
+        if (!Resolve(ent, ref ent.Comp))
+            return;
+
+        if (ent.Comp.Station == station)
+            return;
+
+        ent.Comp.Station = station;
+        Dirty(ent);
+    }
+}
index c067af610d65647e2c8c969995e3151dbacf484e..afd2e7725842a70a34a3a4c244df2ee7a84b054b 100644 (file)
@@ -1,11 +1,14 @@
+using System.Linq;
 using Content.Shared.Station.Components;
 using JetBrains.Annotations;
 using Robust.Shared.Map;
+using Robust.Shared.Map.Components;
 
 namespace Content.Shared.Station;
 
 public abstract partial class SharedStationSystem : EntitySystem
 {
+    [Dependency] private readonly SharedMapSystem _map = default!;
     [Dependency] private readonly MetaDataSystem _meta = default!;
 
     private EntityQuery<TransformComponent> _xformQuery;
@@ -16,96 +19,164 @@ public abstract partial class SharedStationSystem : EntitySystem
     {
         base.Initialize();
 
+        InitializeTracker();
+
         _xformQuery = GetEntityQuery<TransformComponent>();
         _stationMemberQuery = GetEntityQuery<StationMemberComponent>();
-
-        SubscribeLocalEvent<StationTrackerComponent, MapInitEvent>(OnTrackerMapInit);
-        SubscribeLocalEvent<StationTrackerComponent, ComponentRemove>(OnTrackerRemove);
-        SubscribeLocalEvent<StationTrackerComponent, GridUidChangedEvent>(OnTrackerGridChanged);
-        SubscribeLocalEvent<StationTrackerComponent, MetaFlagRemoveAttemptEvent>(OnMetaFlagRemoveAttempt);
     }
 
-    private void OnTrackerMapInit(Entity<StationTrackerComponent> ent, ref MapInitEvent args)
+    /// <summary>
+    /// Gets the largest member grid from a station.
+    /// </summary>
+    public EntityUid? GetLargestGrid(Entity<StationDataComponent?> ent)
     {
-        _meta.AddFlag(ent, MetaDataFlags.ExtraTransformEvents);
-        UpdateStationTracker(ent.AsNullable());
-    }
+        if (!Resolve(ent, ref ent.Comp))
+            return null;
 
-    private void OnTrackerRemove(Entity<StationTrackerComponent> ent, ref ComponentRemove args)
-    {
-        _meta.RemoveFlag(ent, MetaDataFlags.ExtraTransformEvents);
-    }
+        EntityUid? largestGrid = null;
+        Box2 largestBounds = new Box2();
 
-    private void OnTrackerGridChanged(Entity<StationTrackerComponent> ent, ref GridUidChangedEvent args)
-    {
-        UpdateStationTracker((ent, ent.Comp, args.Transform));
+        foreach (var gridUid in ent.Comp.Grids)
+        {
+            if (!TryComp<MapGridComponent>(gridUid, out var grid) ||
+                grid.LocalAABB.Size.LengthSquared() < largestBounds.Size.LengthSquared())
+                continue;
+
+            largestBounds = grid.LocalAABB;
+            largestGrid = gridUid;
+        }
+
+        return largestGrid;
     }
 
-    private void OnMetaFlagRemoveAttempt(Entity<StationTrackerComponent> ent, ref MetaFlagRemoveAttemptEvent args)
+    /// <summary>
+    /// Returns the total number of tiles contained in the station's grids.
+    /// </summary>
+    public int GetTileCount(Entity<StationDataComponent?> ent)
     {
-        if ((args.ToRemove & MetaDataFlags.ExtraTransformEvents) != 0 &&
-            ent.Comp.LifeStage <= ComponentLifeStage.Running)
+        if (!Resolve(ent, ref ent.Comp))
+            return 0;
+
+        var count = 0;
+        foreach (var gridUid in ent.Comp.Grids)
         {
-            args.ToRemove &= ~MetaDataFlags.ExtraTransformEvents;
+            if (!TryComp<MapGridComponent>(gridUid, out var grid))
+                continue;
+
+            count += _map.GetAllTiles(gridUid, grid).Count();
         }
+
+        return count;
+    }
+
+    [PublicAPI]
+    public EntityUid? GetOwningStation(EntityUid? entity, TransformComponent? xform = null)
+    {
+        if (entity == null)
+            return null;
+
+        return GetOwningStation(entity.Value, xform);
     }
 
     /// <summary>
-    /// Updates the station tracker component based on entity's current location.
+    /// Gets the station that "owns" the given entity (essentially, the station the grid it's on is attached to)
     /// </summary>
-    [PublicAPI]
-    public void UpdateStationTracker(Entity<StationTrackerComponent?, TransformComponent?> ent)
+    /// <param name="entity">Entity to find the owner of.</param>
+    /// <param name="xform">Resolve pattern, transform of the entity.</param>
+    /// <returns>The owning station, if any.</returns>
+    /// <remarks>
+    /// This does not remember what station an entity started on, it simply checks where it is currently located.
+    /// </remarks>
+    public EntityUid? GetOwningStation(EntityUid entity, TransformComponent? xform = null)
     {
-        if (!Resolve(ent, ref ent.Comp1))
-            return;
+        if (!Resolve(entity, ref xform))
+            throw new ArgumentException("Tried to use an abstract entity!", nameof(entity));
 
-        var xform = ent.Comp2;
+        if (TryComp<StationTrackerComponent>(entity, out var stationTracker))
+        {
+            // We have a specific station we are tracking and are tethered to.
+            return stationTracker.Station;
+        }
 
-        if (!_xformQuery.Resolve(ent, ref xform))
-            return;
+        if (HasComp<StationDataComponent>(entity))
+        {
+            // We are the station, just return ourselves.
+            return entity;
+        }
 
-        // Entity is in nullspace or not on a grid
-        if (xform.MapID == MapId.Nullspace || xform.GridUid == null)
+        if (HasComp<MapGridComponent>(entity))
         {
-            SetStation(ent, null);
-            return;
+            // We are the station, just check ourselves.
+            return CompOrNull<StationMemberComponent>(entity)?.Station;
         }
 
-        // Check if the grid is part of a station
-        if (!_stationMemberQuery.TryGetComponent(xform.GridUid.Value, out var stationMember))
+        if (xform.GridUid == EntityUid.Invalid)
         {
-            SetStation(ent, null);
-            return;
+            Log.Debug("Unable to get owning station - GridUid invalid.");
+            return null;
         }
 
-        SetStation(ent, stationMember.Station);
+        return CompOrNull<StationMemberComponent>(xform.GridUid)?.Station;
     }
 
-    /// <summary>
-    /// Sets the station for a StationTrackerComponent.
-    /// </summary>
-    [PublicAPI]
-    public void SetStation(Entity<StationTrackerComponent?> ent, EntityUid? station)
+    public List<EntityUid> GetStations()
     {
-        if (!Resolve(ent, ref ent.Comp))
-            return;
+        var stations = new List<EntityUid>();
+        var query = EntityQueryEnumerator<StationDataComponent>();
+        while (query.MoveNext(out var uid, out _))
+        {
+            stations.Add(uid);
+        }
 
-        if (ent.Comp.Station == station)
-            return;
+        return stations;
+    }
 
-        ent.Comp.Station = station;
-        Dirty(ent);
+    public HashSet<EntityUid> GetStationsSet()
+    {
+        var stations = new HashSet<EntityUid>();
+        var query = EntityQueryEnumerator<StationDataComponent>();
+        while (query.MoveNext(out var uid, out _))
+        {
+            stations.Add(uid);
+        }
+
+        return stations;
+    }
+
+    public List<(string Name, NetEntity Entity)> GetStationNames()
+    {
+        var stations = GetStationsSet();
+        var stats = new List<(string Name, NetEntity Station)>();
+
+        foreach (var weh in stations)
+        {
+            stats.Add((MetaData(weh).EntityName, GetNetEntity(weh)));
+        }
+
+        return stats;
     }
 
     /// <summary>
-    /// Gets the station an entity is currently on, if any.
+    /// Returns the first station that has a grid in a certain map.
+    /// If the map has no stations, null is returned instead.
     /// </summary>
-    [PublicAPI]
-    public EntityUid? GetCurrentStation(Entity<StationTrackerComponent?> ent)
+    /// <remarks>
+    /// If there are multiple stations on a map it is probably arbitrary which one is returned.
+    /// </remarks>
+    public EntityUid? GetStationInMap(MapId map)
     {
-        if (!Resolve(ent, ref ent.Comp, logMissing: false))
-            return null;
+        var query = EntityQueryEnumerator<StationDataComponent>();
+        while (query.MoveNext(out var uid, out var data))
+        {
+            foreach (var gridUid in data.Grids)
+            {
+                if (Transform(gridUid).MapID == map)
+                {
+                    return uid;
+                }
+            }
+        }
 
-        return ent.Comp.Station;
+        return null;
     }
 }
similarity index 59%
rename from Content.Server/Station/StationConfig.cs
rename to Content.Shared/Station/StationConfig.cs
index 8bc0caf1aad19db6dea5385e2746b2f4d8b43883..5bdbf77422bc8cef2759f8db122dd3235f921a9c 100644 (file)
@@ -1,17 +1,15 @@
-using Content.Server.Maps.NameGenerators;
-using JetBrains.Annotations;
-using Robust.Shared.Prototypes;
+using Robust.Shared.Prototypes;
 
-namespace Content.Server.Station;
+namespace Content.Shared.Station;
 
 /// <summary>
 /// A config for a station. Specifies name and component modifications.
 /// </summary>
-[DataDefinition, PublicAPI]
+[DataDefinition]
 public sealed partial class StationConfig
 {
     [DataField("stationProto", required: true)]
-    public string StationPrototype = default!;
+    public EntProtoId StationPrototype;
 
     [DataField("components", required: true)]
     public ComponentRegistry StationComponentOverrides = default!;