diff --git a/Content.Shared/Camera/GetEyeOffsetEvent.cs b/Content.Shared/Camera/GetEyeOffsetEvent.cs
new file mode 100644
index 0000000000..de9c7c9e17
--- /dev/null
+++ b/Content.Shared/Camera/GetEyeOffsetEvent.cs
@@ -0,0 +1,19 @@
+using System.Numerics;
+using Content.Shared.Movement.Systems;
+
+namespace Content.Shared.Camera;
+
+///
+/// Raised directed by-ref when 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.
+///
+///
+/// The total offset to apply.
+///
+///
+/// Note that in most cases should be incremented or decremented by subscribers, not set.
+/// Otherwise, any offsets applied by previous subscribing systems will be overridden.
+///
+[ByRefEvent]
+public record struct GetEyeOffsetEvent(Vector2 Offset);
diff --git a/Content.Shared/Camera/SharedCameraRecoilSystem.cs b/Content.Shared/Camera/SharedCameraRecoilSystem.cs
index 3507bf1023..d42fe9dcee 100644
--- a/Content.Shared/Camera/SharedCameraRecoilSystem.cs
+++ b/Content.Shared/Camera/SharedCameraRecoilSystem.cs
@@ -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
///
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(OnCameraRecoilGetEyeOffset);
+ }
+
+ private void OnCameraRecoilGetEyeOffset(Entity ent, ref GetEyeOffsetEvent args)
+ {
+ args.Offset += ent.Comp.BaseOffset + ent.Comp.CurrentKick;
+ }
///
/// Applies explosion/recoil/etc kickback to the view of the entity.
@@ -39,10 +51,8 @@ public abstract class SharedCameraRecoilSystem : EntitySystem
///
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();
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]
diff --git a/Content.Shared/Movement/Systems/SharedContentEyeSystem.cs b/Content.Shared/Movement/Systems/SharedContentEyeSystem.cs
index 207f14a258..0c4304d374 100644
--- a/Content.Shared/Movement/Systems/SharedContentEyeSystem.cs
+++ b/Content.Shared/Movement/Systems/SharedContentEyeSystem.cs
@@ -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 eye)
+ {
+ var ev = new GetEyeOffsetEvent();
+ RaiseLocalEvent(eye, ref ev);
+ _eye.SetOffset(eye, ev.Offset, eye);
+ }
+
///
/// Sendable from client to server to request a target zoom.
///