Move some Station methods into shared (#38976)
This commit is contained in:
@@ -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)
|
||||
{
|
||||
_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.
|
||||
/// Gets the largest member grid from a station.
|
||||
/// </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)
|
||||
public EntityUid? GetLargestGrid(Entity<StationDataComponent?> ent)
|
||||
{
|
||||
if (!Resolve(ent, ref ent.Comp))
|
||||
return;
|
||||
return null;
|
||||
|
||||
if (ent.Comp.Station == station)
|
||||
return;
|
||||
EntityUid? largestGrid = null;
|
||||
Box2 largestBounds = new Box2();
|
||||
|
||||
ent.Comp.Station = station;
|
||||
Dirty(ent);
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the station an entity is currently on, if any.
|
||||
/// Returns the total number of tiles contained in the station's grids.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public EntityUid? GetCurrentStation(Entity<StationTrackerComponent?> ent)
|
||||
public int GetTileCount(Entity<StationDataComponent?> 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 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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user