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