using System.Diagnostics.CodeAnalysis; using Content.Shared.Station.Components; using JetBrains.Annotations; using Robust.Shared.Collections; using Robust.Shared.Map; using Robust.Shared.Map.Components; namespace Content.Shared.Station.Systems; public abstract partial class StationSystem { /// /// Utility function for finding a random event-eligible station entity /// TODO: Make calls of this use the below method with T = StationEventEligibleComponent and make this a lookup for NO T versions of stations!!! /// [PublicAPI] [Obsolete($"Use TryGetRandomStation instead using {nameof(StationEventEligibleComponent)}!")] public bool TryGetRandomStation([NotNullWhen(true)] out Entity? station, Func? filter = null) { var stations = new ValueList>(Count()); filter ??= _ => true; var query = AllEntityQuery(); while (query.MoveNext(out var uid, out _, out var data)) { if (!filter(uid)) continue; stations.Add((uid, data)); } if (stations.Count == 0) { station = null; return false; } // TODO: Engine PR. station = stations[Random.Next(stations.Count)]; return true; } /// /// Tries to get a random station with a given component. /// /// Station we are returning. /// Optional filter. /// Component we are querying for. /// Station Entity if it exists [PublicAPI] public bool TryGetRandomStation([NotNullWhen(true)] out Entity? station, Func? filter = null) where T : IComponent { var stations = new ValueList>(Count()); filter ??= _ => true; var query = AllEntityQuery(); while (query.MoveNext(out var uid, out var comp, out var data)) { if (!filter(uid)) continue; stations.Add((uid, data, comp)); } if (stations.Count == 0) { station = null; return false; } // TODO: Engine PR. station = stations[Random.Next(stations.Count)]; return true; } [PublicAPI] public bool TryFindRandomTile(out Vector2i tile, [NotNullWhen(true)] out Entity? targetStation, [NotNullWhen(true)] out Entity? targetGrid, out EntityCoordinates targetCoords) { tile = default; targetStation = null; targetGrid = null; targetCoords = EntityCoordinates.Invalid; if (TryGetRandomStation(out targetStation)) { return TryFindRandomTileOnStation(targetStation.Value, out tile, out targetGrid, out targetCoords); } return false; } /// /// Returns a random tile on a random station with the given T component. /// /// Tile returned. /// Station returned /// Station grid with the tile. /// Coordinates of the tile. /// Component we query for the station! /// True if all of the above were found [PublicAPI] public bool TryFindRandomTile(out Vector2i tile, [NotNullWhen(true)] out Entity? targetStation, [NotNullWhen(true)] out Entity? targetGrid, out EntityCoordinates targetCoords) where T : IComponent { tile = default; targetStation = null; targetGrid = null; targetCoords = EntityCoordinates.Invalid; return TryGetRandomStation(out targetStation) && TryFindRandomTileOnStation(targetStation.Value, out tile, out targetGrid, out targetCoords); } [PublicAPI] public virtual bool TryFindRandomTileOnStation(Entity station, out Vector2i tile, [NotNullWhen(true)] out Entity? targetGrid, out EntityCoordinates targetCoords, int numAttempts = 10) { tile = default; targetCoords = EntityCoordinates.Invalid; targetGrid = null; return false; } }