]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Follow mouse rotation in combat mode (#20433)
authorKara <lunarautomaton6@gmail.com>
Sun, 24 Sep 2023 21:22:44 +0000 (14:22 -0700)
committerGitHub <noreply@github.com>
Sun, 24 Sep 2023 21:22:44 +0000 (17:22 -0400)
Content.Client/MouseRotator/MouseRotatorSystem.cs
Content.Shared/CombatMode/CombatModeComponent.cs
Content.Shared/CombatMode/SharedCombatModeSystem.cs
Content.Shared/MouseRotator/MouseRotatorComponent.cs
Content.Shared/MouseRotator/SharedMouseRotatorSystem.cs
Resources/Prototypes/Entities/Objects/Weapons/Guns/turrets.yml

index 4b7f9373479505aff85f4b6945159ad4edbfb898..9615862dc5e578ce1db44f766429aff7d0f410d8 100644 (file)
@@ -41,6 +41,22 @@ public sealed class MouseRotatorSystem : SharedMouseRotatorSystem
 
         var curRot = _transform.GetWorldRotation(xform);
 
+        // 4-dir handling is separate --
+        // only raise event if the cardinal direction has changed
+        if (rotator.Simple4DirMode)
+        {
+            var angleDir = angle.GetCardinalDir();
+            if (angleDir == curRot.GetCardinalDir())
+                return;
+
+            RaisePredictiveEvent(new  RequestMouseRotatorRotationSimpleEvent()
+            {
+                Direction = angleDir,
+            });
+
+            return;
+        }
+
         // Don't raise event if mouse ~hasn't moved (or if too close to goal rotation already)
         var diff = Angle.ShortestDistance(angle, curRot);
         if (Math.Abs(diff.Theta) < rotator.AngleTolerance.Theta)
index ace8105b9996903886e586549dcb76ead38c55da..6696f8af806d6b479481009dbb726ded7c86b2f9 100644 (file)
@@ -1,3 +1,5 @@
+using Content.Shared.MouseRotator;
+using Content.Shared.Movement.Components;
 using Content.Shared.Targeting;
 using Robust.Shared.Audio;
 using Robust.Shared.GameStates;
@@ -41,6 +43,13 @@ namespace Content.Shared.CombatMode
         [ViewVariables(VVAccess.ReadWrite), DataField("isInCombatMode"), AutoNetworkedField]
         public bool IsInCombatMode;
 
+        /// <summary>
+        ///     Will add <see cref="MouseRotatorComponent"/> and <see cref="NoRotateOnMoveComponent"/>
+        ///     to entities with this flag enabled that enter combat mode, and vice versa for removal.
+        /// </summary>
+        [DataField, AutoNetworkedField]
+        public bool ToggleMouseRotator = true;
+
         [ViewVariables(VVAccess.ReadWrite), DataField("activeZone"), AutoNetworkedField]
         public TargetingZone ActiveZone;
     }
index 263f3e8311abe229ae39337a368a9ebc45d60786..66b31d01ffb0c32b4f7cfe3ea4d084706cca1577 100644 (file)
@@ -1,4 +1,6 @@
 using Content.Shared.Actions;
+using Content.Shared.MouseRotator;
+using Content.Shared.Movement.Components;
 using Content.Shared.Popups;
 using Content.Shared.Targeting;
 using Robust.Shared.Network;
@@ -30,6 +32,8 @@ public abstract class SharedCombatModeSystem : EntitySystem
     private void OnShutdown(EntityUid uid, CombatModeComponent component, ComponentShutdown args)
     {
         _actionsSystem.RemoveAction(uid, component.CombatToggleActionEntity);
+
+        SetMouseRotatorComponents(uid, false);
     }
 
     private void OnActionPerform(EntityUid uid, CombatModeComponent component, ToggleCombatActionEvent args)
@@ -76,6 +80,12 @@ public abstract class SharedCombatModeSystem : EntitySystem
 
         if (component.CombatToggleActionEntity != null)
             _actionsSystem.SetToggled(component.CombatToggleActionEntity, component.IsInCombatMode);
+
+        // Change mouse rotator comps if flag is set
+        if (!component.ToggleMouseRotator)
+            return;
+
+        SetMouseRotatorComponents(entity, value);
     }
 
     public virtual void SetActiveZone(EntityUid entity, TargetingZone zone,
@@ -86,6 +96,20 @@ public abstract class SharedCombatModeSystem : EntitySystem
 
         component.ActiveZone = zone;
     }
+
+    private void SetMouseRotatorComponents(EntityUid uid, bool value)
+    {
+        if (value)
+        {
+            EnsureComp<MouseRotatorComponent>(uid);
+            EnsureComp<NoRotateOnMoveComponent>(uid);
+        }
+        else
+        {
+            RemComp<MouseRotatorComponent>(uid);
+            RemComp<NoRotateOnMoveComponent>(uid);
+        }
+    }
 }
 
 public sealed partial class ToggleCombatActionEvent : InstantActionEvent { }
index 9b4dac54ba7bc65e239d59b79e24491436a3a83e..a35dfe0a288f3982f6bb5697d4387951d4af5a97 100644 (file)
@@ -14,22 +14,31 @@ public sealed partial class MouseRotatorComponent : Component
     /// <summary>
     ///     How much the desired angle needs to change before a predictive event is sent
     /// </summary>
-    [DataField]
-    [ViewVariables(VVAccess.ReadWrite)]
-    public Angle AngleTolerance = Angle.FromDegrees(5.0);
+    [DataField, AutoNetworkedField]
+    public Angle AngleTolerance = Angle.FromDegrees(20.0);
 
     /// <summary>
     ///     The angle that will be lerped to
     /// </summary>
-    [AutoNetworkedField, DataField]
+    [DataField, AutoNetworkedField]
     public Angle? GoalRotation;
 
     /// <summary>
     ///     Max degrees the entity can rotate per second
     /// </summary>
-    [DataField]
-    [ViewVariables(VVAccess.ReadWrite)]
+    [DataField, AutoNetworkedField]
     public double RotationSpeed = float.MaxValue;
+
+    /// <summary>
+    ///     This one is important. If this is true, <see cref="AngleTolerance"/> does not apply, and the system will
+    ///     use <see cref="RequestMouseRotatorRotationSimpleEvent"/> instead. In this mode, the client will only send
+    ///     events when an entity should snap to a different cardinal direction, rather than for every angle change.
+    ///
+    ///     This is useful for cases like humans, where what really matters is the visual sprite direction, as opposed to something
+    ///     like turrets or ship guns, which have finer range of movement.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public bool Simple4DirMode = true;
 }
 
 /// <summary>
@@ -41,3 +50,13 @@ public sealed class RequestMouseRotatorRotationEvent : EntityEventArgs
 {
     public Angle Rotation;
 }
+
+/// <summary>
+///     Simpler version of <see cref="RequestMouseRotatorRotationEvent"/> for implementations
+///     that only require snapping to 4-dir and not full angle rotation.
+/// </summary>
+[Serializable, NetSerializable]
+public sealed class RequestMouseRotatorRotationSimpleEvent : EntityEventArgs
+{
+    public Direction Direction;
+}
index 4ff309682a4af34164fba60f2822a4f8f872038e..c57d477bd2fd46873313d1273297b1c1b2a4b7cc 100644 (file)
@@ -16,6 +16,7 @@ public abstract class SharedMouseRotatorSystem : EntitySystem
         base.Initialize();
 
         SubscribeAllEvent<RequestMouseRotatorRotationEvent>(OnRequestRotation);
+        SubscribeAllEvent<RequestMouseRotatorRotationSimpleEvent>(OnRequestSimpleRotation);
     }
 
     public override void Update(float frameTime)
@@ -48,13 +49,27 @@ public abstract class SharedMouseRotatorSystem : EntitySystem
 
     private void OnRequestRotation(RequestMouseRotatorRotationEvent msg, EntitySessionEventArgs args)
     {
-        if (args.SenderSession.AttachedEntity is not { } ent || !TryComp<MouseRotatorComponent>(ent, out var rotator))
+        if (args.SenderSession.AttachedEntity is not { } ent
+            || !TryComp<MouseRotatorComponent>(ent, out var rotator) || rotator.Simple4DirMode)
         {
-            Log.Error($"User {args.SenderSession.Name} ({args.SenderSession.UserId}) tried setting local rotation without a mouse rotator component attached!");
+            Log.Error($"User {args.SenderSession.Name} ({args.SenderSession.UserId}) tried setting local rotation directly without a valid mouse rotator component attached!");
             return;
         }
 
         rotator.GoalRotation = msg.Rotation;
         Dirty(ent, rotator);
     }
+
+    private void OnRequestSimpleRotation(RequestMouseRotatorRotationSimpleEvent ev, EntitySessionEventArgs args)
+    {
+        if (args.SenderSession.AttachedEntity is not { } ent
+            || !TryComp<MouseRotatorComponent>(ent, out var rotator) || !rotator.Simple4DirMode)
+        {
+            Log.Error($"User {args.SenderSession.Name} ({args.SenderSession.UserId}) tried setting 4-dir rotation directly without a valid mouse rotator component attached!");
+            return;
+        }
+
+        rotator.GoalRotation = ev.Direction.ToAngle();
+        Dirty(ent, rotator);
+    }
 }
index 3c7d0dd5d08ecf8714b7fc0f4365d81ec9506bbf..632e86e4fcc3cdc5b0e1c972913500ea952bfeac 100644 (file)
@@ -66,6 +66,7 @@
       interactSuccessSound:
         path: /Audio/Effects/double_beep.ogg
     - type: CombatMode
+      toggleMouseRotator: false
     - type: Damageable
       damageContainer: Inorganic
     - type: Destructible
         SoundTargetInLOS: !type:SoundPathSpecifier
           path: /Audio/Effects/double_beep.ogg
     - type: MouseRotator
+      angleTolerance: 5
       rotationSpeed: 180
+      simple4DirMode: false
     - type: NoRotateOnInteract
     - type: NoRotateOnMove
     - type: Input