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:
14
Content.Shared/Shuttles/BUIStates/DockingInterfaceState.cs
Normal file
14
Content.Shared/Shuttles/BUIStates/DockingInterfaceState.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Shuttles.BUIStates;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class DockingInterfaceState
|
||||
{
|
||||
public Dictionary<NetEntity, List<DockingPortState>> Docks;
|
||||
|
||||
public DockingInterfaceState(Dictionary<NetEntity, List<DockingPortState>> docks)
|
||||
{
|
||||
Docks = docks;
|
||||
}
|
||||
}
|
||||
20
Content.Shared/Shuttles/BUIStates/DockingPortState.cs
Normal file
20
Content.Shared/Shuttles/BUIStates/DockingPortState.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Shuttles.BUIStates;
|
||||
|
||||
/// <summary>
|
||||
/// State of each individual docking port for interface purposes
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class DockingPortState
|
||||
{
|
||||
public string Name = string.Empty;
|
||||
|
||||
public NetCoordinates Coordinates;
|
||||
public Angle Angle;
|
||||
public NetEntity Entity;
|
||||
public bool Connected => GridDockedWith != null;
|
||||
|
||||
public NetEntity? GridDockedWith;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Shuttles.BUIStates;
|
||||
|
||||
/// <summary>
|
||||
/// Wrapper around <see cref="NavInterfaceState"/>
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class NavBoundUserInterfaceState : BoundUserInterfaceState
|
||||
{
|
||||
public NavInterfaceState State;
|
||||
|
||||
public NavBoundUserInterfaceState(NavInterfaceState state)
|
||||
{
|
||||
State = state;
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,9 @@ using Robust.Shared.Serialization;
|
||||
namespace Content.Shared.Shuttles.BUIStates;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
[Virtual]
|
||||
public class RadarConsoleBoundInterfaceState : BoundUserInterfaceState
|
||||
public sealed class NavInterfaceState
|
||||
{
|
||||
public readonly float MaxRange;
|
||||
public float MaxRange;
|
||||
|
||||
/// <summary>
|
||||
/// The relevant coordinates to base the radar around.
|
||||
@@ -19,13 +18,13 @@ public class RadarConsoleBoundInterfaceState : BoundUserInterfaceState
|
||||
/// </summary>
|
||||
public Angle? Angle;
|
||||
|
||||
public readonly List<DockingInterfaceState> Docks;
|
||||
public Dictionary<NetEntity, List<DockingPortState>> Docks;
|
||||
|
||||
public RadarConsoleBoundInterfaceState(
|
||||
public NavInterfaceState(
|
||||
float maxRange,
|
||||
NetCoordinates? coordinates,
|
||||
Angle? angle,
|
||||
List<DockingInterfaceState> docks)
|
||||
Dictionary<NetEntity, List<DockingPortState>> docks)
|
||||
{
|
||||
MaxRange = maxRange;
|
||||
Coordinates = coordinates;
|
||||
@@ -34,20 +33,6 @@ public class RadarConsoleBoundInterfaceState : BoundUserInterfaceState
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// State of each individual docking port for interface purposes
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class DockingInterfaceState
|
||||
{
|
||||
public NetCoordinates Coordinates;
|
||||
public Angle Angle;
|
||||
public NetEntity Entity;
|
||||
public bool Connected;
|
||||
public Color Color;
|
||||
public Color HighlightedColor;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum RadarConsoleUiKey : byte
|
||||
{
|
||||
@@ -0,0 +1,19 @@
|
||||
using Content.Shared.Shuttles.UI.MapObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Shuttles.BUIStates;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class ShuttleBoundUserInterfaceState : BoundUserInterfaceState
|
||||
{
|
||||
public NavInterfaceState NavState;
|
||||
public ShuttleMapInterfaceState MapState;
|
||||
public DockingInterfaceState DockState;
|
||||
|
||||
public ShuttleBoundUserInterfaceState(NavInterfaceState navState, ShuttleMapInterfaceState mapState, DockingInterfaceState dockState)
|
||||
{
|
||||
NavState = navState;
|
||||
MapState = mapState;
|
||||
DockState = dockState;
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
using Content.Shared.Shuttles.Components;
|
||||
using Content.Shared.Shuttles.Systems;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Shuttles.BUIStates;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class ShuttleConsoleBoundInterfaceState : RadarConsoleBoundInterfaceState
|
||||
{
|
||||
/// <summary>
|
||||
/// The current FTL state.
|
||||
/// </summary>
|
||||
public readonly FTLState FTLState;
|
||||
|
||||
/// <summary>
|
||||
/// When the next FTL state change happens.
|
||||
/// </summary>
|
||||
public readonly TimeSpan FTLTime;
|
||||
|
||||
public List<(NetEntity Entity, string Destination, bool Enabled)> Destinations;
|
||||
|
||||
public ShuttleConsoleBoundInterfaceState(
|
||||
FTLState ftlState,
|
||||
TimeSpan ftlTime,
|
||||
List<(NetEntity Entity, string Destination, bool Enabled)> destinations,
|
||||
float maxRange,
|
||||
NetCoordinates? coordinates,
|
||||
Angle? angle,
|
||||
List<DockingInterfaceState> docks) : base(maxRange, coordinates, angle, docks)
|
||||
{
|
||||
FTLState = ftlState;
|
||||
FTLTime = ftlTime;
|
||||
Destinations = destinations;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using Content.Shared.Shuttles.Systems;
|
||||
using Content.Shared.Shuttles.UI.MapObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Shuttles.BUIStates;
|
||||
|
||||
/// <summary>
|
||||
/// Handles BUI data for Map screen.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class ShuttleMapInterfaceState
|
||||
{
|
||||
/// <summary>
|
||||
/// The current FTL state.
|
||||
/// </summary>
|
||||
public readonly FTLState FTLState;
|
||||
|
||||
/// <summary>
|
||||
/// How long the FTL state takes.
|
||||
/// </summary>
|
||||
public float FTLDuration;
|
||||
|
||||
public List<ShuttleBeaconObject> Destinations;
|
||||
|
||||
public List<ShuttleExclusionObject> Exclusions;
|
||||
|
||||
public ShuttleMapInterfaceState(
|
||||
FTLState ftlState,
|
||||
float ftlDuration,
|
||||
List<ShuttleBeaconObject> destinations,
|
||||
List<ShuttleExclusionObject> exclusions)
|
||||
{
|
||||
FTLState = ftlState;
|
||||
FTLDuration = ftlDuration;
|
||||
Destinations = destinations;
|
||||
Exclusions = exclusions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Shuttles.Components;
|
||||
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class FTLDestinationComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Should this destination be restricted in some form from console visibility.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
|
||||
public EntityWhitelist? Whitelist;
|
||||
|
||||
/// <summary>
|
||||
/// Is this destination visible but available to be warped to?
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
|
||||
public bool Enabled = true;
|
||||
|
||||
/// <summary>
|
||||
/// Can we only FTL to beacons on this map.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool BeaconsOnly;
|
||||
}
|
||||
28
Content.Shared/Shuttles/Components/FTLMapComponent.cs
Normal file
28
Content.Shared/Shuttles/Components/FTLMapComponent.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Shared.Shuttles.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Marker that specifies a map as being for FTLing entities.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class FTLMapComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
/// Offset for FTLing shuttles so they don't overlap each other.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public int Index;
|
||||
|
||||
/// <summary>
|
||||
/// What parallax to use for the background, immediately gets deffered to ParallaxComponent.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public string Parallax = "FastSpace";
|
||||
|
||||
/// <summary>
|
||||
/// Can FTL on this map only be done to beacons.
|
||||
/// </summary>
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool Beacons;
|
||||
}
|
||||
@@ -15,10 +15,12 @@ public sealed partial class IFFComponent : Component
|
||||
/// </summary>
|
||||
public const bool ShowIFFDefault = true;
|
||||
|
||||
public static readonly Color SelfColor = Color.MediumSpringGreen;
|
||||
|
||||
/// <summary>
|
||||
/// Default color to use for IFF if no component is found.
|
||||
/// </summary>
|
||||
public static readonly Color IFFColor = Color.Aquamarine;
|
||||
public static readonly Color IFFColor = Color.Gold;
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField]
|
||||
public IFFFlags Flags = IFFFlags.None;
|
||||
|
||||
@@ -22,8 +22,6 @@ namespace Content.Shared.Shuttles.Components
|
||||
[ViewVariables]
|
||||
public EntityCoordinates? Position { get; set; }
|
||||
|
||||
public const float BreakDistance = 0.25f;
|
||||
|
||||
public Vector2 CurTickStrafeMovement = Vector2.Zero;
|
||||
public float CurTickRotationMovement;
|
||||
public float CurTickBraking;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Shuttles.Components;
|
||||
|
||||
/// <summary>
|
||||
/// Shows a parallax background on the shuttle map console.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class ShuttleMapParallaxComponent : Component
|
||||
{
|
||||
public static readonly ResPath FallbackTexture = new ResPath("/Textures/Parallaxes/space_map2.png");
|
||||
|
||||
// TODO: This should ideally be shared with parallax stuff to avoid duplication, for now it's just a texture
|
||||
[DataField, AutoNetworkedField]
|
||||
public ResPath TexturePath;
|
||||
}
|
||||
@@ -3,10 +3,12 @@ using Robust.Shared.Serialization;
|
||||
namespace Content.Shared.Shuttles.Events;
|
||||
|
||||
/// <summary>
|
||||
/// Raised on the client when it's viewing a particular docking port to try and dock it automatically.
|
||||
/// Raised on the client when it's viewing a particular docking port to try and dock it.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class AutodockRequestMessage : BoundUserInterfaceMessage
|
||||
public sealed class DockRequestMessage : BoundUserInterfaceMessage
|
||||
{
|
||||
public NetEntity DockEntity;
|
||||
|
||||
public NetEntity TargetDockEntity;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Shuttles.Events;
|
||||
|
||||
/// <summary>
|
||||
/// Raised on a client when it wishes to FTL to a beacon.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class ShuttleConsoleFTLBeaconMessage : BoundUserInterfaceMessage
|
||||
{
|
||||
public NetEntity Beacon;
|
||||
public Angle Angle;
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Shuttles.Events;
|
||||
@@ -6,7 +7,8 @@ namespace Content.Shared.Shuttles.Events;
|
||||
/// Raised on the client when it wishes to travel somewhere.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class ShuttleConsoleFTLRequestMessage : BoundUserInterfaceMessage
|
||||
public sealed class ShuttleConsoleFTLPositionMessage : BoundUserInterfaceMessage
|
||||
{
|
||||
public NetEntity Destination;
|
||||
public MapCoordinates Coordinates;
|
||||
public Angle Angle;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Shuttles.Events;
|
||||
|
||||
/// <summary>
|
||||
/// Raised on a client when it is no longer viewing a dock.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class StopAutodockRequestMessage : BoundUserInterfaceMessage
|
||||
{
|
||||
public NetEntity DockEntity;
|
||||
}
|
||||
78
Content.Shared/Shuttles/Systems/SharedDockingSystem.cs
Normal file
78
Content.Shared/Shuttles/Systems/SharedDockingSystem.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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]
|
||||
|
||||
7
Content.Shared/Shuttles/UI/MapObjects/GridMapObject.cs
Normal file
7
Content.Shared/Shuttles/UI/MapObjects/GridMapObject.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Content.Shared.Shuttles.UI.MapObjects;
|
||||
|
||||
public record struct GridMapObject : IMapObject
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public EntityUid Entity;
|
||||
}
|
||||
9
Content.Shared/Shuttles/UI/MapObjects/IMapObject.cs
Normal file
9
Content.Shared/Shuttles/UI/MapObjects/IMapObject.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Content.Shared.Shuttles.UI.MapObjects;
|
||||
|
||||
/// <summary>
|
||||
/// Abstract map object representing a grid, beacon etc for use on the map screen.
|
||||
/// </summary>
|
||||
public interface IMapObject
|
||||
{
|
||||
string Name { get; }
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Shuttles.UI.MapObjects;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public readonly record struct ShuttleBeaconObject(NetEntity Entity, NetCoordinates Coordinates, string Name) : IMapObject;
|
||||
@@ -0,0 +1,7 @@
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Shuttles.UI.MapObjects;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public record struct ShuttleExclusionObject(NetCoordinates Coordinates, float Range, string Name = "") : IMapObject;
|
||||
Reference in New Issue
Block a user