]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Add FTL arrival visuals (#29402)
authormetalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Mon, 1 Jul 2024 06:11:30 +0000 (16:11 +1000)
committerGitHub <noreply@github.com>
Mon, 1 Jul 2024 06:11:30 +0000 (16:11 +1000)
* 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>
Content.Client/Shuttles/FtlArrivalOverlay.cs [new file with mode: 0644]
Content.Client/Shuttles/Systems/ShuttleSystem.EmergencyConsole.cs
Content.Client/Shuttles/Systems/ShuttleSystem.cs [new file with mode: 0644]
Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs
Content.Server/Shuttles/Systems/ShuttleSystem.cs
Content.Shared/Shuttles/Components/FTLComponent.cs [moved from Content.Server/Shuttles/Components/FTLComponent.cs with 81% similarity]
Content.Shared/Shuttles/Components/FtlVisualizerComponent.cs [new file with mode: 0644]
Resources/Prototypes/Entities/Effects/shuttle.yml [new file with mode: 0644]
Resources/Textures/Effects/medi_holo.rsi/medi_holo.png [new file with mode: 0644]
Resources/Textures/Effects/medi_holo.rsi/meta.json [new file with mode: 0644]

diff --git a/Content.Client/Shuttles/FtlArrivalOverlay.cs b/Content.Client/Shuttles/FtlArrivalOverlay.cs
new file mode 100644 (file)
index 0000000..f24a1e9
--- /dev/null
@@ -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);
+    }
+}
index d5154a87befeedc10f4ff21cdbaa29b67d63a3a7..73c11de27952c13407e00779e415c342f0b1d46a 100644 (file)
@@ -38,9 +38,8 @@ public sealed partial class ShuttleSystem : SharedShuttleSystem
     private bool _enableShuttlePosition;
     private EmergencyShuttleOverlay? _overlay;
 
-    public override void Initialize()
+    private void InitializeEmergency()
     {
-        base.Initialize();
         SubscribeNetworkEvent<EmergencyShuttlePositionMessage>(OnShuttlePosMessage);
     }
 
diff --git a/Content.Client/Shuttles/Systems/ShuttleSystem.cs b/Content.Client/Shuttles/Systems/ShuttleSystem.cs
new file mode 100644 (file)
index 0000000..a2c048f
--- /dev/null
@@ -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>();
+    }
+}
index 28f784f1dda01b8ce49f00a991a746e1cfa915e0..518867b5558388e1edfe444c8f7df5b792cab02a 100644 (file)
@@ -82,6 +82,8 @@ public sealed partial class ShuttleSystem
     private void InitializeFTL()
     {
         SubscribeLocalEvent<StationPostInitEvent>(OnStationPostInit);
+        SubscribeLocalEvent<FTLComponent, ComponentShutdown>(OnFtlShutdown);
+
         _bodyQuery = GetEntityQuery<BodyComponent>();
         _buckleQuery = GetEntityQuery<BuckleComponent>();
         _beaconQuery = GetEntityQuery<FTLBeaconComponent>();
@@ -98,6 +100,12 @@ public sealed partial class ShuttleSystem
         _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)
     {
         // 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;
         comp.StateTime = StartEndTime.FromCurTime(_gameTiming, DefaultArrivalTime);
         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.EnableLinearThrustDirection(shuttle, DirectionFlag.South);
index bbafef022c80c82f4e0d8072c73ec764f129a113..b8f216db7370a0747c0d92cc6202aadb940c28f6 100644 (file)
@@ -11,6 +11,7 @@ using Content.Shared.Shuttles.Systems;
 using Content.Shared.Throwing;
 using JetBrains.Annotations;
 using Robust.Server.GameObjects;
+using Robust.Server.GameStates;
 using Robust.Shared.Audio;
 using Robust.Shared.Audio.Systems;
 using Robust.Shared.Configuration;
@@ -40,6 +41,7 @@ public sealed partial class ShuttleSystem : SharedShuttleSystem
     [Dependency] private readonly FixtureSystem _fixtures = default!;
     [Dependency] private readonly MapLoaderSystem _loader = default!;
     [Dependency] private readonly MetaDataSystem _metadata = default!;
+    [Dependency] private readonly PvsOverrideSystem _pvs = default!;
     [Dependency] private readonly SharedAudioSystem _audio = default!;
     [Dependency] private readonly SharedMapSystem _maps = default!;
     [Dependency] private readonly SharedPhysicsSystem _physics = default!;
similarity index 81%
rename from Content.Server/Shuttles/Components/FTLComponent.cs
rename to Content.Shared/Shuttles/Components/FTLComponent.cs
index 0a01bb7636e2533e1819e8df7af0274f609f3daa..bce33492b9d4b21604e2436831ea17e277c97484 100644 (file)
@@ -2,16 +2,16 @@ using Content.Shared.Shuttles.Systems;
 using Content.Shared.Tag;
 using Content.Shared.Timing;
 using Robust.Shared.Audio;
+using Robust.Shared.GameStates;
 using Robust.Shared.Map;
 using Robust.Shared.Prototypes;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
 
-namespace Content.Server.Shuttles.Components;
+namespace Content.Shared.Shuttles.Components;
 
 /// <summary>
 /// Added to a component when it is queued or is travelling via FTL.
 /// </summary>
-[RegisterComponent]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
 public sealed partial class FTLComponent : Component
 {
     // TODO Full game save / add datafields
@@ -29,13 +29,19 @@ public sealed partial class FTLComponent : Component
     [ViewVariables(VVAccess.ReadWrite)]
     public float TravelTime = 0f;
 
+    [DataField]
+    public EntProtoId? VisualizerProto = "FtlVisualizerEntity";
+
+    [DataField, AutoNetworkedField]
+    public EntityUid? VisualizerEntity;
+
     /// <summary>
     /// Coordinates to arrive it: May be relative to another grid (for docking) or map coordinates.
     /// </summary>
-    [ViewVariables(VVAccess.ReadWrite), DataField]
+    [DataField, AutoNetworkedField]
     public EntityCoordinates TargetCoordinates;
 
-    [DataField]
+    [DataField, AutoNetworkedField]
     public Angle TargetAngle;
 
     /// <summary>
diff --git a/Content.Shared/Shuttles/Components/FtlVisualizerComponent.cs b/Content.Shared/Shuttles/Components/FtlVisualizerComponent.cs
new file mode 100644 (file)
index 0000000..628a4f8
--- /dev/null
@@ -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;
+}
diff --git a/Resources/Prototypes/Entities/Effects/shuttle.yml b/Resources/Prototypes/Entities/Effects/shuttle.yml
new file mode 100644 (file)
index 0000000..d453811
--- /dev/null
@@ -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
diff --git a/Resources/Textures/Effects/medi_holo.rsi/medi_holo.png b/Resources/Textures/Effects/medi_holo.rsi/medi_holo.png
new file mode 100644 (file)
index 0000000..9b024fa
Binary files /dev/null and b/Resources/Textures/Effects/medi_holo.rsi/medi_holo.png differ
diff --git a/Resources/Textures/Effects/medi_holo.rsi/meta.json b/Resources/Textures/Effects/medi_holo.rsi/meta.json
new file mode 100644 (file)
index 0000000..1be5022
--- /dev/null
@@ -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
+        ]
+      ]
+    }
+  ]
+}
\ No newline at end of file