From 382cd710a7c734c9c0b9406ade7dcb8561a87826 Mon Sep 17 00:00:00 2001 From: Saphire Lattice Date: Thu, 13 Feb 2025 12:51:28 +0700 Subject: [PATCH] Use screen local north for buckling/unbuckling layering, plus #31625 (#33447) * 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 --- Content.Client/Buckle/BuckleSystem.cs | 53 ++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/Content.Client/Buckle/BuckleSystem.cs b/Content.Client/Buckle/BuckleSystem.cs index 035e1300ca..40b2092a26 100644 --- a/Content.Client/Buckle/BuckleSystem.cs +++ b/Content.Client/Buckle/BuckleSystem.cs @@ -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(OnAppearanceChange); SubscribeLocalEvent(OnStrapMoveEvent); + SubscribeLocalEvent(OnBuckledEvent); + SubscribeLocalEvent(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(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(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 } } + /// + /// 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 + /// + private void OnBuckledEvent(Entity ent, ref BuckledEvent args) + { + if (!TryComp(args.Strap, out var strapSprite)) + return; + + if (!TryComp(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; + } + + /// + /// Was the draw depth of the buckled entity lowered? Reset it upon unbuckling. + /// + private void OnUnbuckledEvent(Entity ent, ref UnbuckledEvent args) + { + if (!TryComp(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(uid, out var rotVisuals)) -- 2.51.2