using System; using JetBrains.Annotations; using Robust.Client.Graphics; using Robust.Client.Physics; using Robust.Shared.GameObjects; using Robust.Shared.Input; using Robust.Shared.Input.Binding; using Robust.Shared.IoC; using Robust.Shared.Maths; #nullable enable namespace Robust.Client.GameObjects { /// /// Updates the position of every Eye every frame, so that the camera follows the player around. /// [UsedImplicitly] internal class EyeUpdateSystem : EntitySystem { // How fast the camera rotates in radians private const float CameraRotateSpeed = MathF.PI; private const float CameraSnapTolerance = 0.01f; #pragma warning disable 649, CS8618 // ReSharper disable once NotNullMemberIsNotInitialized [Dependency] private readonly IEyeManager _eyeManager; #pragma warning restore 649, CS8618 /// public override void Initialize() { base.Initialize(); //WARN: Tightly couples this system with InputSystem, and assumes InputSystem exists and is initialized CommandBinds.Builder .Bind(EngineKeyFunctions.CameraRotateRight, new NullInputCmdHandler()) .Bind(EngineKeyFunctions.CameraRotateLeft, new NullInputCmdHandler()) .Register(); // Make sure this runs *after* entities have been moved by interpolation and movement. UpdatesAfter.Add(typeof(TransformSystem)); UpdatesAfter.Add(typeof(PhysicsSystem)); } /// public override void Shutdown() { //WARN: Tightly couples this system with InputSystem, and assumes InputSystem exists and is initialized CommandBinds.Unregister(); base.Shutdown(); } /// public override void FrameUpdate(float frameTime) { var currentEye = _eyeManager.CurrentEye; var inputSystem = EntitySystemManager.GetEntitySystem(); var direction = 0; if (inputSystem.CmdStates[EngineKeyFunctions.CameraRotateRight] == BoundKeyState.Down) { direction += 1; } if (inputSystem.CmdStates[EngineKeyFunctions.CameraRotateLeft] == BoundKeyState.Down) { direction -= 1; } // apply camera rotation if(direction != 0) { currentEye.Rotation += CameraRotateSpeed * frameTime * direction; currentEye.Rotation = currentEye.Rotation.Reduced(); } else { // snap to cardinal directions var closestDir = currentEye.Rotation.GetCardinalDir().ToVec(); var currentDir = currentEye.Rotation.ToVec(); var dot = Vector2.Dot(closestDir, currentDir); if (MathHelper.CloseTo(dot, 1, CameraSnapTolerance)) { currentEye.Rotation = closestDir.ToAngle(); } } foreach (var eyeComponent in EntityManager.ComponentManager.EntityQuery(true)) { eyeComponent.UpdateEyePosition(); } } } }