From d8570b8bdad19d502803f608c5fff539565a23e9 Mon Sep 17 00:00:00 2001 From: Aviu00 <93730715+Aviu00@users.noreply.github.com> Date: Sat, 6 Apr 2024 21:31:51 +0900 Subject: [PATCH] - add: TelescopeSystem. (#273) --- .../_White/Telescope/TelescopeSystem.cs | 70 +++++++++++++++++ .../_White/Telescope/TelescopeSystem.cs | 5 ++ .../_White/Telescope/SharedTelescopeSystem.cs | 78 +++++++++++++++++++ .../_White/Telescope/TelescopeComponent.cs | 19 +++++ .../Objects/Weapons/Guns/Snipers/snipers.yml | 1 + 5 files changed, 173 insertions(+) create mode 100644 Content.Client/_White/Telescope/TelescopeSystem.cs create mode 100644 Content.Server/_White/Telescope/TelescopeSystem.cs create mode 100644 Content.Shared/_White/Telescope/SharedTelescopeSystem.cs create mode 100644 Content.Shared/_White/Telescope/TelescopeComponent.cs diff --git a/Content.Client/_White/Telescope/TelescopeSystem.cs b/Content.Client/_White/Telescope/TelescopeSystem.cs new file mode 100644 index 0000000000..80facafbf4 --- /dev/null +++ b/Content.Client/_White/Telescope/TelescopeSystem.cs @@ -0,0 +1,70 @@ +using System.Numerics; +using Content.Shared._White.Telescope; +using Content.Shared.Hands.Components; +using Robust.Client.GameObjects; +using Robust.Client.Graphics; +using Robust.Client.Input; +using Robust.Client.Player; +using Robust.Shared.Input; +using Robust.Shared.Timing; + +namespace Content.Client._White.Telescope; + +public sealed class TelescopeSystem : SharedTelescopeSystem +{ + [Dependency] private readonly InputSystem _inputSystem = default!; + [Dependency] private readonly IGameTiming _timing = default!; + [Dependency] private readonly IPlayerManager _player = default!; + [Dependency] private readonly IInputManager _input = default!; + [Dependency] private readonly IEyeManager _eyeManager = default!; + + public override void Update(float frameTime) + { + base.Update(frameTime); + + if (_timing.ApplyingState || !_timing.IsFirstTimePredicted || !_input.MouseScreenPosition.IsValid) + return; + + var player = _player.LocalEntity; + + if (!TryComp(player, out var hands) || + !TryComp(hands.ActiveHandEntity, out var telescope) || + !TryComp(player.Value, out var eye) || !TryComp(player.Value, out TransformComponent? xform)) + return; + + var offset = Vector2.Zero; + + if (_inputSystem.CmdStates.GetState(EngineKeyFunctions.UseSecondary) != BoundKeyState.Down) + { + RaisePredictiveEvent(new EyeOffsetChangedEvent + { + Offset = offset + }); + return; + } + + var mousePos = _input.MouseScreenPosition.Position; + var playerPos = _eyeManager.CoordinatesToScreen(xform.Coordinates).Position; + + var diff = mousePos - playerPos; + var len = diff.Length(); + + if (len > telescope.MaxLength) + { + diff *= telescope.MaxLength / len; + len = telescope.MaxLength; + } + + if (len > telescope.MinLength) + { + diff -= diff * telescope.MinLength / len; + offset = new Vector2(diff.X / telescope.Divisor, -diff.Y / telescope.Divisor); + offset = new Angle(-eye.Rotation.Theta).RotateVec(offset); + } + + RaisePredictiveEvent(new EyeOffsetChangedEvent + { + Offset = offset + }); + } +} diff --git a/Content.Server/_White/Telescope/TelescopeSystem.cs b/Content.Server/_White/Telescope/TelescopeSystem.cs new file mode 100644 index 0000000000..7320c67694 --- /dev/null +++ b/Content.Server/_White/Telescope/TelescopeSystem.cs @@ -0,0 +1,5 @@ +namespace Content.Server._White.Telescope; + +public sealed class TelescopeSystem : EntitySystem +{ +} diff --git a/Content.Shared/_White/Telescope/SharedTelescopeSystem.cs b/Content.Shared/_White/Telescope/SharedTelescopeSystem.cs new file mode 100644 index 0000000000..a6fd829922 --- /dev/null +++ b/Content.Shared/_White/Telescope/SharedTelescopeSystem.cs @@ -0,0 +1,78 @@ +using System.Numerics; +using Content.Shared.Camera; +using Content.Shared.Hands; +using Content.Shared.Hands.Components; +using Robust.Shared.Serialization; + +namespace Content.Shared._White.Telescope; + +public abstract class SharedTelescopeSystem : EntitySystem +{ + [Dependency] private readonly SharedEyeSystem _eye = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeAllEvent(OnEyeOffsetChanged); + SubscribeLocalEvent(OnUnequip); + SubscribeLocalEvent(OnHandDeselected); + SubscribeLocalEvent(OnShutdown); + } + + private void OnShutdown(Entity ent, ref ComponentShutdown args) + { + if (!TryComp(ent.Comp.LastHoldingEntity, out EyeComponent? eye)) + return; + + SetOffset((ent.Comp.LastHoldingEntity.Value, eye), Vector2.Zero, ent); + } + + private void OnHandDeselected(Entity ent, ref HandDeselectedEvent args) + { + if (!TryComp(args.User, out EyeComponent? eye)) + return; + + SetOffset((args.User, eye), Vector2.Zero, ent); + } + + private void OnUnequip(Entity ent, ref GotUnequippedHandEvent args) + { + if (!TryComp(args.User, out EyeComponent? eye)) + return; + + SetOffset((args.User, eye), Vector2.Zero, ent); + } + + private void OnEyeOffsetChanged(EyeOffsetChangedEvent msg, EntitySessionEventArgs args) + { + if (args.SenderSession.AttachedEntity is not { } ent) + return; + + if (!TryComp(ent, out var hands) || + !TryComp(hands.ActiveHandEntity, out var telescope) || + !TryComp(ent, out EyeComponent? eye)) + return; + + SetOffset((ent, eye), msg.Offset, telescope); + } + + private void SetOffset(Entity ent, Vector2 offset, TelescopeComponent telescope) + { + telescope.LastHoldingEntity = ent; + + if (TryComp(ent, out CameraRecoilComponent? recoil)) + { + recoil.BaseOffset = offset; + _eye.SetOffset(ent, offset + recoil.CurrentKick, ent); + } + else + _eye.SetOffset(ent, offset, ent); + } +} + +[Serializable, NetSerializable] +public sealed class EyeOffsetChangedEvent : EntityEventArgs +{ + public Vector2 Offset; +} diff --git a/Content.Shared/_White/Telescope/TelescopeComponent.cs b/Content.Shared/_White/Telescope/TelescopeComponent.cs new file mode 100644 index 0000000000..a3b4a35fec --- /dev/null +++ b/Content.Shared/_White/Telescope/TelescopeComponent.cs @@ -0,0 +1,19 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._White.Telescope; + +[RegisterComponent, NetworkedComponent] +public sealed partial class TelescopeComponent : Component +{ + [DataField, ViewVariables(VVAccess.ReadWrite)] + public float MaxLength = 670f; + + [DataField, ViewVariables(VVAccess.ReadWrite)] + public float MinLength = 100f; + + [DataField, ViewVariables(VVAccess.ReadWrite)] + public float Divisor = 60f; + + [ViewVariables] + public EntityUid? LastHoldingEntity; +} diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml index 54e6c03bc2..d0be6f9a41 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/Snipers/snipers.yml @@ -67,6 +67,7 @@ - type: Wieldable wieldTime: 0 forceTwoHanded: True + - type: Telescope - type: entity name: musket