Move some Station methods into shared (#38976)

This commit is contained in:
Nemanja
2025-08-08 11:22:34 -04:00
committed by GitHub
parent 3d9e1f64a9
commit 1374ceea47
41 changed files with 298 additions and 351 deletions

View File

@@ -76,7 +76,7 @@ public sealed partial class ObjectsTab : Control
switch (selection) switch (selection)
{ {
case ObjectsTabSelection.Stations: case ObjectsTabSelection.Stations:
entities.AddRange(_entityManager.EntitySysManager.GetEntitySystem<StationSystem>().Stations); entities.AddRange(_entityManager.EntitySysManager.GetEntitySystem<StationSystem>().GetStationNames());
break; break;
case ObjectsTabSelection.Grids: case ObjectsTabSelection.Grids:
{ {

View File

@@ -2,34 +2,5 @@
namespace Content.Client.Station; namespace Content.Client.Station;
/// <summary> /// <inheritdoc/>
/// This handles letting the client know stations are a thing. Only really used by an admin menu. public sealed partial class StationSystem : SharedStationSystem;
/// </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);
}
}

View File

@@ -2,9 +2,9 @@ using System.Linq;
using Content.Server.GameTicking; using Content.Server.GameTicking;
using Content.Server.Shuttles.Components; using Content.Server.Shuttles.Components;
using Content.Server.Shuttles.Systems; using Content.Server.Shuttles.Systems;
using Content.Server.Station.Components;
using Content.Shared.CCVar; using Content.Shared.CCVar;
using Content.Shared.Shuttles.Components; using Content.Shared.Shuttles.Components;
using Content.Shared.Station.Components;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Map.Components; using Robust.Shared.Map.Components;

View File

@@ -2,15 +2,12 @@ using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using Content.Server.Administration.Components; using Content.Server.Administration.Components;
using Content.Server.Atmos;
using Content.Server.Atmos.Components;
using Content.Server.Cargo.Components; using Content.Server.Cargo.Components;
using Content.Server.Doors.Systems; using Content.Server.Doors.Systems;
using Content.Server.Hands.Systems; using Content.Server.Hands.Systems;
using Content.Server.Power.Components; using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems; using Content.Server.Power.EntitySystems;
using Content.Server.Stack; using Content.Server.Stack;
using Content.Server.Station.Components;
using Content.Server.Station.Systems; using Content.Server.Station.Systems;
using Content.Server.Weapons.Ranged.Systems; using Content.Server.Weapons.Ranged.Systems;
using Content.Shared.Access; using Content.Shared.Access;
@@ -28,6 +25,7 @@ using Content.Shared.Hands.Components;
using Content.Shared.Inventory; using Content.Shared.Inventory;
using Content.Shared.PDA; using Content.Shared.PDA;
using Content.Shared.Stacks; using Content.Shared.Stacks;
using Content.Shared.Station.Components;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Content.Shared.Weapons.Ranged.Components; using Content.Shared.Weapons.Ranged.Components;
using Robust.Server.Physics; using Robust.Server.Physics;

View File

@@ -1,6 +1,5 @@
using Content.Server.Anomaly.Components; using Content.Server.Anomaly.Components;
using Content.Server.Power.EntitySystems; using Content.Server.Power.EntitySystems;
using Content.Server.Station.Components;
using Content.Shared.Anomaly; using Content.Shared.Anomaly;
using Content.Shared.CCVar; using Content.Shared.CCVar;
using Content.Shared.Materials; using Content.Shared.Materials;
@@ -164,8 +163,7 @@ public sealed partial class AnomalySystem
var xform = Transform(uid); var xform = Transform(uid);
if (_station.GetStationInMap(xform.MapID) is not { } station || if (_station.GetStationInMap(xform.MapID) is not { } station ||
!TryComp<StationDataComponent>(station, out var data) || _station.GetLargestGrid(station) is not { } grid)
_station.GetLargestGrid(data) is not { } grid)
{ {
if (xform.GridUid == null) if (xform.GridUid == null)
return; return;

View File

@@ -1,8 +1,8 @@
using System.Linq; using System.Linq;
using Content.Server.Station.Components;
using Content.Shared.Cargo; using Content.Shared.Cargo;
using Content.Shared.Cargo.Components; using Content.Shared.Cargo.Components;
using Content.Shared.Cargo.Prototypes; using Content.Shared.Cargo.Prototypes;
using Content.Shared.Station.Components;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
namespace Content.Server.Cargo.Components; namespace Content.Server.Cargo.Components;

View File

@@ -1,7 +1,6 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using Content.Server.Cargo.Components; using Content.Server.Cargo.Components;
using Content.Server.Station.Components;
using Content.Shared.Cargo; using Content.Shared.Cargo;
using Content.Shared.Cargo.BUI; using Content.Shared.Cargo.BUI;
using Content.Shared.Cargo.Components; using Content.Shared.Cargo.Components;
@@ -13,8 +12,8 @@ using Content.Shared.IdentityManagement;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Labels.Components; using Content.Shared.Labels.Components;
using Content.Shared.Paper; using Content.Shared.Paper;
using Content.Shared.Station.Components;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.Audio;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Timing; using Robust.Shared.Timing;

View File

@@ -3,11 +3,11 @@ using System.Linq;
using Content.Server.Cargo.Components; using Content.Server.Cargo.Components;
using Content.Server.Power.Components; using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems; using Content.Server.Power.EntitySystems;
using Content.Server.Station.Components;
using Content.Shared.Cargo; using Content.Shared.Cargo;
using Content.Shared.Cargo.Components; using Content.Shared.Cargo.Components;
using Content.Shared.DeviceLinking; using Content.Shared.DeviceLinking;
using Content.Shared.Power; using Content.Shared.Power;
using Content.Shared.Station.Components;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Random; using Robust.Shared.Random;
using Robust.Shared.Utility; using Robust.Shared.Utility;

View File

@@ -7,7 +7,6 @@ using Content.Server.Chat.Managers;
using Content.Server.GameTicking; using Content.Server.GameTicking;
using Content.Server.Speech.EntitySystems; using Content.Server.Speech.EntitySystems;
using Content.Server.Speech.Prototypes; using Content.Server.Speech.Prototypes;
using Content.Server.Station.Components;
using Content.Server.Station.Systems; using Content.Server.Station.Systems;
using Content.Shared.ActionBlocker; using Content.Shared.ActionBlocker;
using Content.Shared.Administration; using Content.Shared.Administration;
@@ -21,6 +20,7 @@ using Content.Shared.Mobs.Systems;
using Content.Shared.Players; using Content.Shared.Players;
using Content.Shared.Players.RateLimiting; using Content.Shared.Players.RateLimiting;
using Content.Shared.Radio; using Content.Shared.Radio;
using Content.Shared.Station.Components;
using Content.Shared.Whitelist; using Content.Shared.Whitelist;
using Robust.Server.Player; using Robust.Server.Player;
using Robust.Shared.Audio; using Robust.Shared.Audio;

View File

@@ -1,4 +1,4 @@
using Content.Server.Station.Components; using Content.Shared.Station.Components;
using Robust.Shared.Console; using Robust.Shared.Console;
namespace Content.Server.Commands; namespace Content.Server.Commands;

View File

@@ -1,7 +1,6 @@
using System.Linq; using System.Linq;
using Content.Server.Administration; using Content.Server.Administration;
using Content.Server.EUI; using Content.Server.EUI;
using Content.Server.Station.Components;
using Content.Server.Station.Systems; using Content.Server.Station.Systems;
using Content.Server.StationRecords; using Content.Server.StationRecords;
using Content.Server.StationRecords.Systems; using Content.Server.StationRecords.Systems;
@@ -10,12 +9,12 @@ using Content.Shared.CCVar;
using Content.Shared.CrewManifest; using Content.Shared.CrewManifest;
using Content.Shared.GameTicking; using Content.Shared.GameTicking;
using Content.Shared.Roles; using Content.Shared.Roles;
using Content.Shared.Station.Components;
using Content.Shared.StationRecords; using Content.Shared.StationRecords;
using Robust.Shared.Configuration; using Robust.Shared.Configuration;
using Robust.Shared.Console; using Robust.Shared.Console;
using Robust.Shared.Player; using Robust.Shared.Player;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Server.CrewManifest; namespace Content.Server.CrewManifest;

View File

@@ -1,11 +1,8 @@
using Content.Server.Antag; using Content.Server.Antag;
using Content.Server.Dragon;
using Content.Server.GameTicking.Rules.Components; using Content.Server.GameTicking.Rules.Components;
using Content.Server.Mind; using Content.Server.Mind;
using Content.Server.Roles; using Content.Server.Roles;
using Content.Server.Station.Components;
using Content.Server.Station.Systems; using Content.Server.Station.Systems;
using Content.Shared.CharacterInfo;
using Content.Shared.Localizations; using Content.Shared.Localizations;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
@@ -56,10 +53,9 @@ public sealed class DragonRuleSystem : GameRuleSystem<DragonRuleComponent>
var dragonXform = Transform(dragon); var dragonXform = Transform(dragon);
var station = _station.GetStationInMap(dragonXform.MapID);
EntityUid? stationGrid = null; EntityUid? stationGrid = null;
if (TryComp<StationDataComponent>(station, out var stationData)) if (_station.GetStationInMap(dragonXform.MapID) is { } station)
stationGrid = _station.GetLargestGrid(stationData); stationGrid = _station.GetLargestGrid(station);
if (stationGrid is not null) if (stationGrid is not null)
{ {

View File

@@ -1,14 +1,12 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using Content.Server.GameTicking.Rules.Components;
using Content.Server.Station.Components; using Content.Server.Station.Components;
using Content.Shared.GameTicking.Components; using Content.Shared.GameTicking.Components;
using Content.Shared.Random.Helpers; using Content.Shared.Random.Helpers;
using Robust.Server.GameObjects; using Content.Shared.Station.Components;
using Robust.Shared.Collections; using Robust.Shared.Collections;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Map.Components; using Robust.Shared.Map.Components;
using Robust.Shared.Random;
namespace Content.Server.GameTicking.Rules; namespace Content.Server.GameTicking.Rules;

View File

@@ -24,6 +24,7 @@ using Robust.Shared.Map;
using Robust.Shared.Random; using Robust.Shared.Random;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using System.Linq; using System.Linq;
using Content.Shared.Station.Components;
using Content.Shared.Store.Components; using Content.Shared.Store.Components;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;

View 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.Shuttles.Systems;
using Content.Server.Station.Components; using Content.Server.Station.Components;
using Content.Server.Station.Events; using Content.Server.Station.Events;
using Content.Shared.GameTicking.Components; using Content.Shared.GameTicking.Components;
using Content.Shared.Station.Components;
using Content.Shared.Storage; using Content.Shared.Storage;
using Robust.Shared.Prototypes;
using Robust.Shared.Random; using Robust.Shared.Random;
namespace Content.Server.GameTicking.Rules; namespace Content.Server.GameTicking.Rules;

View File

@@ -58,7 +58,7 @@ public abstract class BaseEntityReplaceVariationPassSystem<TEntComp, TGameRuleCo
Transform(newEnt).LocalRotation = rot; 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) private void QueueReplace(Entity<TransformComponent> ent, List<EntitySpawnEntry> replacements)

View File

@@ -9,7 +9,7 @@ public sealed class EntitySpawnVariationPassSystem : VariationPassSystem<EntityS
{ {
protected override void ApplyVariation(Entity<EntitySpawnVariationPassComponent> ent, ref StationVariationPassEvent args) 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 dirtyMod = Random.NextGaussian(ent.Comp.TilesPerEntityAverage, ent.Comp.TilesPerEntityStdDev);
var trashTiles = Math.Max((int) (totalTiles * (1 / dirtyMod)), 0); var trashTiles = Math.Max((int) (totalTiles * (1 / dirtyMod)), 0);

View File

@@ -15,7 +15,7 @@ public sealed class PuddleMessVariationPassSystem : VariationPassSystem<PuddleMe
protected override void ApplyVariation(Entity<PuddleMessVariationPassComponent> ent, ref StationVariationPassEvent args) 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)) if (!_proto.TryIndex(ent.Comp.RandomPuddleSolutionFill, out var proto))
return; return;

View File

@@ -4,7 +4,6 @@ using Content.Server.GameTicking.Rules.Components;
using Content.Server.Popups; using Content.Server.Popups;
using Content.Server.Roles; using Content.Server.Roles;
using Content.Server.RoundEnd; using Content.Server.RoundEnd;
using Content.Server.Station.Components;
using Content.Server.Station.Systems; using Content.Server.Station.Systems;
using Content.Server.Zombies; using Content.Server.Zombies;
using Content.Shared.GameTicking.Components; using Content.Shared.GameTicking.Components;
@@ -190,7 +189,7 @@ public sealed class ZombieRuleSystem : GameRuleSystem<ZombieRuleComponent>
{ {
foreach (var station in _station.GetStationsSet()) 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); stationGrids.Add(grid);
} }
} }

View File

@@ -1,9 +1,8 @@
using Content.Server.Station;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Utility; using Robust.Shared.Utility;
using System.Diagnostics; using System.Diagnostics;
using System.Numerics; using Content.Shared.Station;
namespace Content.Server.Maps; namespace Content.Server.Maps;

View File

@@ -1,6 +1,6 @@
using Content.Server.Administration; using Content.Server.Administration;
using Content.Server.Station.Components;
using Content.Shared.Administration; using Content.Shared.Administration;
using Content.Shared.Station.Components;
using Robust.Shared.Console; using Robust.Shared.Console;
namespace Content.Server.Nuke.Commands; namespace Content.Server.Nuke.Commands;

View File

@@ -2,9 +2,9 @@ using System.Diagnostics.CodeAnalysis;
using Content.Server.Chat.Systems; using Content.Server.Chat.Systems;
using Content.Server.Fax; using Content.Server.Fax;
using Content.Shared.Fax.Components; using Content.Shared.Fax.Components;
using Content.Server.Station.Components;
using Content.Server.Station.Systems; using Content.Server.Station.Systems;
using Content.Shared.Paper; using Content.Shared.Paper;
using Content.Shared.Station.Components;
using Robust.Shared.Random; using Robust.Shared.Random;
using Robust.Shared.Utility; using Robust.Shared.Utility;

View File

@@ -9,7 +9,6 @@ using Content.Server.GameTicking;
using Content.Server.Screens.Components; using Content.Server.Screens.Components;
using Content.Server.Shuttles.Components; using Content.Server.Shuttles.Components;
using Content.Server.Shuttles.Systems; using Content.Server.Shuttles.Systems;
using Content.Server.Station.Components;
using Content.Server.Station.Systems; using Content.Server.Station.Systems;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.DeviceNetwork; using Content.Shared.DeviceNetwork;
@@ -20,6 +19,7 @@ using Robust.Shared.Player;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Timing; using Robust.Shared.Timing;
using Content.Shared.DeviceNetwork.Components; using Content.Shared.DeviceNetwork.Components;
using Content.Shared.Station.Components;
using Timer = Robust.Shared.Timing.Timer; using Timer = Robust.Shared.Timing.Timer;
namespace Content.Server.RoundEnd namespace Content.Server.RoundEnd
@@ -97,10 +97,10 @@ namespace Content.Server.RoundEnd
/// </summary> /// </summary>
public EntityUid? GetStation() 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) if (data == null)
return null; return null;
var targetGrid = _stationSystem.GetLargestGrid(data); var targetGrid = _stationSystem.GetLargestGrid((uid, data));
return targetGrid == null ? null : Transform(targetGrid.Value).MapUid; return targetGrid == null ? null : Transform(targetGrid.Value).MapUid;
} }

View File

@@ -2,7 +2,6 @@ using System.Numerics;
using Content.Server.Salvage.Expeditions; using Content.Server.Salvage.Expeditions;
using Content.Server.Shuttles.Components; using Content.Server.Shuttles.Components;
using Content.Server.Shuttles.Events; using Content.Server.Shuttles.Events;
using Content.Server.Station.Components;
using Content.Shared.Chat; using Content.Shared.Chat;
using Content.Shared.Humanoid; using Content.Shared.Humanoid;
using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Components;
@@ -10,6 +9,7 @@ using Content.Shared.Mobs.Systems;
using Content.Shared.Salvage.Expeditions; using Content.Shared.Salvage.Expeditions;
using Content.Shared.Shuttles.Components; using Content.Shared.Shuttles.Components;
using Content.Shared.Localizations; using Content.Shared.Localizations;
using Content.Shared.Station.Components;
using Robust.Shared.Map.Components; using Robust.Shared.Map.Components;
using Robust.Shared.Player; using Robust.Shared.Player;

View File

@@ -11,7 +11,6 @@ using Content.Server.Shuttles.Components;
using Content.Server.Shuttles.Events; using Content.Server.Shuttles.Events;
using Content.Server.Spawners.Components; using Content.Server.Spawners.Components;
using Content.Server.Spawners.EntitySystems; using Content.Server.Spawners.EntitySystems;
using Content.Server.Station.Components;
using Content.Server.Station.Events; using Content.Server.Station.Events;
using Content.Server.Station.Systems; using Content.Server.Station.Systems;
using Content.Shared.Administration; using Content.Shared.Administration;
@@ -224,7 +223,7 @@ public sealed class ArrivalsSystem : EntitySystem
if (component.FirstRun) 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; sourceMap = station == null ? null : Transform(station.Value)?.MapUid;
arrivalsDelay += RoundStartFTLDuration; arrivalsDelay += RoundStartFTLDuration;
component.FirstRun = false; 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)) 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; continue;
var tripTime = _shuttles.DefaultTravelTime + _shuttles.DefaultStartupTime; var tripTime = _shuttles.DefaultTravelTime + _shuttles.DefaultStartupTime;
@@ -486,7 +485,7 @@ public sealed class ArrivalsSystem : EntitySystem
// Go to station // Go to station
else else
{ {
var targetGrid = _station.GetLargestGrid(data); var targetGrid = _station.GetLargestGrid(comp.Station);
if (targetGrid != null) if (targetGrid != null)
_shuttles.FTLToDock(uid, shuttle, targetGrid.Value); _shuttles.FTLToDock(uid, shuttle, targetGrid.Value);

View File

@@ -14,7 +14,6 @@ using Content.Server.RoundEnd;
using Content.Server.Screens.Components; using Content.Server.Screens.Components;
using Content.Server.Shuttles.Components; using Content.Server.Shuttles.Components;
using Content.Server.Shuttles.Events; using Content.Server.Shuttles.Events;
using Content.Server.Station.Components;
using Content.Server.Station.Events; using Content.Server.Station.Events;
using Content.Server.Station.Systems; using Content.Server.Station.Systems;
using Content.Shared.Access.Systems; using Content.Shared.Access.Systems;
@@ -181,7 +180,7 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
return; return;
} }
var targetGrid = _station.GetLargestGrid(Comp<StationDataComponent>(station.Value)); var targetGrid = _station.GetLargestGrid(station.Value);
if (targetGrid == null) if (targetGrid == null)
return; return;
@@ -270,7 +269,7 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
return null; return null;
} }
var targetGrid = _station.GetLargestGrid(Comp<StationDataComponent>(stationUid)); var targetGrid = _station.GetLargestGrid(stationUid);
// UHH GOOD LUCK // UHH GOOD LUCK
if (targetGrid == null) if (targetGrid == null)

View File

@@ -1,9 +1,7 @@
using System.Numerics; using System.Numerics;
using Content.Server.Shuttles.Components; using Content.Server.Shuttles.Components;
using Content.Server.Station.Components;
using Content.Server.Station.Events; using Content.Server.Station.Events;
using Content.Shared.CCVar; using Content.Shared.CCVar;
using Content.Shared.Salvage;
using Content.Shared.Shuttles.Components; using Content.Shared.Shuttles.Components;
using Content.Shared.Station.Components; using Content.Shared.Station.Components;
using Robust.Shared.Collections; using Robust.Shared.Collections;
@@ -62,10 +60,7 @@ public sealed partial class ShuttleSystem
if (!_cfg.GetCVar(CCVars.GridFill)) if (!_cfg.GetCVar(CCVars.GridFill))
return; return;
if (!TryComp(uid, out StationDataComponent? dataComp)) var targetGrid = _station.GetLargestGrid(uid);
return;
var targetGrid = _station.GetLargestGrid(dataComp);
if (targetGrid == null) if (targetGrid == null)
return; return;
@@ -165,12 +160,7 @@ public sealed partial class ShuttleSystem
if (!_cfg.GetCVar(CCVars.GridFill)) if (!_cfg.GetCVar(CCVars.GridFill))
return; return;
if (!TryComp<StationDataComponent>(uid, out var data)) var targetGrid = _station.GetLargestGrid(uid);
{
return;
}
var targetGrid = _station.GetLargestGrid(data);
if (targetGrid == null) if (targetGrid == null)
return; return;

View File

@@ -1,15 +1,13 @@
using System.Numerics; using System.Numerics;
using Content.Server.Administration.Logs; using Content.Server.Administration.Logs;
using Content.Server.Singularity.Events; using Content.Server.Singularity.Events;
using Content.Server.Station.Components;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.Ghost;
using Content.Shared.Mind.Components; using Content.Shared.Mind.Components;
using Content.Shared.Singularity.Components; using Content.Shared.Singularity.Components;
using Content.Shared.Singularity.EntitySystems; using Content.Shared.Singularity.EntitySystems;
using Content.Shared.Station.Components;
using Content.Shared.Tag; using Content.Shared.Tag;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Map.Components; using Robust.Shared.Map.Components;
using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Components;

View File

@@ -2,12 +2,12 @@ using System.Diagnostics;
using System.Linq; using System.Linq;
using Content.Server.Administration; using Content.Server.Administration;
using Content.Server.Cargo.Systems; using Content.Server.Cargo.Systems;
using Content.Server.Station.Components;
using Content.Server.Station.Systems; using Content.Server.Station.Systems;
using Content.Shared.Administration; using Content.Shared.Administration;
using Content.Shared.Station;
using Content.Shared.Station.Components;
using Robust.Shared.Toolshed; using Robust.Shared.Toolshed;
using Robust.Shared.Toolshed.Errors; using Robust.Shared.Toolshed.Errors;
using Robust.Shared.Toolshed.Syntax;
using Robust.Shared.Utility; using Robust.Shared.Utility;
namespace Content.Server.Station.Commands; namespace Content.Server.Station.Commands;
@@ -54,7 +54,7 @@ public sealed class StationsCommand : ToolshedCommand
public EntityUid? LargestGrid([PipedArgument] EntityUid input) public EntityUid? LargestGrid([PipedArgument] EntityUid input)
{ {
_station ??= GetSys<StationSystem>(); _station ??= GetSys<StationSystem>();
return _station.GetLargestGrid(Comp<StationDataComponent>(input)); return _station.GetLargestGrid(input);
} }
[CommandImplementation("largestgrid")] [CommandImplementation("largestgrid")]

View File

@@ -1,4 +1,4 @@
using Content.Server.Station.Components; using Content.Shared.Station.Components;
namespace Content.Server.Station.Events; namespace Content.Server.Station.Events;

View File

@@ -20,12 +20,10 @@ public sealed partial class StationBiomeSystem : EntitySystem
private void OnStationPostInit(Entity<StationBiomeComponent> map, ref StationPostInitEvent args) 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; return;
var station = _station.GetLargestGrid(dataComp);
if (station == null) return;
var mapId = Transform(station.Value).MapID; var mapId = Transform(station.Value).MapID;
var mapUid = _map.GetMapOrInvalid(mapId); var mapUid = _map.GetMapOrInvalid(mapId);

View File

@@ -1,4 +1,5 @@
using Content.Server.Station.Components; using Content.Server.Station.Components;
using Content.Shared.Station.Components;
namespace Content.Server.Station.Systems; namespace Content.Server.Station.Systems;

View File

@@ -3,20 +3,16 @@ using Content.Server.Chat.Systems;
using Content.Server.GameTicking; using Content.Server.GameTicking;
using Content.Server.Station.Components; using Content.Server.Station.Components;
using Content.Server.Station.Events; using Content.Server.Station.Events;
using Content.Shared.CCVar;
using Content.Shared.Station; using Content.Shared.Station;
using Content.Shared.Station.Components; using Content.Shared.Station.Components;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Server.GameObjects;
using Robust.Server.GameStates; using Robust.Server.GameStates;
using Robust.Server.Player; using Robust.Server.Player;
using Robust.Shared.Collections; using Robust.Shared.Collections;
using Robust.Shared.Configuration;
using Robust.Shared.Enums; using Robust.Shared.Enums;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Map.Components; using Robust.Shared.Map.Components;
using Robust.Shared.Player; using Robust.Shared.Player;
using Robust.Shared.Random;
using Robust.Shared.Utility; using Robust.Shared.Utility;
namespace Content.Server.Station.Systems; namespace Content.Server.Station.Systems;
@@ -34,7 +30,6 @@ public sealed partial class StationSystem : SharedStationSystem
[Dependency] private readonly ChatSystem _chatSystem = default!; [Dependency] private readonly ChatSystem _chatSystem = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!; [Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly MetaDataSystem _metaData = default!; [Dependency] private readonly MetaDataSystem _metaData = default!;
[Dependency] private readonly MapSystem _map = default!;
[Dependency] private readonly PvsOverrideSystem _pvsOverride = default!; [Dependency] private readonly PvsOverrideSystem _pvsOverride = default!;
private ISawmill _sawmill = default!; private ISawmill _sawmill = default!;
@@ -42,8 +37,8 @@ public sealed partial class StationSystem : SharedStationSystem
private EntityQuery<MapGridComponent> _gridQuery; private EntityQuery<MapGridComponent> _gridQuery;
private EntityQuery<TransformComponent> _xformQuery; private EntityQuery<TransformComponent> _xformQuery;
private ValueList<MapId> _mapIds = new(); private ValueList<MapId> _mapIds;
private ValueList<(Box2Rotated Bounds, MapId MapId)> _gridBounds = new(); private ValueList<(Box2Rotated Bounds, MapId MapId)> _gridBounds;
/// <inheritdoc/> /// <inheritdoc/>
public override void Initialize() public override void Initialize()
@@ -79,6 +74,7 @@ public sealed partial class StationSystem : SharedStationSystem
return; return;
stationData.Grids.Remove(uid); stationData.Grids.Remove(uid);
Dirty(uid, component);
} }
public override void Shutdown() public override void Shutdown()
@@ -193,44 +189,6 @@ public sealed partial class StationSystem : SharedStationSystem
#endregion Event handlers #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> /// <summary>
/// Tries to retrieve a filter for everything in the station the source is on. /// Tries to retrieve a filter for everything in the station the source is on.
/// </summary> /// </summary>
@@ -384,6 +342,7 @@ public sealed partial class StationSystem : SharedStationSystem
var stationMember = EnsureComp<StationMemberComponent>(mapGrid); var stationMember = EnsureComp<StationMemberComponent>(mapGrid);
stationMember.Station = station; stationMember.Station = station;
stationData.Grids.Add(mapGrid); stationData.Grids.Add(mapGrid);
Dirty(station, stationData);
RaiseLocalEvent(station, new StationGridAddedEvent(mapGrid, station, false), true); RaiseLocalEvent(station, new StationGridAddedEvent(mapGrid, station, false), true);
@@ -407,6 +366,7 @@ public sealed partial class StationSystem : SharedStationSystem
RemComp<StationMemberComponent>(mapGrid); RemComp<StationMemberComponent>(mapGrid);
stationData.Grids.Remove(mapGrid); stationData.Grids.Remove(mapGrid);
Dirty(station, stationData);
RaiseLocalEvent(station, new StationGridRemovedEvent(mapGrid, station), true); RaiseLocalEvent(station, new StationGridRemovedEvent(mapGrid, station), true);
_sawmill.Info($"Removing grid {mapGrid} from station {Name(station)} ({station})"); _sawmill.Info($"Removing grid {mapGrid} from station {Name(station)} ({station})");
@@ -450,110 +410,6 @@ public sealed partial class StationSystem : SharedStationSystem
QueueDel(station); 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> /// <summary>

View File

@@ -1,7 +1,7 @@
using Content.Server.Anomaly; using Content.Server.Anomaly;
using Content.Server.Station.Components;
using Content.Server.StationEvents.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; namespace Content.Server.StationEvents.Events;
@@ -31,7 +31,7 @@ public sealed class AnomalySpawnRule : StationEventSystem<AnomalySpawnRuleCompon
if (!TryComp<StationDataComponent>(chosenStation, out var stationData)) if (!TryComp<StationDataComponent>(chosenStation, out var stationData))
return; return;
var grid = StationSystem.GetLargestGrid(stationData); var grid = StationSystem.GetLargestGrid((chosenStation.Value, stationData));
if (grid is null) if (grid is null)
return; return;

View File

@@ -2,9 +2,9 @@ using System.Linq;
using Content.Server.Cargo.Components; using Content.Server.Cargo.Components;
using Content.Server.Cargo.Systems; using Content.Server.Cargo.Systems;
using Content.Server.GameTicking; using Content.Server.GameTicking;
using Content.Server.Station.Components;
using Content.Server.StationEvents.Components; using Content.Server.StationEvents.Components;
using Content.Shared.GameTicking.Components; using Content.Shared.GameTicking.Components;
using Content.Shared.Station.Components;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
namespace Content.Server.StationEvents.Events; namespace Content.Server.StationEvents.Events;

View File

@@ -1,7 +1,6 @@
using System.Numerics; using System.Numerics;
using Content.Server.Chat.Systems; using Content.Server.Chat.Systems;
using Content.Server.GameTicking.Rules; using Content.Server.GameTicking.Rules;
using Content.Server.Station.Components;
using Content.Server.Station.Systems; using Content.Server.Station.Systems;
using Content.Server.StationEvents.Components; using Content.Server.StationEvents.Components;
using Content.Shared.GameTicking.Components; using Content.Shared.GameTicking.Components;
@@ -49,7 +48,7 @@ public sealed class MeteorSwarmSystem : GameRuleSystem<MeteorSwarmComponent>
return; return;
var station = RobustRandom.Pick(_station.GetStations()); var station = RobustRandom.Pick(_station.GetStations());
if (_station.GetLargestGrid(Comp<StationDataComponent>(station)) is not { } grid) if (_station.GetLargestGrid(station) is not { } grid)
return; return;
var mapId = Transform(grid).MapID; var mapId = Transform(grid).MapID;

View File

@@ -1,6 +1,4 @@
using Content.Server.Antag; using Content.Server.Antag;
using Content.Server.GameTicking.Rules.Components;
using Content.Server.Station.Components;
using Content.Server.StationEvents.Components; using Content.Server.StationEvents.Components;
using Content.Shared.GameTicking.Components; using Content.Shared.GameTicking.Components;
using Robust.Shared.Map; using Robust.Shared.Map;
@@ -32,10 +30,8 @@ public sealed class SpaceSpawnRule : StationEventSystem<SpaceSpawnRuleComponent>
return; return;
} }
var stationData = Comp<StationDataComponent>(station.Value);
// find a station grid // find a station grid
var gridUid = StationSystem.GetLargestGrid(stationData); var gridUid = StationSystem.GetLargestGrid(station.Value);
if (gridUid == null || !TryComp<MapGridComponent>(gridUid, out var grid)) if (gridUid == null || !TryComp<MapGridComponent>(gridUid, out var grid))
{ {
Sawmill.Warning("Chosen station has no grids, cannot pick location for {ToPrettyString(uid):rule}"); Sawmill.Warning("Chosen station has no grids, cannot pick location for {ToPrettyString(uid):rule}");

View File

@@ -1,26 +1,23 @@
using Content.Server.Shuttles.Systems; using Robust.Shared.GameStates;
using Content.Server.Station.Systems;
using Robust.Shared.Serialization.TypeSerializers.Implementations;
using Robust.Shared.Utility;
namespace Content.Server.Station.Components; namespace Content.Shared.Station.Components;
/// <summary> /// <summary>
/// Stores core information about a station, namely its config and associated grids. /// Stores core information about a station, namely its config and associated grids.
/// All station entities will have this component. /// All station entities will have this component.
/// </summary> /// </summary>
[RegisterComponent, Access(typeof(StationSystem))] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(SharedStationSystem))]
public sealed partial class StationDataComponent : Component public sealed partial class StationDataComponent : Component
{ {
/// <summary> /// <summary>
/// The game map prototype, if any, associated with this station. /// The game map prototype, if any, associated with this station.
/// </summary> /// </summary>
[DataField("stationConfig")] [DataField]
public StationConfig? StationConfig = null; public StationConfig? StationConfig;
/// <summary> /// <summary>
/// List of all grids this station is part of. /// List of all grids this station is part of.
/// </summary> /// </summary>
[DataField("grids")] [DataField, AutoNetworkedField]
public HashSet<EntityUid> Grids = new(); public HashSet<EntityUid> Grids = new();
} }

View File

@@ -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);
}
}

View File

@@ -1,11 +1,14 @@
using System.Linq;
using Content.Shared.Station.Components; using Content.Shared.Station.Components;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Map.Components;
namespace Content.Shared.Station; namespace Content.Shared.Station;
public abstract partial class SharedStationSystem : EntitySystem public abstract partial class SharedStationSystem : EntitySystem
{ {
[Dependency] private readonly SharedMapSystem _map = default!;
[Dependency] private readonly MetaDataSystem _meta = default!; [Dependency] private readonly MetaDataSystem _meta = default!;
private EntityQuery<TransformComponent> _xformQuery; private EntityQuery<TransformComponent> _xformQuery;
@@ -16,96 +19,164 @@ public abstract partial class SharedStationSystem : EntitySystem
{ {
base.Initialize(); base.Initialize();
InitializeTracker();
_xformQuery = GetEntityQuery<TransformComponent>(); _xformQuery = GetEntityQuery<TransformComponent>();
_stationMemberQuery = GetEntityQuery<StationMemberComponent>(); _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)
{
_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> /// <summary>
/// Updates the station tracker component based on entity's current location. /// Gets the largest member grid from a station.
/// </summary> /// </summary>
[PublicAPI] public EntityUid? GetLargestGrid(Entity<StationDataComponent?> ent)
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)) if (!Resolve(ent, ref ent.Comp))
return; return null;
if (ent.Comp.Station == station) EntityUid? largestGrid = null;
return; Box2 largestBounds = new Box2();
ent.Comp.Station = station; foreach (var gridUid in ent.Comp.Grids)
Dirty(ent); {
if (!TryComp<MapGridComponent>(gridUid, out var grid) ||
grid.LocalAABB.Size.LengthSquared() < largestBounds.Size.LengthSquared())
continue;
largestBounds = grid.LocalAABB;
largestGrid = gridUid;
}
return largestGrid;
} }
/// <summary> /// <summary>
/// Gets the station an entity is currently on, if any. /// Returns the total number of tiles contained in the station's grids.
/// </summary> /// </summary>
[PublicAPI] public int GetTileCount(Entity<StationDataComponent?> ent)
public EntityUid? GetCurrentStation(Entity<StationTrackerComponent?> ent)
{ {
if (!Resolve(ent, ref ent.Comp, logMissing: false)) if (!Resolve(ent, ref ent.Comp))
return 0;
var count = 0;
foreach (var gridUid in ent.Comp.Grids)
{
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 null;
return ent.Comp.Station; 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<StationTrackerComponent>(entity, out var stationTracker))
{
// We have a specific station we are tracking and are tethered to.
return stationTracker.Station;
}
if (HasComp<StationDataComponent>(entity))
{
// We are the station, just return ourselves.
return entity;
}
if (HasComp<MapGridComponent>(entity))
{
// 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;
} }
} }

View File

@@ -1,17 +1,15 @@
using Content.Server.Maps.NameGenerators; using Robust.Shared.Prototypes;
using JetBrains.Annotations;
using Robust.Shared.Prototypes;
namespace Content.Server.Station; namespace Content.Shared.Station;
/// <summary> /// <summary>
/// A config for a station. Specifies name and component modifications. /// A config for a station. Specifies name and component modifications.
/// </summary> /// </summary>
[DataDefinition, PublicAPI] [DataDefinition]
public sealed partial class StationConfig public sealed partial class StationConfig
{ {
[DataField("stationProto", required: true)] [DataField("stationProto", required: true)]
public string StationPrototype = default!; public EntProtoId StationPrototype;
[DataField("components", required: true)] [DataField("components", required: true)]
public ComponentRegistry StationComponentOverrides = default!; public ComponentRegistry StationComponentOverrides = default!;