178 lines
5.6 KiB
C#
178 lines
5.6 KiB
C#
using Content.Server.Shuttles.Components;
|
|
using Content.Server.Shuttles.Events;
|
|
using Content.Server.Shuttles.Systems;
|
|
using Content.Server.Station.Systems;
|
|
using Content.Shared.DeltaV.Shuttles;
|
|
using Content.Shared.DeltaV.Shuttles.Components;
|
|
using Content.Shared.DeltaV.Shuttles.Systems;
|
|
using Content.Shared.Shuttles.Components;
|
|
using Content.Shared.Shuttles.Systems;
|
|
using Content.Shared.Station.Components;
|
|
using Content.Shared.Timing;
|
|
using Content.Shared.Whitelist;
|
|
using Robust.Shared.Map;
|
|
using Robust.Shared.Map.Components;
|
|
|
|
namespace Content.Server.DeltaV.Shuttles.Systems;
|
|
|
|
public sealed class DockingConsoleSystem : SharedDockingConsoleSystem
|
|
{
|
|
[Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
|
|
[Dependency] private readonly SharedMapSystem _map = default!;
|
|
[Dependency] private readonly SharedUserInterfaceSystem _ui = default!;
|
|
[Dependency] private readonly ShuttleSystem _shuttle = default!;
|
|
[Dependency] private readonly StationSystem _station = default!;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
|
|
SubscribeLocalEvent<DockEvent>(OnDock);
|
|
SubscribeLocalEvent<UndockEvent>(OnUndock);
|
|
|
|
Subs.BuiEvents<DockingConsoleComponent>(DockingConsoleUiKey.Key, subs =>
|
|
{
|
|
subs.Event<BoundUIOpenedEvent>(OnOpened);
|
|
subs.Event<DockingConsoleFTLMessage>(OnFTL);
|
|
});
|
|
}
|
|
|
|
private void OnDock(DockEvent args)
|
|
{
|
|
UpdateConsoles(args.GridAUid, args.GridBUid);
|
|
}
|
|
|
|
private void OnUndock(UndockEvent args)
|
|
{
|
|
UpdateConsoles(args.GridAUid, args.GridBUid);
|
|
}
|
|
|
|
private void OnOpened(Entity<DockingConsoleComponent> ent, ref BoundUIOpenedEvent args)
|
|
{
|
|
if (TerminatingOrDeleted(ent.Comp.Shuttle))
|
|
UpdateShuttle(ent);
|
|
|
|
UpdateUI(ent);
|
|
}
|
|
|
|
private void UpdateConsoles(EntityUid gridA, EntityUid gridB)
|
|
{
|
|
UpdateConsolesUsing(gridA);
|
|
UpdateConsolesUsing(gridB);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Update the UI of every console that is using a certain shuttle.
|
|
/// </summary>
|
|
public void UpdateConsolesUsing(EntityUid shuttle)
|
|
{
|
|
if (!HasComp<DockingShuttleComponent>(shuttle))
|
|
return;
|
|
|
|
var query = EntityQueryEnumerator<DockingConsoleComponent>();
|
|
while (query.MoveNext(out var uid, out var comp))
|
|
{
|
|
if (comp.Shuttle == shuttle)
|
|
UpdateUI((uid, comp));
|
|
}
|
|
}
|
|
|
|
private void UpdateUI(Entity<DockingConsoleComponent> ent)
|
|
{
|
|
if (ent.Comp.Shuttle is not {} shuttle)
|
|
return;
|
|
|
|
var ftlState = FTLState.Available;
|
|
StartEndTime ftlTime = default;
|
|
List<DockingDestination> destinations = new();
|
|
|
|
if (TryComp<FTLComponent>(shuttle, out var ftl))
|
|
{
|
|
ftlState = ftl.State;
|
|
ftlTime = _shuttle.GetStateTime(ftl);
|
|
}
|
|
|
|
if (TryComp<DockingShuttleComponent>(shuttle, out var docking))
|
|
{
|
|
destinations = docking.Destinations;
|
|
}
|
|
|
|
var state = new DockingConsoleState(ftlState, ftlTime, destinations);
|
|
_ui.SetUiState(ent.Owner, DockingConsoleUiKey.Key, state);
|
|
}
|
|
|
|
private void OnFTL(Entity<DockingConsoleComponent> ent, ref DockingConsoleFTLMessage args)
|
|
{
|
|
if (ent.Comp.Shuttle is not {} shuttle || !TryComp<DockingShuttleComponent>(shuttle, out var docking))
|
|
return;
|
|
|
|
if (args.Index < 0 || args.Index > docking.Destinations.Count)
|
|
return;
|
|
|
|
var dest = docking.Destinations[args.Index];
|
|
var map = dest.Map;
|
|
// can't FTL if its already there or somehow failed whitelist
|
|
if (map == Transform(shuttle).MapID || !_shuttle.CanFTLTo(shuttle, map, ent))
|
|
return;
|
|
|
|
if (FindLargestGrid(map) is not {} grid)
|
|
return;
|
|
|
|
Log.Debug($"{ToPrettyString(args.Actor):user} is FTL-docking {ToPrettyString(shuttle):shuttle} to {ToPrettyString(grid):grid}");
|
|
|
|
_shuttle.FTLToDock(shuttle, Comp<ShuttleComponent>(shuttle), grid, priorityTag: ent.Comp.DockTag);
|
|
UpdateUI(ent);
|
|
}
|
|
|
|
private EntityUid? FindLargestGrid(MapId map)
|
|
{
|
|
EntityUid? largestGrid = null;
|
|
var largestSize = 0f;
|
|
|
|
if (_station.GetStationInMap(map) is {} station)
|
|
{
|
|
// prevent picking vgroid and stuff
|
|
return _station.GetLargestGrid(station); // May need to get the StationDataComponent if this doesn't work
|
|
}
|
|
|
|
var query = EntityQueryEnumerator<MapGridComponent, TransformComponent>();
|
|
while (query.MoveNext(out var gridUid, out var grid, out var xform))
|
|
{
|
|
if (xform.MapID != map)
|
|
continue;
|
|
|
|
var size = grid.LocalAABB.Size.LengthSquared();
|
|
if (size < largestSize)
|
|
continue;
|
|
|
|
largestSize = size;
|
|
largestGrid = gridUid;
|
|
}
|
|
|
|
return largestGrid;
|
|
}
|
|
|
|
private void UpdateShuttle(Entity<DockingConsoleComponent> ent)
|
|
{
|
|
var hadShuttle = ent.Comp.HasShuttle;
|
|
// no error if it cant find one since it would fail every test as shuttle.grid_fill is false in dev
|
|
ent.Comp.Shuttle = FindShuttle(ent.Comp.ShuttleWhitelist);
|
|
ent.Comp.HasShuttle = ent.Comp.Shuttle != null;
|
|
|
|
if (ent.Comp.HasShuttle != hadShuttle)
|
|
Dirty(ent);
|
|
}
|
|
|
|
private EntityUid? FindShuttle(EntityWhitelist whitelist)
|
|
{
|
|
var query = EntityQueryEnumerator<DockingShuttleComponent>();
|
|
while (query.MoveNext(out var uid, out _))
|
|
{
|
|
if (_whitelist.IsValid(whitelist, uid))
|
|
return uid;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|