From d26667a5ad73d51d53fa1082a445028e42aa2957 Mon Sep 17 00:00:00 2001 From: Spatison <137375981+Spatison@users.noreply.github.com> Date: Tue, 20 Aug 2024 14:02:24 +0300 Subject: [PATCH 1/5] add: White lay down --- .../Options/UI/Tabs/KeyRebindTab.xaml.cs | 8 + .../_White/Standing/LayingDownSystem.cs | 85 ++++++++++ .../Standing/LayingDownComponent.cs | 14 -- Content.Server/Standing/LayingDownSystem.cs | 100 +----------- .../Assorted/LayingDownModifierSystem.cs | 6 +- .../Standing/StandingStateComponent.cs | 45 ++++-- .../Standing/StandingStateSystem.cs | 26 ++- Content.Shared/Stunnable/SharedStunSystem.cs | 24 ++- Content.Shared/_White/CVars.cs | 14 ++ .../_White/Standing/LayingDownComponent.cs | 25 +++ .../_White/Standing/SharedLayingDownSystem.cs | 149 ++++++++++++++++++ .../en-US/_white/escape-menu/options-menu.ftl | 2 + .../ru-RU/_white/escape-menu/options-menu.ftl | 2 + 13 files changed, 359 insertions(+), 141 deletions(-) create mode 100644 Content.Client/_White/Standing/LayingDownSystem.cs delete mode 100644 Content.Server/Standing/LayingDownComponent.cs create mode 100644 Content.Shared/_White/CVars.cs create mode 100644 Content.Shared/_White/Standing/LayingDownComponent.cs create mode 100644 Content.Shared/_White/Standing/SharedLayingDownSystem.cs create mode 100644 Resources/Locale/en-US/_white/escape-menu/options-menu.ftl create mode 100644 Resources/Locale/ru-RU/_white/escape-menu/options-menu.ftl diff --git a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs index 13e456985a..1857e3f8e3 100644 --- a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs +++ b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs @@ -1,5 +1,6 @@ using System.Numerics; using Content.Client.Stylesheets; +using Content.Shared._White; using Content.Shared.CCVar; using Content.Shared.Input; using Robust.Client.AutoGenerated; @@ -103,6 +104,12 @@ private void HandleStaticStorageUI(BaseButton.ButtonToggledEventArgs args) _cfg.SaveToFile(); } + private void HandleToggleAutoGetUp(BaseButton.ButtonToggledEventArgs args) // WD EDIT + { + _cfg.SetCVar(WhiteCVars.AutoGetUp, args.Pressed); + _cfg.SaveToFile(); + } + public KeyRebindTab() { IoCManager.InjectDependencies(this); @@ -186,6 +193,7 @@ void AddCheckBox(string checkBoxName, bool currentState, Action(OnMovementInput); + + SubscribeNetworkEvent(OnCheckAutoGetUp); + } + + private void OnMovementInput(EntityUid uid, LayingDownComponent component, MoveEvent args) + { + if (!_timing.IsFirstTimePredicted) + return; + + if (!_standing.IsDown(uid)) + return; + + if (_buckle.IsBuckled(uid)) + return; + + if (_animation.HasRunningAnimation(uid, "rotate")) + return; + + if (!TryComp(uid, out var transform) || !TryComp(uid, out var sprite)) + return; + + var rotation = transform.LocalRotation.Degrees + _eyeManager.CurrentEye.Rotation.Degrees; + + if (Angle.FromDegrees(rotation).GetDir() is Direction.SouthEast or Direction.East or Direction.NorthEast or Direction.North) + { + sprite.Rotation = Angle.FromDegrees(270); + return; + } + + sprite.Rotation = Angle.FromDegrees(90); + } + + private void OnCheckAutoGetUp(CheckAutoGetUpEvent ev, EntitySessionEventArgs args) + { + if (!_timing.IsFirstTimePredicted) + return; + + var uid = GetEntity(ev.User); + + if (!TryComp(uid, out LayingDownComponent? layingDown)) + return; + + layingDown.AutoGetUp = _cfg.GetClientCVar(args.SenderSession.Channel, WhiteCVars.AutoGetUp); + Dirty(uid, layingDown); + + if (!TryComp(uid, out var transform) || !TryComp(uid, out var rotationVisuals)) + return; + + var rotation = transform.LocalRotation.Degrees + _eyeManager.CurrentEye.Rotation.Degrees; + + if (Angle.FromDegrees(rotation).GetDir() is Direction.SouthEast or Direction.East or Direction.NorthEast or Direction.North) + { + rotationVisuals.HorizontalRotation = Angle.FromDegrees(270); + return; + } + + rotationVisuals.HorizontalRotation = Angle.FromDegrees(90); + } +} diff --git a/Content.Server/Standing/LayingDownComponent.cs b/Content.Server/Standing/LayingDownComponent.cs deleted file mode 100644 index 7921749f14..0000000000 --- a/Content.Server/Standing/LayingDownComponent.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Content.Server.Standing; - -[RegisterComponent] -public sealed partial class LayingDownComponent : Component -{ - [DataField] - public float DownedSpeedMultiplier = 0.15f; - - [DataField] - public TimeSpan Cooldown = TimeSpan.FromSeconds(2.5f); - - [DataField] - public TimeSpan NextToggleAttempt = TimeSpan.Zero; -} diff --git a/Content.Server/Standing/LayingDownSystem.cs b/Content.Server/Standing/LayingDownSystem.cs index 73a929fdfc..7d9dd6ed93 100644 --- a/Content.Server/Standing/LayingDownSystem.cs +++ b/Content.Server/Standing/LayingDownSystem.cs @@ -1,101 +1,5 @@ -using Content.Shared.ActionBlocker; -using Content.Shared.Input; -using Content.Shared.Movement.Systems; -using Content.Shared.Popups; -using Content.Shared.Standing; -using Robust.Shared.Input.Binding; -using Robust.Shared.Player; -using Robust.Shared.Timing; +using Content.Shared._White.Standing; namespace Content.Server.Standing; -/// Unfortunately cannot be shared because some standing conditions are server-side only -public sealed class LayingDownSystem : EntitySystem -{ - [Dependency] private readonly ActionBlockerSystem _actionBlocker = default!; - [Dependency] private readonly MovementSpeedModifierSystem _movement = default!; - [Dependency] private readonly SharedPopupSystem _popups = default!; - [Dependency] private readonly Shared.Standing.StandingStateSystem _standing = default!; // WHY IS THERE TWO DIFFERENT STANDING SYSTEMS?! - [Dependency] private readonly IGameTiming _timing = default!; - - - public override void Initialize() - { - CommandBinds.Builder - .Bind(ContentKeyFunctions.ToggleStanding, InputCmdHandler.FromDelegate(ToggleStanding, handle: false, outsidePrediction: false)) - .Register(); - - SubscribeLocalEvent(DoRefreshMovementSpeed); - SubscribeLocalEvent(DoRefreshMovementSpeed); - SubscribeLocalEvent(OnRefreshMovementSpeed); - SubscribeLocalEvent(OnParentChanged); - } - - public override void Shutdown() - { - base.Shutdown(); - - CommandBinds.Unregister(); - } - - private void DoRefreshMovementSpeed(EntityUid uid, LayingDownComponent component, object args) - { - _movement.RefreshMovementSpeedModifiers(uid); - } - - private void OnRefreshMovementSpeed(EntityUid uid, LayingDownComponent component, RefreshMovementSpeedModifiersEvent args) - { - if (TryComp(uid, out var standingState) && standingState.Standing) - return; - - args.ModifySpeed(component.DownedSpeedMultiplier, component.DownedSpeedMultiplier, bypassImmunity: true); - } - - private void OnParentChanged(EntityUid uid, LayingDownComponent component, EntParentChangedMessage args) - { - // If the entity is not on a grid, try to make it stand up to avoid issues - if (!TryComp(uid, out var standingState) - || standingState.Standing - || Transform(uid).GridUid != null) - return; - - _standing.Stand(uid, standingState); - } - - private void ToggleStanding(ICommonSession? session) - { - if (session is not { AttachedEntity: { Valid: true } uid } playerSession - || !Exists(uid) - || !TryComp(uid, out var standingState) - || !TryComp(uid, out var layingDown)) - return; - - // If successful, show popup to self and others. Otherwise, only to self. - if (ToggleStandingImpl(uid, standingState, layingDown, out var popupBranch)) - { - _popups.PopupEntity(Loc.GetString($"laying-comp-{popupBranch}-other", ("entity", uid)), uid, Filter.PvsExcept(uid), true); - layingDown.NextToggleAttempt = _timing.CurTime + layingDown.Cooldown; - } - - _popups.PopupEntity(Loc.GetString($"laying-comp-{popupBranch}-self", ("entity", uid)), uid, uid); - } - - private bool ToggleStandingImpl(EntityUid uid, StandingStateComponent standingState, LayingDownComponent layingDown, out string popupBranch) - { - var success = layingDown.NextToggleAttempt <= _timing.CurTime; - - if (_standing.IsDown(uid, standingState)) - { - success = success && _standing.Stand(uid, standingState, force: false); - popupBranch = success ? "stand-success" : "stand-fail"; - } - else - { - success = success && Transform(uid).GridUid != null; // Do not allow laying down when not on a surface. - success = success && _standing.Down(uid, standingState: standingState, playSound: true, dropHeldItems: false); - popupBranch = success ? "lay-success" : "lay-fail"; - } - - return success; - } -} +public sealed class LayingDownSystem : SharedLayingDownSystem; diff --git a/Content.Server/Traits/Assorted/LayingDownModifierSystem.cs b/Content.Server/Traits/Assorted/LayingDownModifierSystem.cs index dc6dcd2de3..7d2c16e3c4 100644 --- a/Content.Server/Traits/Assorted/LayingDownModifierSystem.cs +++ b/Content.Server/Traits/Assorted/LayingDownModifierSystem.cs @@ -1,5 +1,5 @@ using Content.Server.Traits.Assorted; -using Content.Server.Standing; +using Content.Shared._White.Standing; namespace Content.Shared.Traits.Assorted.Systems; @@ -16,7 +16,7 @@ private void OnStartup(EntityUid uid, LayingDownModifierComponent component, Com if (!TryComp(uid, out var layingDown)) return; - layingDown.Cooldown *= component.LayingDownCooldownMultiplier; - layingDown.DownedSpeedMultiplier *= component.DownedSpeedMultiplierMultiplier; + layingDown.StandingUpTime *= component.LayingDownCooldownMultiplier; + layingDown.SpeedModify *= component.DownedSpeedMultiplierMultiplier; } } diff --git a/Content.Shared/Standing/StandingStateComponent.cs b/Content.Shared/Standing/StandingStateComponent.cs index 5d7bb0a59f..3a7cb2a008 100644 --- a/Content.Shared/Standing/StandingStateComponent.cs +++ b/Content.Shared/Standing/StandingStateComponent.cs @@ -1,24 +1,35 @@ using Robust.Shared.Audio; using Robust.Shared.GameStates; -namespace Content.Shared.Standing +namespace Content.Shared.Standing; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class StandingStateComponent : Component { - [RegisterComponent, NetworkedComponent, AutoGenerateComponentState] - [Access(typeof(StandingStateSystem))] - public sealed partial class StandingStateComponent : Component - { - [ViewVariables(VVAccess.ReadWrite)] - [DataField] - public SoundSpecifier DownSound { get; private set; } = new SoundCollectionSpecifier("BodyFall"); + [ViewVariables(VVAccess.ReadWrite)] + [DataField] + public SoundSpecifier DownSound { get; private set; } = new SoundCollectionSpecifier("BodyFall"); + + // WD EDIT START + [DataField, AutoNetworkedField] + public StandingState CurrentState { get; set; } = StandingState.Standing; + // WD EDIT END - [DataField, AutoNetworkedField] - public bool Standing { get; set; } = true; + [DataField, AutoNetworkedField] + public bool Standing { get; set; } = true; - /// - /// List of fixtures that had their collision mask changed when the entity was downed. - /// Required for re-adding the collision mask. - /// - [DataField, AutoNetworkedField] - public List ChangedFixtures = new(); - } + /// + /// List of fixtures that had their collision mask changed when the entity was downed. + /// Required for re-adding the collision mask. + /// + [DataField, AutoNetworkedField] + public List ChangedFixtures = new(); +} +// WD EDIT START +public enum StandingState +{ + Lying, + GettingUp, + Standing, } +// WD EDIT END diff --git a/Content.Shared/Standing/StandingStateSystem.cs b/Content.Shared/Standing/StandingStateSystem.cs index 517831b8a1..212e1d06d1 100644 --- a/Content.Shared/Standing/StandingStateSystem.cs +++ b/Content.Shared/Standing/StandingStateSystem.cs @@ -1,7 +1,9 @@ +using Content.Shared.Buckle; +using Content.Shared.Buckle.Components; using Content.Shared.Hands.Components; +using Content.Shared.Movement.Systems; using Content.Shared.Physics; using Content.Shared.Rotation; -using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; using Robust.Shared.Physics; using Robust.Shared.Physics.Systems; @@ -13,6 +15,8 @@ public sealed class StandingStateSystem : EntitySystem [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; + [Dependency] private readonly MovementSpeedModifierSystem _movement = default!; // WD EDIT + [Dependency] private readonly SharedBuckleSystem _buckle = default!; // WD EDIT // If StandingCollisionLayer value is ever changed to more than one layer, the logic needs to be edited. private const int StandingCollisionLayer = (int) CollisionGroup.MidImpassable; @@ -22,7 +26,7 @@ public bool IsDown(EntityUid uid, StandingStateComponent? standingState = null) if (!Resolve(uid, ref standingState, false)) return false; - return !standingState.Standing; + return standingState.CurrentState is StandingState.Lying or StandingState.GettingUp; } public bool Down(EntityUid uid, bool playSound = true, bool dropHeldItems = true, @@ -37,7 +41,7 @@ public bool Down(EntityUid uid, bool playSound = true, bool dropHeldItems = true // Optional component. Resolve(uid, ref appearance, ref hands, false); - if (!standingState.Standing) + if (standingState.CurrentState is StandingState.Lying or StandingState.GettingUp) return true; // This is just to avoid most callers doing this manually saving boilerplate @@ -49,13 +53,16 @@ public bool Down(EntityUid uid, bool playSound = true, bool dropHeldItems = true RaiseLocalEvent(uid, new DropHandItemsEvent(), false); } + if (TryComp(uid, out BuckleComponent? buckle) && buckle.Buckled && !_buckle.TryUnbuckle(uid, uid, buckleComp: buckle)) // WD EDIT + return false; + var msg = new DownAttemptEvent(); RaiseLocalEvent(uid, msg, false); if (msg.Cancelled) return false; - standingState.Standing = false; + standingState.CurrentState = StandingState.Lying; Dirty(standingState); RaiseLocalEvent(uid, new DownedEvent(), false); @@ -82,9 +89,10 @@ public bool Down(EntityUid uid, bool playSound = true, bool dropHeldItems = true if (playSound) { - _audio.PlayPredicted(standingState.DownSound, uid, uid); + _audio.PlayPredicted(standingState.DownSound, uid, null); } + _movement.RefreshMovementSpeedModifiers(uid); // WD EDIT return true; } @@ -100,9 +108,12 @@ public bool Stand(EntityUid uid, // Optional component. Resolve(uid, ref appearance, false); - if (standingState.Standing) + if (standingState.CurrentState is StandingState.Standing) return true; + if (TryComp(uid, out BuckleComponent? buckle) && buckle.Buckled && !_buckle.TryUnbuckle(uid, uid, buckleComp: buckle)) // WD EDIT + return false; + if (!force) { var msg = new StandAttemptEvent(); @@ -112,7 +123,7 @@ public bool Stand(EntityUid uid, return false; } - standingState.Standing = true; + standingState.CurrentState = StandingState.Standing; Dirty(uid, standingState); RaiseLocalEvent(uid, new StoodEvent(), false); @@ -127,6 +138,7 @@ public bool Stand(EntityUid uid, } } standingState.ChangedFixtures.Clear(); + _movement.RefreshMovementSpeedModifiers(uid); // WD EDIT return true; } diff --git a/Content.Shared/Stunnable/SharedStunSystem.cs b/Content.Shared/Stunnable/SharedStunSystem.cs index c447f8c8bc..ddac3d3942 100644 --- a/Content.Shared/Stunnable/SharedStunSystem.cs +++ b/Content.Shared/Stunnable/SharedStunSystem.cs @@ -1,3 +1,4 @@ +using Content.Shared._White.Standing; using Content.Shared.ActionBlocker; using Content.Shared.Administration.Logs; using Content.Shared.Audio; @@ -19,6 +20,7 @@ using Content.Shared.Throwing; using Robust.Shared.Audio; using Robust.Shared.Audio.Systems; +using Robust.Shared.Containers; using Robust.Shared.GameStates; using Robust.Shared.Player; @@ -32,6 +34,8 @@ public abstract class SharedStunSystem : EntitySystem [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly StandingStateSystem _standingState = default!; [Dependency] private readonly StatusEffectsSystem _statusEffect = default!; + [Dependency] private readonly SharedLayingDownSystem _layingDown = default!; // WD EDIT + [Dependency] private readonly SharedContainerSystem _container = default!; // WD EDIT /// /// Friction modifier for knocked down players. @@ -109,12 +113,28 @@ private void UpdateCanMove(EntityUid uid, StunnedComponent component, EntityEven private void OnKnockInit(EntityUid uid, KnockedDownComponent component, ComponentInit args) { - _standingState.Down(uid); + _layingDown.TryLieDown(uid, null, null, DropHeldItemsBehavior.DropIfStanding); // WD EDIT } private void OnKnockShutdown(EntityUid uid, KnockedDownComponent component, ComponentShutdown args) { - _standingState.Stand(uid); + // WD EDIT START + RaiseNetworkEvent(new CheckAutoGetUpEvent(GetNetEntity(uid))); + + if (!TryComp(uid, out StandingStateComponent? standing)) + return; + + if (!TryComp(uid, out LayingDownComponent? layingDown) || !layingDown.AutoGetUp) + return; + + if (layingDown.AutoGetUp && !_container.IsEntityInContainer(uid)) + { + _layingDown.TryStandUp(uid, layingDown); + return; + } + + _standingState.Stand(uid, standing); + // WD EDIT END } private void OnStandAttempt(EntityUid uid, KnockedDownComponent component, StandAttemptEvent args) diff --git a/Content.Shared/_White/CVars.cs b/Content.Shared/_White/CVars.cs new file mode 100644 index 0000000000..754f2dd42e --- /dev/null +++ b/Content.Shared/_White/CVars.cs @@ -0,0 +1,14 @@ +using Robust.Shared.Configuration; + +namespace Content.Shared._White; + +[CVarDefs] +public sealed class WhiteCVars +{ + #region Keybind + + public static readonly CVarDef AutoGetUp = + CVarDef.Create("white.auto_get_up", true, CVar.CLIENT | CVar.ARCHIVE | CVar.REPLICATED); + + #endregion +} diff --git a/Content.Shared/_White/Standing/LayingDownComponent.cs b/Content.Shared/_White/Standing/LayingDownComponent.cs new file mode 100644 index 0000000000..6dce32ac24 --- /dev/null +++ b/Content.Shared/_White/Standing/LayingDownComponent.cs @@ -0,0 +1,25 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Serialization; + +namespace Content.Shared._White.Standing; + +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class LayingDownComponent : Component +{ + [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)] + public float StandingUpTime { get; set; } = 1f; + + [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)] + public float SpeedModify { get; set; } = 0.4f; + + [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)] + public bool AutoGetUp; +} +[Serializable, NetSerializable] +public sealed class ChangeLayingDownEvent : CancellableEntityEventArgs; + +[Serializable, NetSerializable] +public sealed class CheckAutoGetUpEvent(NetEntity user) : CancellableEntityEventArgs +{ + public NetEntity User = user; +} diff --git a/Content.Shared/_White/Standing/SharedLayingDownSystem.cs b/Content.Shared/_White/Standing/SharedLayingDownSystem.cs new file mode 100644 index 0000000000..be25f9f6c1 --- /dev/null +++ b/Content.Shared/_White/Standing/SharedLayingDownSystem.cs @@ -0,0 +1,149 @@ +using Content.Shared.DoAfter; +using Content.Shared.Input; +using Content.Shared.Mobs.Systems; +using Content.Shared.Movement.Systems; +using Content.Shared.Standing; +using Content.Shared.Stunnable; +using Robust.Shared.Input.Binding; +using Robust.Shared.Player; +using Robust.Shared.Serialization; + +namespace Content.Shared._White.Standing; + +public abstract class SharedLayingDownSystem : EntitySystem +{ + [Dependency] private readonly MobStateSystem _mobState = default!; + [Dependency] private readonly StandingStateSystem _standing = default!; + [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; + + + public override void Initialize() + { + CommandBinds.Builder + .Bind(ContentKeyFunctions.ToggleStanding, InputCmdHandler.FromDelegate(ToggleStanding)) + .Register(); + + SubscribeNetworkEvent(OnChangeState); + + SubscribeLocalEvent(OnStandingUpDoAfter); + SubscribeLocalEvent(OnRefreshMovementSpeed); + SubscribeLocalEvent(OnParentChanged); + } + + public override void Shutdown() + { + base.Shutdown(); + + CommandBinds.Unregister(); + } + + private void ToggleStanding(ICommonSession? session) + { + if (session?.AttachedEntity == null || + !HasComp(session.AttachedEntity)) + return; + + RaiseNetworkEvent(new ChangeLayingDownEvent()); + } + + private void OnChangeState(ChangeLayingDownEvent ev, EntitySessionEventArgs args) + { + if (!args.SenderSession.AttachedEntity.HasValue) + return; + + var uid = args.SenderSession.AttachedEntity.Value; + + // TODO: Wizard + //if (HasComp(uid)) + // return; + + if (!TryComp(uid, out StandingStateComponent? standing) || + !TryComp(uid, out LayingDownComponent? layingDown)) + return; + + RaiseNetworkEvent(new CheckAutoGetUpEvent(GetNetEntity(uid))); + + if (HasComp(uid) || !_mobState.IsAlive(uid)) + return; + + if (_standing.IsDown(uid, standing)) + TryStandUp(uid, layingDown, standing); + else + TryLieDown(uid, layingDown, standing); + } + + private void OnStandingUpDoAfter(EntityUid uid, StandingStateComponent component, StandingUpDoAfterEvent args) + { + if (args.Handled || args.Cancelled || HasComp(uid) || + _mobState.IsIncapacitated(uid) || !_standing.Stand(uid)) + component.CurrentState = StandingState.Lying; + + component.CurrentState = StandingState.Standing; + } + private void OnRefreshMovementSpeed(EntityUid uid, LayingDownComponent component, RefreshMovementSpeedModifiersEvent args) + { + if (_standing.IsDown(uid)) + args.ModifySpeed(component.SpeedModify, component.SpeedModify); + else + args.ModifySpeed(1f, 1f); + } + + private void OnParentChanged(EntityUid uid, LayingDownComponent component, EntParentChangedMessage args) + { + // If the entity is not on a grid, try to make it stand up to avoid issues + if (!TryComp(uid, out var standingState) + || standingState.CurrentState is StandingState.Standing + || Transform(uid).GridUid != null) + return; + + TryStandUp(uid, component, standingState); + } + + public bool TryStandUp(EntityUid uid, LayingDownComponent? layingDown = null, StandingStateComponent? standingState = null) + { + if (!Resolve(uid, ref standingState, false) || + !Resolve(uid, ref layingDown, false) || + standingState.CurrentState is not StandingState.Lying || + !_mobState.IsAlive(uid) || + TerminatingOrDeleted(uid)) + return false; + + var args = new DoAfterArgs(EntityManager, uid, layingDown.StandingUpTime, new StandingUpDoAfterEvent(), uid) + { + BreakOnHandChange = false, + RequireCanInteract = false + }; + + if (!_doAfter.TryStartDoAfter(args)) + return false; + + standingState.CurrentState = StandingState.GettingUp; + return true; + } + + public bool TryLieDown(EntityUid uid, LayingDownComponent? layingDown = null, StandingStateComponent? standingState = null, DropHeldItemsBehavior behavior = DropHeldItemsBehavior.NoDrop) + { + if (!Resolve(uid, ref standingState, false) || + !Resolve(uid, ref layingDown, false) || + standingState.CurrentState is not StandingState.Standing) + { + if (behavior == DropHeldItemsBehavior.AlwaysDrop) + RaiseLocalEvent(uid, new DropHandItemsEvent()); + + return false; + } + + _standing.Down(uid, true, behavior != DropHeldItemsBehavior.NoDrop, standingState); + return true; + } +} + +[Serializable, NetSerializable] +public sealed partial class StandingUpDoAfterEvent : SimpleDoAfterEvent; + +public enum DropHeldItemsBehavior : byte +{ + NoDrop, + DropIfStanding, + AlwaysDrop +} diff --git a/Resources/Locale/en-US/_white/escape-menu/options-menu.ftl b/Resources/Locale/en-US/_white/escape-menu/options-menu.ftl new file mode 100644 index 0000000000..ff46226c0d --- /dev/null +++ b/Resources/Locale/en-US/_white/escape-menu/options-menu.ftl @@ -0,0 +1,2 @@ +ui-options-function-look-up = Look up +ui-options-function-auto-get-up = Automatically get up after falling \ No newline at end of file diff --git a/Resources/Locale/ru-RU/_white/escape-menu/options-menu.ftl b/Resources/Locale/ru-RU/_white/escape-menu/options-menu.ftl new file mode 100644 index 0000000000..5561521eda --- /dev/null +++ b/Resources/Locale/ru-RU/_white/escape-menu/options-menu.ftl @@ -0,0 +1,2 @@ +ui-options-function-look-up = Присмотреться +ui-options-function-auto-get-up = Автоматически вставать при падении \ No newline at end of file From bb534ff5c6e936aaa29d35066ec713cc9de82313 Mon Sep 17 00:00:00 2001 From: Spatison <137375981+Spatison@users.noreply.github.com> Date: Tue, 20 Aug 2024 17:52:03 +0300 Subject: [PATCH 2/5] fix: rotation --- Content.Client/Buckle/BuckleSystem.cs | 1 - .../_White/Standing/LayingDownSystem.cs | 17 +++---------- Content.Server/Standing/LayingDownSystem.cs | 25 ++++++++++++++++++- Content.Shared/Stunnable/SharedStunSystem.cs | 11 +++----- 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/Content.Client/Buckle/BuckleSystem.cs b/Content.Client/Buckle/BuckleSystem.cs index fea18e5cf3..b899a88106 100644 --- a/Content.Client/Buckle/BuckleSystem.cs +++ b/Content.Client/Buckle/BuckleSystem.cs @@ -57,7 +57,6 @@ private void OnAppearanceChange(EntityUid uid, BuckleComponent component, ref Ap !buckled || args.Sprite == null) { - _rotationVisualizerSystem.SetHorizontalAngle((uid, rotVisuals), rotVisuals.DefaultRotation); return; } diff --git a/Content.Client/_White/Standing/LayingDownSystem.cs b/Content.Client/_White/Standing/LayingDownSystem.cs index a1ef121bed..0e0ee11e8f 100644 --- a/Content.Client/_White/Standing/LayingDownSystem.cs +++ b/Content.Client/_White/Standing/LayingDownSystem.cs @@ -1,11 +1,9 @@ -using Content.Shared._White; using Content.Shared._White.Standing; using Content.Shared.Buckle; using Content.Shared.Rotation; using Content.Shared.Standing; using Robust.Client.GameObjects; using Robust.Client.Graphics; -using Robust.Shared.Configuration; using Robust.Shared.Timing; namespace Content.Client._White.Standing; @@ -17,7 +15,6 @@ public sealed class LayingDownSystem : SharedLayingDownSystem [Dependency] private readonly StandingStateSystem _standing = default!; [Dependency] private readonly AnimationPlayerSystem _animation = default!; [Dependency] private readonly SharedBuckleSystem _buckle = default!; - [Dependency] private readonly INetConfigurationManager _cfg = default!; public override void Initialize() { @@ -45,9 +42,9 @@ private void OnMovementInput(EntityUid uid, LayingDownComponent component, MoveE if (!TryComp(uid, out var transform) || !TryComp(uid, out var sprite)) return; - var rotation = transform.LocalRotation.Degrees + _eyeManager.CurrentEye.Rotation.Degrees; + var rotation = transform.LocalRotation + (_eyeManager.CurrentEye.Rotation - (transform.LocalRotation - transform.WorldRotation)); - if (Angle.FromDegrees(rotation).GetDir() is Direction.SouthEast or Direction.East or Direction.NorthEast or Direction.North) + if (rotation.GetDir() is Direction.SouthEast or Direction.East or Direction.NorthEast or Direction.North) { sprite.Rotation = Angle.FromDegrees(270); return; @@ -63,18 +60,12 @@ private void OnCheckAutoGetUp(CheckAutoGetUpEvent ev, EntitySessionEventArgs arg var uid = GetEntity(ev.User); - if (!TryComp(uid, out LayingDownComponent? layingDown)) - return; - - layingDown.AutoGetUp = _cfg.GetClientCVar(args.SenderSession.Channel, WhiteCVars.AutoGetUp); - Dirty(uid, layingDown); - if (!TryComp(uid, out var transform) || !TryComp(uid, out var rotationVisuals)) return; - var rotation = transform.LocalRotation.Degrees + _eyeManager.CurrentEye.Rotation.Degrees; + var rotation = transform.LocalRotation + (_eyeManager.CurrentEye.Rotation - (transform.LocalRotation - transform.WorldRotation)); - if (Angle.FromDegrees(rotation).GetDir() is Direction.SouthEast or Direction.East or Direction.NorthEast or Direction.North) + if (rotation.GetDir() is Direction.SouthEast or Direction.East or Direction.NorthEast or Direction.North) { rotationVisuals.HorizontalRotation = Angle.FromDegrees(270); return; diff --git a/Content.Server/Standing/LayingDownSystem.cs b/Content.Server/Standing/LayingDownSystem.cs index 7d9dd6ed93..eccbf0773b 100644 --- a/Content.Server/Standing/LayingDownSystem.cs +++ b/Content.Server/Standing/LayingDownSystem.cs @@ -1,5 +1,28 @@ +using Content.Shared._White; using Content.Shared._White.Standing; +using Robust.Shared.Configuration; namespace Content.Server.Standing; -public sealed class LayingDownSystem : SharedLayingDownSystem; +public sealed class LayingDownSystem : SharedLayingDownSystem // WD EDIT +{ + [Dependency] private readonly INetConfigurationManager _cfg = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeNetworkEvent(OnCheckAutoGetUp); + } + + private void OnCheckAutoGetUp(CheckAutoGetUpEvent ev, EntitySessionEventArgs args) + { + var uid = GetEntity(ev.User); + + if (!TryComp(uid, out LayingDownComponent? layingDown)) + return; + + layingDown.AutoGetUp = _cfg.GetClientCVar(args.SenderSession.Channel, WhiteCVars.AutoGetUp); + Dirty(uid, layingDown); + } +} diff --git a/Content.Shared/Stunnable/SharedStunSystem.cs b/Content.Shared/Stunnable/SharedStunSystem.cs index ddac3d3942..3f6ef8999d 100644 --- a/Content.Shared/Stunnable/SharedStunSystem.cs +++ b/Content.Shared/Stunnable/SharedStunSystem.cs @@ -113,23 +113,20 @@ private void UpdateCanMove(EntityUid uid, StunnedComponent component, EntityEven private void OnKnockInit(EntityUid uid, KnockedDownComponent component, ComponentInit args) { + RaiseNetworkEvent(new CheckAutoGetUpEvent(GetNetEntity(uid))); // WD EDIT _layingDown.TryLieDown(uid, null, null, DropHeldItemsBehavior.DropIfStanding); // WD EDIT } private void OnKnockShutdown(EntityUid uid, KnockedDownComponent component, ComponentShutdown args) { // WD EDIT START - RaiseNetworkEvent(new CheckAutoGetUpEvent(GetNetEntity(uid))); - if (!TryComp(uid, out StandingStateComponent? standing)) return; - if (!TryComp(uid, out LayingDownComponent? layingDown) || !layingDown.AutoGetUp) - return; - - if (layingDown.AutoGetUp && !_container.IsEntityInContainer(uid)) + if (TryComp(uid, out LayingDownComponent? layingDown)) { - _layingDown.TryStandUp(uid, layingDown); + if (layingDown.AutoGetUp && !_container.IsEntityInContainer(uid)) + _layingDown.TryStandUp(uid, layingDown); return; } From 5e913b385040c4f01a8dc9e6427ba2d49c82574e Mon Sep 17 00:00:00 2001 From: Spatison <137375981+Spatison@users.noreply.github.com> Date: Thu, 22 Aug 2024 11:11:46 +0300 Subject: [PATCH 3/5] fix --- .../_White/Standing/SharedLayingDownSystem.cs | 17 +++++++++++++++-- .../en-US/_white/escape-menu/options-menu.ftl | 1 - .../ru-RU/_white/escape-menu/options-menu.ftl | 1 - 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/Content.Shared/_White/Standing/SharedLayingDownSystem.cs b/Content.Shared/_White/Standing/SharedLayingDownSystem.cs index be25f9f6c1..86c6b92992 100644 --- a/Content.Shared/_White/Standing/SharedLayingDownSystem.cs +++ b/Content.Shared/_White/Standing/SharedLayingDownSystem.cs @@ -1,4 +1,5 @@ using Content.Shared.DoAfter; +using Content.Shared.Gravity; using Content.Shared.Input; using Content.Shared.Mobs.Systems; using Content.Shared.Movement.Systems; @@ -15,7 +16,7 @@ public abstract class SharedLayingDownSystem : EntitySystem [Dependency] private readonly MobStateSystem _mobState = default!; [Dependency] private readonly StandingStateSystem _standing = default!; [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; - + [Dependency] private readonly SharedGravitySystem _gravity = default!; public override void Initialize() { @@ -40,8 +41,11 @@ public override void Shutdown() private void ToggleStanding(ICommonSession? session) { if (session?.AttachedEntity == null || - !HasComp(session.AttachedEntity)) + !HasComp(session.AttachedEntity) || + _gravity.IsWeightless(session.AttachedEntity.Value)) + { return; + } RaiseNetworkEvent(new ChangeLayingDownEvent()); } @@ -59,7 +63,9 @@ private void OnChangeState(ChangeLayingDownEvent ev, EntitySessionEventArgs args if (!TryComp(uid, out StandingStateComponent? standing) || !TryComp(uid, out LayingDownComponent? layingDown)) + { return; + } RaiseNetworkEvent(new CheckAutoGetUpEvent(GetNetEntity(uid))); @@ -76,10 +82,13 @@ private void OnStandingUpDoAfter(EntityUid uid, StandingStateComponent component { if (args.Handled || args.Cancelled || HasComp(uid) || _mobState.IsIncapacitated(uid) || !_standing.Stand(uid)) + { component.CurrentState = StandingState.Lying; + } component.CurrentState = StandingState.Standing; } + private void OnRefreshMovementSpeed(EntityUid uid, LayingDownComponent component, RefreshMovementSpeedModifiersEvent args) { if (_standing.IsDown(uid)) @@ -94,7 +103,9 @@ private void OnParentChanged(EntityUid uid, LayingDownComponent component, EntPa if (!TryComp(uid, out var standingState) || standingState.CurrentState is StandingState.Standing || Transform(uid).GridUid != null) + { return; + } TryStandUp(uid, component, standingState); } @@ -106,7 +117,9 @@ public bool TryStandUp(EntityUid uid, LayingDownComponent? layingDown = null, St standingState.CurrentState is not StandingState.Lying || !_mobState.IsAlive(uid) || TerminatingOrDeleted(uid)) + { return false; + } var args = new DoAfterArgs(EntityManager, uid, layingDown.StandingUpTime, new StandingUpDoAfterEvent(), uid) { diff --git a/Resources/Locale/en-US/_white/escape-menu/options-menu.ftl b/Resources/Locale/en-US/_white/escape-menu/options-menu.ftl index ff46226c0d..8ef2b1639a 100644 --- a/Resources/Locale/en-US/_white/escape-menu/options-menu.ftl +++ b/Resources/Locale/en-US/_white/escape-menu/options-menu.ftl @@ -1,2 +1 @@ -ui-options-function-look-up = Look up ui-options-function-auto-get-up = Automatically get up after falling \ No newline at end of file diff --git a/Resources/Locale/ru-RU/_white/escape-menu/options-menu.ftl b/Resources/Locale/ru-RU/_white/escape-menu/options-menu.ftl index 5561521eda..8ac060bbaf 100644 --- a/Resources/Locale/ru-RU/_white/escape-menu/options-menu.ftl +++ b/Resources/Locale/ru-RU/_white/escape-menu/options-menu.ftl @@ -1,2 +1 @@ -ui-options-function-look-up = Присмотреться ui-options-function-auto-get-up = Автоматически вставать при падении \ No newline at end of file From f65bcf7efbe2be543cb2e26bc902163b4cef9617 Mon Sep 17 00:00:00 2001 From: Spatison <137375981+Spatison@users.noreply.github.com> Date: Thu, 22 Aug 2024 12:44:06 +0300 Subject: [PATCH 4/5] fix: rotation --- Content.Client/_White/Standing/LayingDownSystem.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Content.Client/_White/Standing/LayingDownSystem.cs b/Content.Client/_White/Standing/LayingDownSystem.cs index 0e0ee11e8f..c60a07f5c1 100644 --- a/Content.Client/_White/Standing/LayingDownSystem.cs +++ b/Content.Client/_White/Standing/LayingDownSystem.cs @@ -39,17 +39,23 @@ private void OnMovementInput(EntityUid uid, LayingDownComponent component, MoveE if (_animation.HasRunningAnimation(uid, "rotate")) return; - if (!TryComp(uid, out var transform) || !TryComp(uid, out var sprite)) + if (!TryComp(uid, out var transform) + || !TryComp(uid, out var sprite) + || !TryComp(uid, out var rotationVisuals)) + { return; + } var rotation = transform.LocalRotation + (_eyeManager.CurrentEye.Rotation - (transform.LocalRotation - transform.WorldRotation)); if (rotation.GetDir() is Direction.SouthEast or Direction.East or Direction.NorthEast or Direction.North) { + rotationVisuals.HorizontalRotation = Angle.FromDegrees(270); sprite.Rotation = Angle.FromDegrees(270); return; } + rotationVisuals.HorizontalRotation = Angle.FromDegrees(90); sprite.Rotation = Angle.FromDegrees(90); } From f9f4f07eed058ce73d217f3bdfa4b6b228217895 Mon Sep 17 00:00:00 2001 From: Spatison <137375981+Spatison@users.noreply.github.com> Date: Thu, 22 Aug 2024 12:49:46 +0300 Subject: [PATCH 5/5] fix --- Content.Shared/_White/Standing/SharedLayingDownSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Shared/_White/Standing/SharedLayingDownSystem.cs b/Content.Shared/_White/Standing/SharedLayingDownSystem.cs index 86c6b92992..2406d19a37 100644 --- a/Content.Shared/_White/Standing/SharedLayingDownSystem.cs +++ b/Content.Shared/_White/Standing/SharedLayingDownSystem.cs @@ -107,7 +107,7 @@ private void OnParentChanged(EntityUid uid, LayingDownComponent component, EntPa return; } - TryStandUp(uid, component, standingState); + _standing.Stand(uid, standingState); } public bool TryStandUp(EntityUid uid, LayingDownComponent? layingDown = null, StandingStateComponent? standingState = null)