From: Kara Date: Sun, 24 Sep 2023 21:22:44 +0000 (-0700) Subject: Follow mouse rotation in combat mode (#20433) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=2e481be694f6b845305803fa2459272e8121d871;p=space-station-14.git Follow mouse rotation in combat mode (#20433) --- diff --git a/Content.Client/MouseRotator/MouseRotatorSystem.cs b/Content.Client/MouseRotator/MouseRotatorSystem.cs index 4b7f937347..9615862dc5 100644 --- a/Content.Client/MouseRotator/MouseRotatorSystem.cs +++ b/Content.Client/MouseRotator/MouseRotatorSystem.cs @@ -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) diff --git a/Content.Shared/CombatMode/CombatModeComponent.cs b/Content.Shared/CombatMode/CombatModeComponent.cs index ace8105b99..6696f8af80 100644 --- a/Content.Shared/CombatMode/CombatModeComponent.cs +++ b/Content.Shared/CombatMode/CombatModeComponent.cs @@ -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; + /// + /// Will add and + /// to entities with this flag enabled that enter combat mode, and vice versa for removal. + /// + [DataField, AutoNetworkedField] + public bool ToggleMouseRotator = true; + [ViewVariables(VVAccess.ReadWrite), DataField("activeZone"), AutoNetworkedField] public TargetingZone ActiveZone; } diff --git a/Content.Shared/CombatMode/SharedCombatModeSystem.cs b/Content.Shared/CombatMode/SharedCombatModeSystem.cs index 263f3e8311..66b31d01ff 100644 --- a/Content.Shared/CombatMode/SharedCombatModeSystem.cs +++ b/Content.Shared/CombatMode/SharedCombatModeSystem.cs @@ -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(uid); + EnsureComp(uid); + } + else + { + RemComp(uid); + RemComp(uid); + } + } } public sealed partial class ToggleCombatActionEvent : InstantActionEvent { } diff --git a/Content.Shared/MouseRotator/MouseRotatorComponent.cs b/Content.Shared/MouseRotator/MouseRotatorComponent.cs index 9b4dac54ba..a35dfe0a28 100644 --- a/Content.Shared/MouseRotator/MouseRotatorComponent.cs +++ b/Content.Shared/MouseRotator/MouseRotatorComponent.cs @@ -14,22 +14,31 @@ public sealed partial class MouseRotatorComponent : Component /// /// How much the desired angle needs to change before a predictive event is sent /// - [DataField] - [ViewVariables(VVAccess.ReadWrite)] - public Angle AngleTolerance = Angle.FromDegrees(5.0); + [DataField, AutoNetworkedField] + public Angle AngleTolerance = Angle.FromDegrees(20.0); /// /// The angle that will be lerped to /// - [AutoNetworkedField, DataField] + [DataField, AutoNetworkedField] public Angle? GoalRotation; /// /// Max degrees the entity can rotate per second /// - [DataField] - [ViewVariables(VVAccess.ReadWrite)] + [DataField, AutoNetworkedField] public double RotationSpeed = float.MaxValue; + + /// + /// This one is important. If this is true, does not apply, and the system will + /// use 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. + /// + [DataField, AutoNetworkedField] + public bool Simple4DirMode = true; } /// @@ -41,3 +50,13 @@ public sealed class RequestMouseRotatorRotationEvent : EntityEventArgs { public Angle Rotation; } + +/// +/// Simpler version of for implementations +/// that only require snapping to 4-dir and not full angle rotation. +/// +[Serializable, NetSerializable] +public sealed class RequestMouseRotatorRotationSimpleEvent : EntityEventArgs +{ + public Direction Direction; +} diff --git a/Content.Shared/MouseRotator/SharedMouseRotatorSystem.cs b/Content.Shared/MouseRotator/SharedMouseRotatorSystem.cs index 4ff309682a..c57d477bd2 100644 --- a/Content.Shared/MouseRotator/SharedMouseRotatorSystem.cs +++ b/Content.Shared/MouseRotator/SharedMouseRotatorSystem.cs @@ -16,6 +16,7 @@ public abstract class SharedMouseRotatorSystem : EntitySystem base.Initialize(); SubscribeAllEvent(OnRequestRotation); + SubscribeAllEvent(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(ent, out var rotator)) + if (args.SenderSession.AttachedEntity is not { } ent + || !TryComp(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(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); + } } diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Guns/turrets.yml b/Resources/Prototypes/Entities/Objects/Weapons/Guns/turrets.yml index 3c7d0dd5d0..632e86e4fc 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Guns/turrets.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Guns/turrets.yml @@ -66,6 +66,7 @@ interactSuccessSound: path: /Audio/Effects/double_beep.ogg - type: CombatMode + toggleMouseRotator: false - type: Damageable damageContainer: Inorganic - type: Destructible @@ -110,7 +111,9 @@ SoundTargetInLOS: !type:SoundPathSpecifier path: /Audio/Effects/double_beep.ogg - type: MouseRotator + angleTolerance: 5 rotationSpeed: 180 + simple4DirMode: false - type: NoRotateOnInteract - type: NoRotateOnMove - type: Input