Shuttle console + FTL rework (#24430)

* Add shuttle interior drawing back

Just do it per-tile she'll be right, at least it's done with 1 draw call.

* Revamp shuttle console

* Bunch of cleanup work

* Lables sortito

* dok

* Pixel alignment and colours

* Fix a bunch of drawing bugs

* Shuttle map drawing

* Drawing fixes

* Map parallax working finally

* weh

* Commit all my stuff

* mic

* deez

* Update everything

* Xamlify everything

* uh

* Rudimentary blocker range

* My enemies have succeeded

* Bunch of changes to FTL

* Heaps of cleanup

* Fix FTL bugs

* FTL

* weewoo

* FTL fallback

* wew

* weh

* Basic FTL working

* FTL working

* FTL destination fixes

* a

* Exclusion zones

* Fix drawing / FTL

* Beacons working

* Coordinates drawing

* Fix unknown map names

* Dorks beginning

* State + docking cleanup start

* Basic dock drawing

* Bunch of drawing fixes

* Batching / color fixes

* Cleanup and beacons support

* weh

* weh

* Begin pings

* First draft at map objects

* Map fixup

* Faster drawing

* Fix perf + FTL

* Cached drawing

* Fix drawing

* Best I got

* strips

* Back to lists but with caching

* Final optimisation

* Fix dock bounds

* Docking work

* stinker

* kobolds

* Btns

* Docking vis working

* Fix docking pre-vis

* canasses

* Helldivers 2

* a

* Array life

* Fix

* Fix TODOs

* liltenhead feature club

* dorking

* Merge artifacts

* Last-minute touchup
This commit is contained in:
metalgearsloth
2024-03-03 18:39:19 +11:00
committed by GitHub
parent 2ef38f8a62
commit c5486873db
99 changed files with 4896 additions and 2371 deletions

View File

@@ -0,0 +1,78 @@
using Content.Shared.Shuttles.Components;
using Robust.Shared.Map;
namespace Content.Shared.Shuttles.Systems;
public abstract class SharedDockingSystem : EntitySystem
{
[Dependency] protected readonly SharedTransformSystem XformSystem = default!;
public const float DockingHiglightRange = 4f;
public const float DockRange = 1f + 0.2f;
public static readonly double AlignmentTolerance = Angle.FromDegrees(15).Theta;
public bool CanShuttleDock(EntityUid? shuttle)
{
if (shuttle == null)
return false;
return !HasComp<PreventPilotComponent>(shuttle.Value);
}
public bool CanShuttleUndock(EntityUid? shuttle)
{
if (shuttle == null)
return false;
return !HasComp<PreventPilotComponent>(shuttle.Value);
}
public bool CanDock(MapCoordinates mapPosA, Angle worldRotA,
MapCoordinates mapPosB, Angle worldRotB)
{
// Uh oh
if (mapPosA.MapId != mapPosB.MapId)
return false;
return InRange(mapPosA, mapPosB) && InAlignment(mapPosA, worldRotA, mapPosB, worldRotB);
}
public bool InRange(MapCoordinates mapPosA, MapCoordinates mapPosB)
{
return (mapPosA.Position - mapPosB.Position).Length() <= DockRange;
}
public bool InAlignment(MapCoordinates mapPosA, Angle worldRotA, MapCoordinates mapPosB, Angle worldRotB)
{
// Check if the nubs are in line with the two docks.
var worldRotToB = (mapPosB.Position - mapPosA.Position).ToWorldAngle();
var worldRotToA = (mapPosA.Position - mapPosB.Position).ToWorldAngle();
var aDiff = Angle.ShortestDistance((worldRotA - worldRotToB).Reduced(), Angle.Zero);
var bDiff = Angle.ShortestDistance((worldRotB - worldRotToA).Reduced(), Angle.Zero);
if (Math.Abs(aDiff.Theta) > AlignmentTolerance)
return false;
if (Math.Abs(bDiff.Theta) > AlignmentTolerance)
return false;
return true;
}
public bool CanDock(NetCoordinates coordinatesOne, Angle angleOne,
NetCoordinates coordinatesTwo, Angle angleTwo)
{
// TODO: Dump the dock fixtures
var coordsA = GetCoordinates(coordinatesOne);
var coordsB = GetCoordinates(coordinatesTwo);
var mapPosA = XformSystem.ToMapCoordinates(coordsA);
var mapPosB = XformSystem.ToMapCoordinates(coordsB);
var worldRotA = XformSystem.GetWorldRotation(coordsA.EntityId) + angleOne;
var worldRotB = XformSystem.GetWorldRotation(coordsB.EntityId) + angleTwo;
return CanDock(mapPosA, worldRotA, mapPosB, worldRotB);
}
}

View File

@@ -4,7 +4,6 @@ namespace Content.Shared.Shuttles.Systems;
public abstract class SharedRadarConsoleSystem : EntitySystem
{
public const float DefaultMinRange = 64f;
public const float DefaultMaxRange = 256f;
protected virtual void UpdateState(EntityUid uid, RadarConsoleComponent component)

View File

@@ -1,5 +1,6 @@
using Content.Shared.ActionBlocker;
using Content.Shared.Movement.Events;
using Content.Shared.Shuttles.BUIStates;
using Content.Shared.Shuttles.Components;
using Robust.Shared.Serialization;

View File

@@ -11,6 +11,43 @@ public abstract partial class SharedShuttleSystem
protected virtual void UpdateIFFInterfaces(EntityUid gridUid, IFFComponent component) {}
public Color GetIFFColor(EntityUid gridUid, bool self = false, IFFComponent? component = null)
{
if (self)
{
return IFFComponent.SelfColor;
}
if (!Resolve(gridUid, ref component, false))
{
return IFFComponent.IFFColor;
}
return component.Color;
}
public string? GetIFFLabel(EntityUid gridUid, bool self = false, IFFComponent? component = null)
{
if (!IFFComponent.ShowIFFDefault)
{
return null;
}
var entName = MetaData(gridUid).EntityName;
if (self)
{
return entName;
}
if (Resolve(gridUid, ref component, false) && (component.Flags & (IFFFlags.HideLabel | IFFFlags.Hide)) != 0x0)
{
return null;
}
return string.IsNullOrEmpty(entName) ? Loc.GetString("shuttle-console-unknown") : entName;
}
/// <summary>
/// Sets the color for this grid to appear as on radar.
/// </summary>

View File

@@ -1,7 +1,198 @@
using Content.Shared.Shuttles.BUIStates;
using Content.Shared.Shuttles.Components;
using Content.Shared.Shuttles.UI.MapObjects;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Physics.Collision.Shapes;
using Robust.Shared.Physics.Components;
namespace Content.Shared.Shuttles.Systems;
public abstract partial class SharedShuttleSystem : EntitySystem
{
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] protected readonly SharedMapSystem Maps = default!;
[Dependency] protected readonly SharedTransformSystem XformSystem = default!;
public const float FTLRange = 512f;
public const float FTLBufferRange = 8f;
private EntityQuery<MapGridComponent> _gridQuery;
private EntityQuery<PhysicsComponent> _physicsQuery;
private EntityQuery<TransformComponent> _xformQuery;
private List<Entity<MapGridComponent>> _grids = new();
public override void Initialize()
{
base.Initialize();
_gridQuery = GetEntityQuery<MapGridComponent>();
_physicsQuery = GetEntityQuery<PhysicsComponent>();
_xformQuery = GetEntityQuery<TransformComponent>();
}
/// <summary>
/// Returns whether an entity can FTL to the specified map.
/// </summary>
public bool CanFTLTo(EntityUid shuttleUid, MapId targetMap)
{
var mapUid = _mapManager.GetMapEntityId(targetMap);
var shuttleMap = _xformQuery.GetComponent(shuttleUid).MapID;
if (shuttleMap == targetMap)
return true;
if (!TryComp<FTLDestinationComponent>(mapUid, out var destination) ||
!destination.Enabled)
{
return false;
}
if (HasComp<FTLMapComponent>(mapUid))
return false;
return destination.Whitelist?.IsValid(shuttleUid, EntityManager) != false;
}
/// <summary>
/// Gets the list of map objects relevant for the specified map.
/// </summary>
public IEnumerable<(ShuttleExclusionObject Exclusion, MapCoordinates Coordinates)> GetExclusions(MapId mapId, List<ShuttleExclusionObject> exclusions)
{
foreach (var exc in exclusions)
{
var beaconCoords = XformSystem.ToMapCoordinates(GetCoordinates(exc.Coordinates));
if (beaconCoords.MapId != mapId)
continue;
yield return (exc, beaconCoords);
}
}
/// <summary>
/// Gets the list of map objects relevant for the specified map.
/// </summary>
public IEnumerable<(ShuttleBeaconObject Beacon, MapCoordinates Coordinates)> GetBeacons(MapId mapId, List<ShuttleBeaconObject> beacons)
{
foreach (var beacon in beacons)
{
var beaconCoords = XformSystem.ToMapCoordinates(GetCoordinates(beacon.Coordinates));
if (beaconCoords.MapId != mapId)
continue;
yield return (beacon, beaconCoords);
}
}
public bool CanDraw(EntityUid gridUid, PhysicsComponent? physics = null, IFFComponent? iffComp = null)
{
if (!Resolve(gridUid, ref physics))
return true;
if (physics.Mass < 10f)
{
return false;
}
if (!Resolve(gridUid, ref iffComp, false))
{
return true;
}
// Hide it entirely.
return (iffComp.Flags & IFFFlags.Hide) == 0x0;
}
public bool IsBeaconMap(EntityUid mapUid)
{
return TryComp(mapUid, out FTLDestinationComponent? ftlDest) && ftlDest.BeaconsOnly;
}
/// <summary>
/// Returns true if a beacon can be FTLd to.
/// </summary>
public bool CanFTLBeacon(NetCoordinates nCoordinates)
{
// Only beacons parented to map supported.
var coordinates = GetCoordinates(nCoordinates);
return HasComp<MapComponent>(coordinates.EntityId);
}
public float GetFTLRange(EntityUid shuttleUid) => FTLRange;
public float GetFTLBufferRange(EntityUid shuttleUid, MapGridComponent? grid = null)
{
if (!_gridQuery.Resolve(shuttleUid, ref grid))
return 0f;
var localAABB = grid.LocalAABB;
var maxExtent = localAABB.MaxDimension / 2f;
var range = maxExtent + FTLBufferRange;
return range;
}
/// <summary>
/// Returns true if the spot is free to be FTLd to (not close to any objects and in range).
/// </summary>
public bool FTLFree(EntityUid shuttleUid, EntityCoordinates coordinates, Angle angle, List<ShuttleExclusionObject>? exclusionZones)
{
if (!_physicsQuery.TryGetComponent(shuttleUid, out var shuttlePhysics) ||
!_xformQuery.TryGetComponent(shuttleUid, out var shuttleXform))
{
return false;
}
// Just checks if any grids inside of a buffer range at the target position.
_grids.Clear();
var ftlRange = FTLRange;
var mapCoordinates = coordinates.ToMap(EntityManager, XformSystem);
var ourPos = Maps.GetGridPosition((shuttleUid, shuttlePhysics, shuttleXform));
// This is the already adjusted position
var targetPosition = mapCoordinates.Position;
// Check range even if it's cross-map.
if ((targetPosition - ourPos).Length() > FTLRange)
{
return false;
}
// Check exclusion zones.
// This needs to be passed in manually due to PVS.
if (exclusionZones != null)
{
foreach (var exclusion in exclusionZones)
{
var exclusionCoords = XformSystem.ToMapCoordinates(GetCoordinates(exclusion.Coordinates));
if (exclusionCoords.MapId != mapCoordinates.MapId)
continue;
if ((mapCoordinates.Position - exclusionCoords.Position).Length() <= exclusion.Range)
return false;
}
}
var ourFTLBuffer = GetFTLBufferRange(shuttleUid);
var circle = new PhysShapeCircle(ourFTLBuffer + FTLBufferRange, targetPosition);
_mapManager.FindGridsIntersecting(mapCoordinates.MapId, circle, Robust.Shared.Physics.Transform.Empty,
ref _grids, includeMap: false);
// If any grids in range that aren't us then can't FTL.
foreach (var grid in _grids)
{
if (grid.Owner == shuttleUid)
continue;
return false;
}
return true;
}
}
[Flags]