diff --git a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs index 883f517ad5..b5449c99d2 100644 --- a/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs +++ b/Content.Client/Options/UI/Tabs/KeyRebindTab.xaml.cs @@ -2,6 +2,7 @@ using System.Numerics; using Content.Client.Stylesheets; using Content.Shared.CCVar; using Content.Shared.Input; +using Content.Shared._White; using Robust.Client.AutoGenerated; using Robust.Client.Input; using Robust.Client.UserInterface; @@ -97,6 +98,12 @@ namespace Content.Client.Options.UI.Tabs _deferCommands.Add(_inputManager.SaveToUserData); } + private void HandleToggleAutoGetUp(BaseButton.ButtonToggledEventArgs args) // WD EDIT + { + _cfg.SetCVar(WhiteCVars.AutoGetUp, args.Pressed); + _cfg.SaveToFile(); + } + private void HandleStaticStorageUI(BaseButton.ButtonToggledEventArgs args) { _cfg.SetCVar(CCVars.StaticStorageUI, args.Pressed); @@ -185,6 +192,7 @@ namespace Content.Client.Options.UI.Tabs AddButton(ContentKeyFunctions.RotateStoredItem); AddButton(ContentKeyFunctions.SaveItemLocation); AddButton(ContentKeyFunctions.LieDown); // WD EDIT + AddCheckBox("ui-options-function-auto-get-up", _cfg.GetCVar(WhiteCVars.AutoGetUp), HandleToggleAutoGetUp); // WD EDIT AddHeader("ui-options-header-interaction-adv"); AddButton(ContentKeyFunctions.SmartEquipBackpack); diff --git a/Content.Client/Standing/StandingStateSystem.cs b/Content.Client/Standing/StandingStateSystem.cs index dcc4b97d2e..42f2e62427 100644 --- a/Content.Client/Standing/StandingStateSystem.cs +++ b/Content.Client/Standing/StandingStateSystem.cs @@ -6,4 +6,4 @@ namespace Content.Client.Standing; public sealed class StandingStateSystem : SharedStandingStateSystem { -} \ No newline at end of file +} diff --git a/Content.Client/_White/Rotation/RotationVisualizerSystem.cs b/Content.Client/_White/Rotation/RotationVisualizerSystem.cs new file mode 100644 index 0000000000..74d31fb1f5 --- /dev/null +++ b/Content.Client/_White/Rotation/RotationVisualizerSystem.cs @@ -0,0 +1,41 @@ +using Content.Shared.Rotation; +using Robust.Client.GameObjects; + +namespace Content.Client._White.Rotation; + +public sealed class RotationVisualizerSystem : EntitySystem +{ + [Dependency] private readonly AppearanceSystem _appearance = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; + public override void Initialize() + { + SubscribeLocalEvent(OnMove); + } + + private void OnMove(EntityUid uid, RotationVisualsComponent component, ref MoveEvent args) + { + if (!TryComp(uid, out var sprite) || + !TryComp(uid, out var appearance)) + return; + + _appearance.TryGetData(uid, RotationVisuals.RotationState, out var state, appearance); + + var rotation = _transform.GetWorldRotation(uid); + + if (rotation.GetDir() is Direction.East or Direction.North or Direction.NorthEast or Direction.SouthEast) + { + if (state == RotationState.Horizontal && + sprite.Rotation == component.DefaultRotation) + { + sprite.Rotation = Angle.FromDegrees(270); + } + + return; + } + if (state == RotationState.Horizontal && + sprite.Rotation == Angle.FromDegrees(270)) + { + sprite.Rotation = component.DefaultRotation; + } + } +} diff --git a/Content.Server/Chat/Managers/ChatSanitizationManager.cs b/Content.Server/Chat/Managers/ChatSanitizationManager.cs index c68eaa2009..adeff51b50 100644 --- a/Content.Server/Chat/Managers/ChatSanitizationManager.cs +++ b/Content.Server/Chat/Managers/ChatSanitizationManager.cs @@ -161,7 +161,7 @@ public sealed class ChatSanitizationManager : IChatSanitizationManager //WD-EDIT public string SanitizeOutSlang(string input) { - var pattern = @"(^\!|^\?|[\p{L}\d'`-]+)"; + var pattern = @"(^\!|^\?|[\p{L}\d'`%-]+)"; var newMessage = Regex.Replace(input, pattern , match => _slangToNormal.ContainsKey(match.Groups[1].Value.ToLower()) ? _slangToNormal[match.Groups[1].Value.ToLower()] : match.Value, RegexOptions.IgnoreCase); diff --git a/Content.Server/NPC/HTN/PrimitiveTasks/Operators/SpeakOperator.cs b/Content.Server/NPC/HTN/PrimitiveTasks/Operators/SpeakOperator.cs index cf07831959..613a15d21b 100644 --- a/Content.Server/NPC/HTN/PrimitiveTasks/Operators/SpeakOperator.cs +++ b/Content.Server/NPC/HTN/PrimitiveTasks/Operators/SpeakOperator.cs @@ -1,13 +1,16 @@ using Content.Server.Chat.Systems; +using Content.Shared.Random.Helpers; +using Robust.Shared.Random; namespace Content.Server.NPC.HTN.PrimitiveTasks.Operators; public sealed partial class SpeakOperator : HTNOperator { private ChatSystem _chat = default!; + private IRobustRandom _random = default!; [DataField("speech", required: true)] - public string Speech = string.Empty; + public List Speech { get; set; } = new(); /// /// Whether to hide message from chat window and logs. @@ -19,13 +22,15 @@ public sealed partial class SpeakOperator : HTNOperator { base.Initialize(sysManager); _chat = IoCManager.Resolve().GetEntitySystem(); + _random = IoCManager.Resolve(); } public override HTNOperatorStatus Update(NPCBlackboard blackboard, float frameTime) { var speaker = blackboard.GetValue(NPCBlackboard.Owner); + var message = Loc.GetString(_random.Pick(Speech)); - _chat.TrySendInGameICMessage(speaker, Loc.GetString(Speech), InGameICChatType.Speak, hideChat: Hidden, hideLog: Hidden); + _chat.TrySendInGameICMessage(speaker, message, InGameICChatType.Speak, hideChat: Hidden, hideLog: Hidden); return base.Update(blackboard, frameTime); } } diff --git a/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs b/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs index ec4693b3f4..3287ced1bc 100644 --- a/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs +++ b/Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs @@ -10,8 +10,6 @@ using Content.Shared.Interaction; using Content.Shared.Mobs.Components; using Content.Shared.Movement.Events; using Content.Shared.Popups; -using Content.Shared.Standing; -using Content.Shared.Standing.Systems; using Content.Shared.Storage.Components; using Content.Shared.Stunnable; using Content.Shared.Throwing; @@ -35,8 +33,6 @@ public abstract partial class SharedBuckleSystem SubscribeLocalEvent(OnBuckleInsertIntoEntityStorageAttempt); SubscribeLocalEvent(OnBucklePreventCollide); - SubscribeLocalEvent(OnBuckleDownAttempt); - SubscribeLocalEvent(OnBuckleStandAttempt); SubscribeLocalEvent(OnBuckleThrowPushbackAttempt); SubscribeLocalEvent(OnBuckleUpdateCanMove); } @@ -114,18 +110,6 @@ public abstract partial class SharedBuckleSystem args.Cancelled = true; } - private void OnBuckleDownAttempt(EntityUid uid, BuckleComponent component, DownAttemptEvent args) - { - if (component.Buckled) - args.Cancel(); - } - - private void OnBuckleStandAttempt(EntityUid uid, BuckleComponent component, StandAttemptEvent args) - { - if (component.Buckled) - args.Cancel(); - } - private void OnBuckleThrowPushbackAttempt(EntityUid uid, BuckleComponent component, ThrowPushbackAttemptEvent args) { if (component.Buckled) diff --git a/Content.Shared/Standing/StandingStateComponent.cs b/Content.Shared/Standing/StandingStateComponent.cs index 3db3488084..7af773cdb7 100644 --- a/Content.Shared/Standing/StandingStateComponent.cs +++ b/Content.Shared/Standing/StandingStateComponent.cs @@ -1,11 +1,12 @@ using Content.Shared.Standing.Systems; +using Content.Shared._White.Standing; using Robust.Shared.Audio; using Robust.Shared.GameStates; using Robust.Shared.Serialization; namespace Content.Shared.Standing { - [RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(SharedStandingStateSystem))] + [RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(SharedStandingStateSystem), typeof(StandingStateSystem))] public sealed partial class StandingStateComponent : Component { [ViewVariables(VVAccess.ReadWrite), DataField] @@ -23,19 +24,29 @@ namespace Content.Shared.Standing // WD EDIT [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)] public bool CanLieDown = false; - + + // WD EDIT + [DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadWrite)] + public bool AutoGetUp = false; + /// /// 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(); - + } } [Serializable, NetSerializable] -public sealed class ChangeStandingStateEvent : EntityEventArgs +public sealed class ChangeStandingStateEvent : CancellableEntityEventArgs +{ +} + +// WD EDIT +[Serializable, NetSerializable] +public sealed class CheckAutoGetUpEvent : CancellableEntityEventArgs { } @@ -45,4 +56,4 @@ public enum StandingState Lying, GettingUp, Standing -} \ No newline at end of file +} diff --git a/Content.Shared/Standing/Systems/SharedStandingStateSystem.cs b/Content.Shared/Standing/Systems/SharedStandingStateSystem.cs index 35f1fccff8..58344769a7 100644 --- a/Content.Shared/Standing/Systems/SharedStandingStateSystem.cs +++ b/Content.Shared/Standing/Systems/SharedStandingStateSystem.cs @@ -7,6 +7,9 @@ using Content.Shared.Physics; using Content.Shared.Rotation; using Content.Shared.Slippery; using Content.Shared.Stunnable; +using Content.Shared._White.Wizard.Timestop; +using Content.Shared.Buckle; +using Content.Shared.Buckle.Components; using Robust.Shared.Audio.Systems; using Robust.Shared.Input.Binding; using Robust.Shared.Physics; @@ -14,6 +17,7 @@ using Robust.Shared.Physics.Systems; using Robust.Shared.Player; using Robust.Shared.Serialization; + namespace Content.Shared.Standing.Systems; public abstract partial class SharedStandingStateSystem : EntitySystem @@ -25,6 +29,9 @@ public abstract partial class SharedStandingStateSystem : EntitySystem [Dependency] private readonly MovementSpeedModifierSystem _movement = default!; // WD EDIT [Dependency] private readonly SharedStunSystem _stun = default!; // WD EDIT [Dependency] private readonly MobStateSystem _mobState = default!; // WD EDIT + [Dependency] private readonly SharedBuckleSystem _buckle = default!; // WD EDIT + [Dependency] private readonly SharedTransformSystem _transform = default!; // WD EDIT + [Dependency] private readonly SharedRotationVisualsSystem _rotation = 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; @@ -53,6 +60,9 @@ public abstract partial class SharedStandingStateSystem : EntitySystem private void OnChangeState(ChangeStandingStateEvent ev, EntitySessionEventArgs args) { + if (TryComp(args.SenderSession.AttachedEntity, out _)) // WD EDIT + return; + if (!args.SenderSession.AttachedEntity.HasValue) { return; @@ -60,6 +70,11 @@ public abstract partial class SharedStandingStateSystem : EntitySystem var uid = args.SenderSession.AttachedEntity.Value; + if (!TryComp(uid, out StandingStateComponent? standing)) // WD EDIT + return; + + RaiseNetworkEvent(new CheckAutoGetUpEvent()); + if (_stun.IsParalyzed(uid)) { return; @@ -70,18 +85,23 @@ public abstract partial class SharedStandingStateSystem : EntitySystem return; } - if (IsDown(uid)) + if (IsDown(uid, standing)) { - TryStandUp(uid); + TryStandUp(uid, standing); } else { - TryLieDown(uid); + TryLieDown(uid, standing); } } private void OnStandingUpDoAfter(EntityUid uid, StandingStateComponent component, StandingUpDoAfterEvent args) { + if (args.Handled) // WD EDIT + { + component.CurrentState = StandingState.Lying; + return; + } Stand(uid); } @@ -192,6 +212,9 @@ public abstract partial class SharedStandingStateSystem : EntitySystem // Optional component. Resolve(uid, ref appearance, ref hands, false); + if (TryComp(uid, out BuckleComponent? buckle) && buckle.Buckled && !_buckle.TryUnbuckle(uid, uid, buckleComp: buckle)) // WD EDIT + return false; + // This is just to avoid most callers doing this manually saving boilerplate // 99% of the time you'll want to drop items but in some scenarios (e.g. buckling) you don't want to. // We do this BEFORE downing because something like buckle may be blocking downing but we want to drop hand items anyway @@ -212,6 +235,14 @@ public abstract partial class SharedStandingStateSystem : EntitySystem standingState.CurrentState = StandingState.Lying; Dirty(uid, standingState); + + var rotation = _transform.GetWorldRotation(uid); + + if (rotation.GetDir() is Direction.East or Direction.North or Direction.NorthEast or Direction.SouthEast) + _rotation.SetHorizontalAngle(uid, Angle.FromDegrees(270)); + else + _rotation.ResetHorizontalAngle(uid); + RaiseLocalEvent(uid, new DownedEvent()); // Seemed like the best place to put it diff --git a/Content.Shared/Stunnable/SharedStunSystem.cs b/Content.Shared/Stunnable/SharedStunSystem.cs index 8586e46a9a..f278665576 100644 --- a/Content.Shared/Stunnable/SharedStunSystem.cs +++ b/Content.Shared/Stunnable/SharedStunSystem.cs @@ -104,6 +104,7 @@ public abstract class SharedStunSystem : EntitySystem private void OnKnockInit(EntityUid uid, KnockedDownComponent component, ComponentInit args) { + RaiseNetworkEvent(new CheckAutoGetUpEvent()); // WD EDIT _standingState.Down(uid); } @@ -111,7 +112,7 @@ public abstract class SharedStunSystem : EntitySystem { // WD EDIT START // Don't stand up if we can lie down via keybind - if (!TryComp(uid, out StandingStateComponent? standing) || standing.CanLieDown) + if (!TryComp(uid, out StandingStateComponent? standing) || !(!standing.CanLieDown || standing.AutoGetUp)) // WD EDIT return; _standingState.Stand(uid, standing); diff --git a/Content.Shared/_White/Standing/StandingStateSystem.cs b/Content.Shared/_White/Standing/StandingStateSystem.cs new file mode 100644 index 0000000000..f0c4f77771 --- /dev/null +++ b/Content.Shared/_White/Standing/StandingStateSystem.cs @@ -0,0 +1,29 @@ +using Content.Shared.Standing; +using Robust.Shared.Configuration; + +namespace Content.Shared._White.Standing; + +public sealed class StandingStateSystem : EntitySystem +{ + + [Dependency] private readonly INetConfigurationManager _cfg = default!; + public override void Initialize() + { + SubscribeNetworkEvent(OnCheckAutoGetUp); + } + + + private void OnCheckAutoGetUp(CheckAutoGetUpEvent ev, EntitySessionEventArgs args) + { + if (!args.SenderSession.AttachedEntity.HasValue) + return; + + var uid = args.SenderSession.AttachedEntity.Value; + + if (!TryComp(uid, out StandingStateComponent? standing)) + return; + + standing.AutoGetUp = _cfg.GetClientCVar(args.SenderSession.Channel, WhiteCVars.AutoGetUp); + Dirty(args.SenderSession.AttachedEntity.Value, standing); + } +} diff --git a/Content.Shared/_White/WhiteCVars.cs b/Content.Shared/_White/WhiteCVars.cs index 98c13db7d3..da434e771b 100644 --- a/Content.Shared/_White/WhiteCVars.cs +++ b/Content.Shared/_White/WhiteCVars.cs @@ -307,6 +307,12 @@ public sealed class WhiteCVars public static readonly CVarDef LogChatActions = CVarDef.Create("white.log_to_chat", true, CVar.CLIENT | CVar.ARCHIVE | CVar.REPLICATED); + /// + /// Determines whether automatic get up is required + /// + public static readonly CVarDef AutoGetUp = + CVarDef.Create("white.auto_get_up", true, CVar.CLIENT | CVar.ARCHIVE | CVar.REPLICATED); + /* * Aspects */ diff --git a/Content.Shared/_White/Wizard/Timestop/FreezeContactsSystem.cs b/Content.Shared/_White/Wizard/Timestop/FreezeContactsSystem.cs index 4db8bbecaa..3880c11dd3 100644 --- a/Content.Shared/_White/Wizard/Timestop/FreezeContactsSystem.cs +++ b/Content.Shared/_White/Wizard/Timestop/FreezeContactsSystem.cs @@ -36,6 +36,7 @@ public sealed class FreezeContactsSystem : EntitySystem SubscribeLocalEvent(OnRemove); SubscribeLocalEvent(OnPreventCollide); SubscribeLocalEvent(OnGetInserted); + SubscribeLocalEvent(OnStandingUpDoAfter); SubscribeLocalEvent(OnAttempt); SubscribeLocalEvent(OnAttempt); @@ -61,6 +62,11 @@ public sealed class FreezeContactsSystem : EntitySystem args.Cancel(); } + private void OnStandingUpDoAfter(EntityUid uid, FrozenComponent component, StandingUpDoAfterEvent args) + { + args.Handled = true; + } + private void OnAttempt(EntityUid uid, FrozenComponent component, CancellableEntityEventArgs args) { args.Cancel(); diff --git a/Resources/Changelog/ChangelogWhite.yml b/Resources/Changelog/ChangelogWhite.yml index 8bb19a1d7a..c02f3ef82f 100644 --- a/Resources/Changelog/ChangelogWhite.yml +++ b/Resources/Changelog/ChangelogWhite.yml @@ -5607,3 +5607,42 @@ id: 363 time: '2024-07-07T09:40:00.0000000+00:00' url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/429 +- author: DVOniksWyvern + changes: + - message: "55 \u0441\u043E\u043A\u0440\u0430\u0449\u0435\u043D\u0438\u0439 \u0447\ + \u0435\u0440\u0435\u0437 %" + type: Add + - message: "\u0410\u0432\u0442\u043E\u0437\u0430\u043C\u0435\u043D\u0430 \u0431\u043E\ + \u043B\u044C\u0448\u0435 400 \u0441\u043B\u043E\u0432" + type: Remove + id: 364 + time: '2024-07-09T15:51:01.0000000+00:00' + url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/431 +- author: ThereDrD + changes: + - message: "\u0418\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\ + \u0435 \u0430\u0432\u0442\u043E\u0437\u0430\u043C\u0435\u043D\u044B \u0447\u0435\ + \u0440\u0435\u0437 % \u0441\u043D\u043E\u0432\u0430 \u0440\u0430\u0431\u043E\ + \u0442\u0430\u0435\u0442" + type: Fix + id: 365 + time: '2024-07-10T11:02:03.0000000+00:00' + url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/433 +- author: Spatison + changes: + - message: "\u0411\u043E\u043B\u044C\u0448\u0435 \u043D\u0435\u043B\u044C\u0437\u044F\ + \ \u0432\u0441\u0442\u0430\u0442\u044C \u043F\u0440\u0438 \u043E\u0441\u0442\ + \u0430\u043D\u043E\u0432\u043A\u0435 \u0432\u0440\u0435\u043C\u044F" + type: Fix + - message: "\u0418\u0441\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u043E \u043F\u043E\ + \u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u043B\u0435\u0436\u0430" + type: Fix + - message: "Cvar \u0432\u0441\u0442\u0430\u0432\u0430\u043D\u0438\u044F \u043F\u0440\ + \u0438 \u043F\u0430\u0434\u0435\u043D\u0438\u0438" + type: Tweak + - message: "\u041E\u0442\u043A\u0440\u0435\u043F\u043B\u0435\u043D\u0438\u0435 \u043F\ + \u0440\u0438 \u043F\u0430\u0434\u0435\u043D\u0438\u0438" + type: Tweak + id: 366 + time: '2024-07-10T13:26:50.0000000+00:00' + url: https://api.github.com/repos/frosty-dev/ss14-core/pulls/430 diff --git a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl index 36429c843d..19afd1efdb 100644 --- a/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl +++ b/Resources/Locale/en-US/escape-menu/ui/options-menu.ftl @@ -137,6 +137,7 @@ ui-options-function-swap-hands = Swap hands ui-options-function-move-stored-item = Move stored item ui-options-function-rotate-stored-item = Rotate stored item ui-options-function-lie-down = Lie down/Get up +ui-options-function-auto-get-up = Automatically get up when falling ui-options-function-save-item-location = Save item location ui-options-static-storage-ui = Lock storage window to hotbar diff --git a/Resources/Locale/ru-RU/escape-menu/ui/options-menu.ftl b/Resources/Locale/ru-RU/escape-menu/ui/options-menu.ftl index 11008c1f2b..f87208afd3 100644 --- a/Resources/Locale/ru-RU/escape-menu/ui/options-menu.ftl +++ b/Resources/Locale/ru-RU/escape-menu/ui/options-menu.ftl @@ -139,6 +139,7 @@ ui-options-function-swap-hands = Поменять руки ui-options-function-move-stored-item = Переместить хранящийся объект ui-options-function-rotate-stored-item = Повернуть хранящийся объект ui-options-function-lie-down = Лечь/встать +ui-options-function-auto-get-up = Автоматически вставать при падении ui-options-function-save-item-location = Сохранить позицию предмета ui-options-static-storage-ui = Закрепить интерфейс хранилища на хотбаре diff --git a/Resources/Prototypes/NPCs/medibot.yml b/Resources/Prototypes/NPCs/medibot.yml index c0853984ee..d96c64700f 100644 --- a/Resources/Prototypes/NPCs/medibot.yml +++ b/Resources/Prototypes/NPCs/medibot.yml @@ -20,7 +20,10 @@ - !type:HTNPrimitiveTask operator: !type:SpeakOperator - speech: medibot-start-inject + speech: + - Пожалуйста, не двигайтесь. + - Пожалуйста, стойте на месте. + - Пожалуйста, не шевелитесь. hidden: true - !type:HTNPrimitiveTask