]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Use screen local north for buckling/unbuckling layering, plus #31625 (#33447)
authorSaphire Lattice <lattice@saphi.re>
Thu, 13 Feb 2025 05:51:28 +0000 (12:51 +0700)
committerGitHub <noreply@github.com>
Thu, 13 Feb 2025 05:51:28 +0000 (21:51 -0800)
* Fix sprite layering upon strapping/unstrapping

* switch from strap to buckle events

* Use screen-local North for the checks instead

Build on top of PR #31625, but I'm not wanting to just push to someone's older PR without a warning.

---------

Co-authored-by: themias <themias5@gmail.com>
Content.Client/Buckle/BuckleSystem.cs

index 035e1300ca5394fa9fc37e7e559275b01eb2e6cf..40b2092a26cfc14ef00ba188e2e558907ae31ec5 100644 (file)
@@ -3,13 +3,15 @@ using Content.Shared.Buckle;
 using Content.Shared.Buckle.Components;
 using Content.Shared.Rotation;
 using Robust.Client.GameObjects;
-using Robust.Shared.GameStates;
+using Robust.Client.Graphics;
 
 namespace Content.Client.Buckle;
 
 internal sealed class BuckleSystem : SharedBuckleSystem
 {
     [Dependency] private readonly RotationVisualizerSystem _rotationVisualizerSystem = default!;
+    [Dependency] private readonly IEyeManager _eye = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     public override void Initialize()
     {
@@ -17,6 +19,8 @@ internal sealed class BuckleSystem : SharedBuckleSystem
 
         SubscribeLocalEvent<BuckleComponent, AppearanceChangeEvent>(OnAppearanceChange);
         SubscribeLocalEvent<StrapComponent, MoveEvent>(OnStrapMoveEvent);
+        SubscribeLocalEvent<BuckleComponent, BuckledEvent>(OnBuckledEvent);
+        SubscribeLocalEvent<BuckleComponent, UnbuckledEvent>(OnUnbuckledEvent);
     }
 
     private void OnStrapMoveEvent(EntityUid uid, StrapComponent component, ref MoveEvent args)
@@ -28,13 +32,21 @@ internal sealed class BuckleSystem : SharedBuckleSystem
         // This code is garbage, it doesn't work with rotated viewports. I need to finally get around to reworking
         // sprite rendering for entity layers & direction dependent sorting.
 
+        // Future notes:
+        // Right now this doesn't handle: other grids, other grids rotating, the camera rotation changing, and many other fun rotation specific things
+        // The entire thing should be a concern of the engine, or something engine helps to implement properly.
+        // Give some of the sprite rotations their own drawdepth, maybe as an offset within the rsi, or something like this
+        // And we won't ever need to set the draw depth manually
+
         if (args.NewRotation == args.OldRotation)
             return;
 
         if (!TryComp<SpriteComponent>(uid, out var strapSprite))
             return;
 
-        var isNorth = Transform(uid).LocalRotation.GetCardinalDir() == Direction.North;
+        var angle = _xformSystem.GetWorldRotation(uid) + _eye.CurrentEye.Rotation; // Get true screen position, or close enough
+
+        var isNorth = angle.GetCardinalDir() == Direction.North;
         foreach (var buckledEntity in component.BuckledEntities)
         {
             if (!TryComp<BuckleComponent>(buckledEntity, out var buckle))
@@ -45,6 +57,7 @@ internal sealed class BuckleSystem : SharedBuckleSystem
 
             if (isNorth)
             {
+                // This will only assign if empty, it won't get overwritten by new depth on multiple calls, which do happen easily
                 buckle.OriginalDrawDepth ??= buckledSprite.DrawDepth;
                 buckledSprite.DrawDepth = strapSprite.DrawDepth - 1;
             }
@@ -56,6 +69,42 @@ internal sealed class BuckleSystem : SharedBuckleSystem
         }
     }
 
+    /// <summary>
+    /// Lower the draw depth of the buckled entity without needing for the strap entity to rotate/move.
+    /// Only do so when the entity is facing screen-local north
+    /// </summary>
+    private void OnBuckledEvent(Entity<BuckleComponent> ent, ref BuckledEvent args)
+    {
+        if (!TryComp<SpriteComponent>(args.Strap, out var strapSprite))
+            return;
+
+        if (!TryComp<SpriteComponent>(ent.Owner, out var buckledSprite))
+            return;
+
+        var angle = _xformSystem.GetWorldRotation(args.Strap) + _eye.CurrentEye.Rotation; // Get true screen position, or close enough
+
+        if (angle.GetCardinalDir() != Direction.North)
+            return;
+
+        ent.Comp.OriginalDrawDepth ??= buckledSprite.DrawDepth;
+        buckledSprite.DrawDepth = strapSprite.DrawDepth - 1;
+    }
+
+    /// <summary>
+    /// Was the draw depth of the buckled entity lowered? Reset it upon unbuckling.
+    /// </summary>
+    private void OnUnbuckledEvent(Entity<BuckleComponent> ent, ref UnbuckledEvent args)
+    {
+        if (!TryComp<SpriteComponent>(ent.Owner, out var buckledSprite))
+            return;
+
+        if (!ent.Comp.OriginalDrawDepth.HasValue)
+            return;
+
+        buckledSprite.DrawDepth = ent.Comp.OriginalDrawDepth.Value;
+        ent.Comp.OriginalDrawDepth = null;
+    }
+
     private void OnAppearanceChange(EntityUid uid, BuckleComponent component, ref AppearanceChangeEvent args)
     {
         if (!TryComp<RotationVisualsComponent>(uid, out var rotVisuals))