]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Fix camera recoil system overriding all other eye offsets (#29146)
authorDrSmugleaf <10968691+DrSmugleaf@users.noreply.github.com>
Wed, 3 Jul 2024 02:51:16 +0000 (19:51 -0700)
committerGitHub <noreply@github.com>
Wed, 3 Jul 2024 02:51:16 +0000 (19:51 -0700)
Content.Shared/Camera/GetEyeOffsetEvent.cs [new file with mode: 0644]
Content.Shared/Camera/SharedCameraRecoilSystem.cs
Content.Shared/Movement/Systems/SharedContentEyeSystem.cs

diff --git a/Content.Shared/Camera/GetEyeOffsetEvent.cs b/Content.Shared/Camera/GetEyeOffsetEvent.cs
new file mode 100644 (file)
index 0000000..de9c7c9
--- /dev/null
@@ -0,0 +1,19 @@
+using System.Numerics;
+using Content.Shared.Movement.Systems;
+
+namespace Content.Shared.Camera;
+
+/// <summary>
+///     Raised directed by-ref when <see cref="SharedContentEyeSystem.UpdateEyeOffset"/> is called.
+///     Should be subscribed to by any systems that want to modify an entity's eye offset,
+///     so that they do not override each other.
+/// </summary>
+/// <param name="Offset">
+///     The total offset to apply.
+/// </param>
+/// <remarks>
+///     Note that in most cases <see cref="Offset"/> should be incremented or decremented by subscribers, not set.
+///     Otherwise, any offsets applied by previous subscribing systems will be overridden.
+/// </remarks>
+[ByRefEvent]
+public record struct GetEyeOffsetEvent(Vector2 Offset);
index 3507bf1023341be05759498c787ffa37942e1cd5..d42fe9dceeea373122415ef699a3363a9ac17540 100644 (file)
@@ -1,6 +1,7 @@
 using System.Numerics;
+using Content.Shared.Movement.Systems;
 using JetBrains.Annotations;
-using Robust.Shared.Player;
+using Robust.Shared.Network;
 using Robust.Shared.Serialization;
 
 namespace Content.Shared.Camera;
@@ -28,7 +29,18 @@ public abstract class SharedCameraRecoilSystem : EntitySystem
     /// </summary>
     protected const float KickMagnitudeMax = 1f;
 
-    [Dependency] private readonly SharedEyeSystem _eye = default!;
+    [Dependency] private readonly SharedContentEyeSystem _eye = default!;
+    [Dependency] private readonly INetManager _net = default!;
+
+    public override void Initialize()
+    {
+        SubscribeLocalEvent<CameraRecoilComponent, GetEyeOffsetEvent>(OnCameraRecoilGetEyeOffset);
+    }
+
+    private void OnCameraRecoilGetEyeOffset(Entity<CameraRecoilComponent> ent, ref GetEyeOffsetEvent args)
+    {
+        args.Offset += ent.Comp.BaseOffset + ent.Comp.CurrentKick;
+    }
 
     /// <summary>
     ///     Applies explosion/recoil/etc kickback to the view of the entity.
@@ -39,10 +51,8 @@ public abstract class SharedCameraRecoilSystem : EntitySystem
     /// </remarks>
     public abstract void KickCamera(EntityUid euid, Vector2 kickback, CameraRecoilComponent? component = null);
 
-    public override void FrameUpdate(float frameTime)
+    private void UpdateEyes(float frameTime)
     {
-        base.FrameUpdate(frameTime);
-
         var query = AllEntityQuery<EyeComponent, CameraRecoilComponent>();
 
         while (query.MoveNext(out var uid, out var eye, out var recoil))
@@ -51,7 +61,7 @@ public abstract class SharedCameraRecoilSystem : EntitySystem
             if (magnitude <= 0.005f)
             {
                 recoil.CurrentKick = Vector2.Zero;
-                _eye.SetOffset(uid, recoil.BaseOffset + recoil.CurrentKick, eye);
+                _eye.UpdateEyeOffset((uid, eye));
             }
             else // Continually restore camera to 0.
             {
@@ -60,16 +70,28 @@ public abstract class SharedCameraRecoilSystem : EntitySystem
                 var restoreRate = MathHelper.Lerp(RestoreRateMin, RestoreRateMax, Math.Min(1, recoil.LastKickTime / RestoreRateRamp));
                 var restore = normalized * restoreRate * frameTime;
                 var (x, y) = recoil.CurrentKick - restore;
-                if (Math.Sign(x) != Math.Sign(recoil.CurrentKick.X)) x = 0;
+                if (Math.Sign(x) != Math.Sign(recoil.CurrentKick.X))
+                    x = 0;
 
-                if (Math.Sign(y) != Math.Sign(recoil.CurrentKick.Y)) y = 0;
+                if (Math.Sign(y) != Math.Sign(recoil.CurrentKick.Y))
+                    y = 0;
 
                 recoil.CurrentKick = new Vector2(x, y);
-
-                _eye.SetOffset(uid, recoil.BaseOffset + recoil.CurrentKick, eye);
+                _eye.UpdateEyeOffset((uid, eye));
             }
         }
     }
+
+    public override void Update(float frameTime)
+    {
+        if (_net.IsServer)
+            UpdateEyes(frameTime);
+    }
+
+    public override void FrameUpdate(float frameTime)
+    {
+        UpdateEyes(frameTime);
+    }
 }
 
 [Serializable]
index 207f14a258aaad0536700d13d4b4050c567caa95..0c4304d37483ebe1410fb7a6452a9aaf87acba24 100644 (file)
@@ -1,6 +1,7 @@
 using System.Numerics;
 using Content.Shared.Administration;
 using Content.Shared.Administration.Managers;
+using Content.Shared.Camera;
 using Content.Shared.Ghost;
 using Content.Shared.Input;
 using Content.Shared.Movement.Components;
@@ -128,6 +129,13 @@ public abstract class SharedContentEyeSystem : EntitySystem
         Dirty(uid, component);
     }
 
+    public void UpdateEyeOffset(Entity<EyeComponent?> eye)
+    {
+        var ev = new GetEyeOffsetEvent();
+        RaiseLocalEvent(eye, ref ev);
+        _eye.SetOffset(eye, ev.Offset, eye);
+    }
+
     /// <summary>
     /// Sendable from client to server to request a target zoom.
     /// </summary>