diff --git a/Content.Client/Eye/EyeLerpingSystem.cs b/Content.Client/Eye/EyeLerpingSystem.cs index 8a5a6586aa..8495f01c81 100644 --- a/Content.Client/Eye/EyeLerpingSystem.cs +++ b/Content.Client/Eye/EyeLerpingSystem.cs @@ -1,11 +1,10 @@ -using Content.Shared.Follower.Components; +using System.Numerics; using Content.Shared.Movement.Components; using Content.Shared.Movement.Systems; +using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.Graphics; using Robust.Client.Physics; using Robust.Client.Player; -using Robust.Shared.Collections; using Robust.Shared.Timing; namespace Content.Client.Eye; @@ -15,9 +14,10 @@ public sealed class EyeLerpingSystem : EntitySystem [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly SharedMoverController _mover = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; // Convenience variable for for VV. - [ViewVariables] + [ViewVariables, UsedImplicitly] private IEnumerable ActiveEyes => EntityQuery(); public override void Initialize() @@ -59,8 +59,14 @@ public sealed class EyeLerpingSystem : EntitySystem lerpInfo.LastRotation = lerpInfo.TargetRotation; lerpInfo.ManuallyAdded |= !automatic; + lerpInfo.TargetZoom = component.Zoom; + lerpInfo.LastZoom = lerpInfo.TargetZoom; + if (component.Eye != null) + { component.Eye.Rotation = lerpInfo.TargetRotation; + component.Eye.Zoom = lerpInfo.TargetZoom; + } } public void RemoveEye(EntityUid uid) @@ -107,9 +113,29 @@ public sealed class EyeLerpingSystem : EntitySystem { lerpInfo.LastRotation = lerpInfo.TargetRotation; lerpInfo.TargetRotation = GetRotation(uid, xform); + + lerpInfo.LastZoom = lerpInfo.TargetZoom; + lerpInfo.TargetZoom = UpdateZoom(uid, frameTime); } } + private Vector2 UpdateZoom(EntityUid uid, float frameTime, EyeComponent? eye = null, ContentEyeComponent? content = null) + { + if (!Resolve(uid, ref content, ref eye, false)) + return Vector2.One; + + var diff = content.TargetZoom - eye.Zoom; + + if (diff.LengthSquared() < 0.00001f) + { + return content.TargetZoom; + } + + var change = diff * 8f * frameTime; + + return eye.Zoom + change; + } + /// /// Does the eye need to lerp or is its rotation matched. /// @@ -138,7 +164,7 @@ public sealed class EyeLerpingSystem : EntitySystem // if not tied to a mover then lock it to map / grid var relative = xform.GridUid ?? xform.MapUid; if (relative != null) - return -Transform(relative.Value).WorldRotation; + return -_transform.GetWorldRotation(relative.Value); return Angle.Zero; } @@ -151,6 +177,19 @@ public sealed class EyeLerpingSystem : EntitySystem while (query.MoveNext(out var entity, out var lerpInfo, out var eye, out var xform)) { + // Handle zoom + var zoomDiff = Vector2.Lerp(lerpInfo.LastZoom, lerpInfo.TargetZoom, tickFraction); + + if ((zoomDiff - lerpInfo.TargetZoom).Length() < lerpMinimum) + { + eye.Zoom = lerpInfo.TargetZoom; + } + else + { + eye.Zoom = zoomDiff; + } + + // Handle Rotation TryComp(entity, out var mover); // This needs to be recomputed every frame, as if this is simply the grid rotation, then we need to account for grid angle lerping. diff --git a/Content.Client/Eye/LerpingEyeComponent.cs b/Content.Client/Eye/LerpingEyeComponent.cs index 29389d1941..b11cc0879e 100644 --- a/Content.Client/Eye/LerpingEyeComponent.cs +++ b/Content.Client/Eye/LerpingEyeComponent.cs @@ -1,3 +1,5 @@ +using System.Numerics; + namespace Content.Client.Eye; /// @@ -16,4 +18,10 @@ public sealed partial class LerpingEyeComponent : Component [ViewVariables] public Angle TargetRotation; + + [ViewVariables] + public Vector2 LastZoom; + + [ViewVariables] + public Vector2 TargetZoom; } diff --git a/Content.Client/Movement/Systems/ContentEyeSystem.cs b/Content.Client/Movement/Systems/ContentEyeSystem.cs index afc2363cd6..cb750ff234 100644 --- a/Content.Client/Movement/Systems/ContentEyeSystem.cs +++ b/Content.Client/Movement/Systems/ContentEyeSystem.cs @@ -41,19 +41,4 @@ public sealed class ContentEyeSystem : SharedContentEyeSystem Fov = value, }); } - - public override void Update(float frameTime) - { - base.Update(frameTime); - - var localPlayer = _player.LocalPlayer?.ControlledEntity; - - if (!TryComp(localPlayer, out var content) || - !TryComp(localPlayer, out var eye)) - { - return; - } - - UpdateEye(localPlayer.Value, content, eye, frameTime); - } } diff --git a/Content.Server/Movement/Systems/ContentEyeSystem.cs b/Content.Server/Movement/Systems/ContentEyeSystem.cs index 54428d9bee..a77e6c7918 100644 --- a/Content.Server/Movement/Systems/ContentEyeSystem.cs +++ b/Content.Server/Movement/Systems/ContentEyeSystem.cs @@ -1,22 +1,5 @@ -using Content.Shared.Movement.Components; using Content.Shared.Movement.Systems; namespace Content.Server.Movement.Systems; -public sealed class ContentEyeSystem : SharedContentEyeSystem -{ - public override void Update(float frameTime) - { - base.Update(frameTime); - - var query = AllEntityQuery(); - - while (query.MoveNext(out var uid, out var comp, out var eyeComp)) - { - if (eyeComp.Zoom.Equals(comp.TargetZoom)) - continue; - - UpdateEye(uid, comp, eyeComp, frameTime); - } - } -} +public sealed class ContentEyeSystem : SharedContentEyeSystem {} diff --git a/Content.Shared/Movement/Systems/SharedContentEyeSystem.cs b/Content.Shared/Movement/Systems/SharedContentEyeSystem.cs index 95b5c272d3..d822a4c772 100644 --- a/Content.Shared/Movement/Systems/SharedContentEyeSystem.cs +++ b/Content.Shared/Movement/Systems/SharedContentEyeSystem.cs @@ -4,11 +4,9 @@ using Content.Shared.Administration.Managers; using Content.Shared.Ghost; using Content.Shared.Input; using Content.Shared.Movement.Components; -using Robust.Shared.Input; using Robust.Shared.Input.Binding; using Robust.Shared.Players; using Robust.Shared.Serialization; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Generic; namespace Content.Shared.Movement.Systems; @@ -78,7 +76,7 @@ public abstract class SharedContentEyeSystem : EntitySystem return; eye.TargetZoom = ignoreLimits ? zoom : Clamp(zoom, eye); - Dirty(eye); + Dirty(uid, eye); } private void OnContentZoomRequest(RequestTargetZoomEvent msg, EntitySessionEventArgs args) @@ -100,7 +98,7 @@ public abstract class SharedContentEyeSystem : EntitySystem if (TryComp(player, out var eyeComp)) { eyeComp.DrawFov = msg.Fov; - Dirty(eyeComp); + Dirty(player, eyeComp); } } @@ -110,24 +108,7 @@ public abstract class SharedContentEyeSystem : EntitySystem return; component.TargetZoom = eyeComp.Zoom; - Dirty(component); - } - - protected void UpdateEye(EntityUid uid, ContentEyeComponent content, SharedEyeComponent eye, float frameTime) - { - var diff = content.TargetZoom - eye.Zoom; - - if (diff.LengthSquared() < 0.00001f) - { - eye.Zoom = content.TargetZoom; - Dirty(eye); - return; - } - - var change = diff * 8f * frameTime; - - eye.Zoom += change; - Dirty(eye); + Dirty(uid, component); } public void ResetZoom(EntityUid uid, ContentEyeComponent? component = null) @@ -142,7 +123,7 @@ public abstract class SharedContentEyeSystem : EntitySystem component.MaxZoom = value; component.TargetZoom = Clamp(component.TargetZoom, component); - Dirty(component); + Dirty(uid, component); } ///