Add FTL arrival visuals (#29402)
* Add FTL arrival visuals * weh * Update Content.Shared/Shuttles/Components/FTLComponent.cs Co-authored-by: Tayrtahn <tayrtahn@gmail.com> --------- Co-authored-by: Tayrtahn <tayrtahn@gmail.com>
This commit is contained in:
82
Content.Client/Shuttles/FtlArrivalOverlay.cs
Normal file
82
Content.Client/Shuttles/FtlArrivalOverlay.cs
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
using System.Numerics;
|
||||||
|
using Content.Shared.Shuttles.Components;
|
||||||
|
using Robust.Client.GameObjects;
|
||||||
|
using Robust.Client.Graphics;
|
||||||
|
using Robust.Shared.Enums;
|
||||||
|
using Robust.Shared.Map.Components;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
|
namespace Content.Client.Shuttles;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Plays a visualization whenever a shuttle is arriving from FTL.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class FtlArrivalOverlay : Overlay
|
||||||
|
{
|
||||||
|
public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowEntities;
|
||||||
|
|
||||||
|
private EntityLookupSystem _lookups;
|
||||||
|
private SharedMapSystem _maps;
|
||||||
|
private SharedTransformSystem _transforms;
|
||||||
|
private SpriteSystem _sprites;
|
||||||
|
[Dependency] private readonly IEntityManager _entManager = default!;
|
||||||
|
[Dependency] private readonly IGameTiming _timing = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _protos = default!;
|
||||||
|
|
||||||
|
private readonly HashSet<Entity<FtlVisualizerComponent>> _visualizers = new();
|
||||||
|
|
||||||
|
private ShaderInstance _shader;
|
||||||
|
|
||||||
|
public FtlArrivalOverlay()
|
||||||
|
{
|
||||||
|
IoCManager.InjectDependencies(this);
|
||||||
|
_lookups = _entManager.System<EntityLookupSystem>();
|
||||||
|
_transforms = _entManager.System<SharedTransformSystem>();
|
||||||
|
_maps = _entManager.System<SharedMapSystem>();
|
||||||
|
_sprites = _entManager.System<SpriteSystem>();
|
||||||
|
|
||||||
|
_shader = _protos.Index<ShaderPrototype>("unshaded").Instance();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool BeforeDraw(in OverlayDrawArgs args)
|
||||||
|
{
|
||||||
|
_visualizers.Clear();
|
||||||
|
_lookups.GetEntitiesOnMap(args.MapId, _visualizers);
|
||||||
|
|
||||||
|
return _visualizers.Count > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Draw(in OverlayDrawArgs args)
|
||||||
|
{
|
||||||
|
args.WorldHandle.UseShader(_shader);
|
||||||
|
|
||||||
|
foreach (var (uid, comp) in _visualizers)
|
||||||
|
{
|
||||||
|
var grid = comp.Grid;
|
||||||
|
|
||||||
|
if (!_entManager.TryGetComponent(grid, out MapGridComponent? mapGrid))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var texture = _sprites.GetFrame(comp.Sprite, TimeSpan.FromSeconds(comp.Elapsed), loop: false);
|
||||||
|
comp.Elapsed += (float) _timing.FrameTime.TotalSeconds;
|
||||||
|
|
||||||
|
// Need to manually transform the viewport in terms of the visualizer entity as the grid isn't in position.
|
||||||
|
var (_, _, worldMatrix, invMatrix) = _transforms.GetWorldPositionRotationMatrixWithInv(uid);
|
||||||
|
args.WorldHandle.SetTransform(worldMatrix);
|
||||||
|
var localAABB = invMatrix.TransformBox(args.WorldBounds);
|
||||||
|
|
||||||
|
var tilesEnumerator = _maps.GetLocalTilesEnumerator(grid, mapGrid, localAABB);
|
||||||
|
|
||||||
|
while (tilesEnumerator.MoveNext(out var tile))
|
||||||
|
{
|
||||||
|
var bounds = _lookups.GetLocalBounds(tile, mapGrid.TileSize);
|
||||||
|
|
||||||
|
args.WorldHandle.DrawTextureRect(texture, bounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
args.WorldHandle.UseShader(null);
|
||||||
|
args.WorldHandle.SetTransform(Matrix3x2.Identity);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,9 +38,8 @@ public sealed partial class ShuttleSystem : SharedShuttleSystem
|
|||||||
private bool _enableShuttlePosition;
|
private bool _enableShuttlePosition;
|
||||||
private EmergencyShuttleOverlay? _overlay;
|
private EmergencyShuttleOverlay? _overlay;
|
||||||
|
|
||||||
public override void Initialize()
|
private void InitializeEmergency()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
|
||||||
SubscribeNetworkEvent<EmergencyShuttlePositionMessage>(OnShuttlePosMessage);
|
SubscribeNetworkEvent<EmergencyShuttlePositionMessage>(OnShuttlePosMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
21
Content.Client/Shuttles/Systems/ShuttleSystem.cs
Normal file
21
Content.Client/Shuttles/Systems/ShuttleSystem.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using Robust.Client.Graphics;
|
||||||
|
|
||||||
|
namespace Content.Client.Shuttles.Systems;
|
||||||
|
|
||||||
|
public sealed partial class ShuttleSystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly IOverlayManager _overlays = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
InitializeEmergency();
|
||||||
|
_overlays.AddOverlay(new FtlArrivalOverlay());
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Shutdown()
|
||||||
|
{
|
||||||
|
base.Shutdown();
|
||||||
|
_overlays.RemoveOverlay<FtlArrivalOverlay>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -82,6 +82,8 @@ public sealed partial class ShuttleSystem
|
|||||||
private void InitializeFTL()
|
private void InitializeFTL()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<StationPostInitEvent>(OnStationPostInit);
|
SubscribeLocalEvent<StationPostInitEvent>(OnStationPostInit);
|
||||||
|
SubscribeLocalEvent<FTLComponent, ComponentShutdown>(OnFtlShutdown);
|
||||||
|
|
||||||
_bodyQuery = GetEntityQuery<BodyComponent>();
|
_bodyQuery = GetEntityQuery<BodyComponent>();
|
||||||
_buckleQuery = GetEntityQuery<BuckleComponent>();
|
_buckleQuery = GetEntityQuery<BuckleComponent>();
|
||||||
_beaconQuery = GetEntityQuery<FTLBeaconComponent>();
|
_beaconQuery = GetEntityQuery<FTLBeaconComponent>();
|
||||||
@@ -98,6 +100,12 @@ public sealed partial class ShuttleSystem
|
|||||||
_cfg.OnValueChanged(CCVars.HyperspaceKnockdownTime, time => _hyperspaceKnockdownTime = TimeSpan.FromSeconds(time), true);
|
_cfg.OnValueChanged(CCVars.HyperspaceKnockdownTime, time => _hyperspaceKnockdownTime = TimeSpan.FromSeconds(time), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnFtlShutdown(Entity<FTLComponent> ent, ref ComponentShutdown args)
|
||||||
|
{
|
||||||
|
Del(ent.Comp.VisualizerEntity);
|
||||||
|
ent.Comp.VisualizerEntity = null;
|
||||||
|
}
|
||||||
|
|
||||||
private void OnStationPostInit(ref StationPostInitEvent ev)
|
private void OnStationPostInit(ref StationPostInitEvent ev)
|
||||||
{
|
{
|
||||||
// Add all grid maps as ftl destinations that anyone can FTL to.
|
// Add all grid maps as ftl destinations that anyone can FTL to.
|
||||||
@@ -422,8 +430,16 @@ public sealed partial class ShuttleSystem
|
|||||||
var comp = entity.Comp1;
|
var comp = entity.Comp1;
|
||||||
comp.StateTime = StartEndTime.FromCurTime(_gameTiming, DefaultArrivalTime);
|
comp.StateTime = StartEndTime.FromCurTime(_gameTiming, DefaultArrivalTime);
|
||||||
comp.State = FTLState.Arriving;
|
comp.State = FTLState.Arriving;
|
||||||
// TODO: Arrival effects
|
|
||||||
// For now we'll just use the ss13 bubbles but we can do fancier.
|
if (entity.Comp1.VisualizerProto != null)
|
||||||
|
{
|
||||||
|
comp.VisualizerEntity = SpawnAtPosition(entity.Comp1.VisualizerProto, entity.Comp1.TargetCoordinates);
|
||||||
|
var visuals = Comp<FtlVisualizerComponent>(comp.VisualizerEntity.Value);
|
||||||
|
visuals.Grid = entity.Owner;
|
||||||
|
Dirty(comp.VisualizerEntity.Value, visuals);
|
||||||
|
_transform.SetLocalRotation(comp.VisualizerEntity.Value, entity.Comp1.TargetAngle);
|
||||||
|
_pvs.AddGlobalOverride(comp.VisualizerEntity.Value);
|
||||||
|
}
|
||||||
|
|
||||||
_thruster.DisableLinearThrusters(shuttle);
|
_thruster.DisableLinearThrusters(shuttle);
|
||||||
_thruster.EnableLinearThrustDirection(shuttle, DirectionFlag.South);
|
_thruster.EnableLinearThrustDirection(shuttle, DirectionFlag.South);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ using Content.Shared.Shuttles.Systems;
|
|||||||
using Content.Shared.Throwing;
|
using Content.Shared.Throwing;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
|
using Robust.Server.GameStates;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
using Robust.Shared.Audio.Systems;
|
using Robust.Shared.Audio.Systems;
|
||||||
using Robust.Shared.Configuration;
|
using Robust.Shared.Configuration;
|
||||||
@@ -40,6 +41,7 @@ public sealed partial class ShuttleSystem : SharedShuttleSystem
|
|||||||
[Dependency] private readonly FixtureSystem _fixtures = default!;
|
[Dependency] private readonly FixtureSystem _fixtures = default!;
|
||||||
[Dependency] private readonly MapLoaderSystem _loader = default!;
|
[Dependency] private readonly MapLoaderSystem _loader = default!;
|
||||||
[Dependency] private readonly MetaDataSystem _metadata = default!;
|
[Dependency] private readonly MetaDataSystem _metadata = default!;
|
||||||
|
[Dependency] private readonly PvsOverrideSystem _pvs = default!;
|
||||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||||
[Dependency] private readonly SharedMapSystem _maps = default!;
|
[Dependency] private readonly SharedMapSystem _maps = default!;
|
||||||
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
|
||||||
|
|||||||
@@ -2,16 +2,16 @@ using Content.Shared.Shuttles.Systems;
|
|||||||
using Content.Shared.Tag;
|
using Content.Shared.Tag;
|
||||||
using Content.Shared.Timing;
|
using Content.Shared.Timing;
|
||||||
using Robust.Shared.Audio;
|
using Robust.Shared.Audio;
|
||||||
|
using Robust.Shared.GameStates;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
|
||||||
|
|
||||||
namespace Content.Server.Shuttles.Components;
|
namespace Content.Shared.Shuttles.Components;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Added to a component when it is queued or is travelling via FTL.
|
/// Added to a component when it is queued or is travelling via FTL.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[RegisterComponent]
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||||
public sealed partial class FTLComponent : Component
|
public sealed partial class FTLComponent : Component
|
||||||
{
|
{
|
||||||
// TODO Full game save / add datafields
|
// TODO Full game save / add datafields
|
||||||
@@ -29,13 +29,19 @@ public sealed partial class FTLComponent : Component
|
|||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
public float TravelTime = 0f;
|
public float TravelTime = 0f;
|
||||||
|
|
||||||
|
[DataField]
|
||||||
|
public EntProtoId? VisualizerProto = "FtlVisualizerEntity";
|
||||||
|
|
||||||
|
[DataField, AutoNetworkedField]
|
||||||
|
public EntityUid? VisualizerEntity;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Coordinates to arrive it: May be relative to another grid (for docking) or map coordinates.
|
/// Coordinates to arrive it: May be relative to another grid (for docking) or map coordinates.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadWrite), DataField]
|
[DataField, AutoNetworkedField]
|
||||||
public EntityCoordinates TargetCoordinates;
|
public EntityCoordinates TargetCoordinates;
|
||||||
|
|
||||||
[DataField]
|
[DataField, AutoNetworkedField]
|
||||||
public Angle TargetAngle;
|
public Angle TargetAngle;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
23
Content.Shared/Shuttles/Components/FtlVisualizerComponent.cs
Normal file
23
Content.Shared/Shuttles/Components/FtlVisualizerComponent.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
|
namespace Content.Shared.Shuttles.Components;
|
||||||
|
|
||||||
|
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||||
|
public sealed partial class FtlVisualizerComponent : Component
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Clientside time tracker for the animation.
|
||||||
|
/// </summary>
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
public float Elapsed;
|
||||||
|
|
||||||
|
[DataField(required: true)]
|
||||||
|
public SpriteSpecifier.Rsi Sprite;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Target grid to pull FTL visualization from.
|
||||||
|
/// </summary>
|
||||||
|
[DataField, AutoNetworkedField]
|
||||||
|
public EntityUid Grid;
|
||||||
|
}
|
||||||
12
Resources/Prototypes/Entities/Effects/shuttle.yml
Normal file
12
Resources/Prototypes/Entities/Effects/shuttle.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
- type: entity
|
||||||
|
id: FtlVisualizerEntity
|
||||||
|
noSpawn: true
|
||||||
|
description: Visualizer for shuttles arriving. You shouldn't see this!
|
||||||
|
components:
|
||||||
|
- type: FtlVisualizer
|
||||||
|
sprite:
|
||||||
|
sprite: /Textures/Effects/medi_holo.rsi
|
||||||
|
state: medi_holo
|
||||||
|
- type: Tag
|
||||||
|
tags:
|
||||||
|
- HideContextMenu
|
||||||
BIN
Resources/Textures/Effects/medi_holo.rsi/medi_holo.png
Normal file
BIN
Resources/Textures/Effects/medi_holo.rsi/medi_holo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
26
Resources/Textures/Effects/medi_holo.rsi/meta.json
Normal file
26
Resources/Textures/Effects/medi_holo.rsi/meta.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": "https://github.com/tgstation/tgstation/tree/217b39cc85e45302d407d5c1ab60809bd9e18987",
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "medi_holo",
|
||||||
|
"delays": [
|
||||||
|
[
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user