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()
{
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)
// 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))
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;
}
}
}
+ /// <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))