From dff8c69f2afff6714b893a7c9572a84bd384ff89 Mon Sep 17 00:00:00 2001 From: VMSolidus Date: Wed, 25 Dec 2024 21:50:09 -0600 Subject: [PATCH 1/2] Basic Soft-Crit Implementation (#1370) # Description This PR adds a simple server configuration option for enabling basic "Soft-Crit", and not much else because oh my god this system is horribly complicated. When enabled, characters can crawl around very slowly while in crit, and really not much else. This more or less mirrors how crit affects character movement in SS13, where you can at least crawl to relative safety while bleeding to death. # Changelog :cl: - add: Added server config options for basic "Soft-Crit". When enabled, characters who are critically injured can still slowly crawl, but are otherwise still helpless and dying. --- Content.Shared/CCVar/CCVars.cs | 23 +++++++++++++++ .../Systems/MobStateSystem.Subscribers.cs | 28 +++++++++++++++++-- .../Systems/SharedMoverController.Input.cs | 7 +++-- .../Movement/Systems/SharedMoverController.cs | 7 +++-- 4 files changed, 58 insertions(+), 7 deletions(-) diff --git a/Content.Shared/CCVar/CCVars.cs b/Content.Shared/CCVar/CCVars.cs index 05a0a7f1883..a02cbb6419f 100644 --- a/Content.Shared/CCVar/CCVars.cs +++ b/Content.Shared/CCVar/CCVars.cs @@ -2820,5 +2820,28 @@ public static readonly CVarDef /// public static readonly CVarDef UseDynamicHostname = CVarDef.Create("game.use_dynamic_hostname", false, CVar.SERVERONLY); + + #region SoftCrit + + /// + /// Used for basic Soft-Crit implementation. Entities are allowed to crawl when in crit, as this CVar intercepts the mover controller check for incapacitation, + /// and prevents it from stopping movement if this CVar is set to true and the user is Crit but Not Dead. This is only for movement, + /// you still can't stand up while crit, and you're still more or less helpless. + /// + public static readonly CVarDef AllowMovementWhileCrit = + CVarDef.Create("mobstate.allow_movement_while_crit", true, CVar.REPLICATED); + + public static readonly CVarDef AllowTalkingWhileCrit = + CVarDef.Create("mobstate.allow_talking_while_crit", true, CVar.REPLICATED); + + /// + /// Currently does nothing because I would have to figure out WHERE I would even put this check, and the mover controller is fairly complicated. + /// The goal is to make it so that attempting to move while in 'soft crit' can potentially cause further injury, causing you to die faster. Ideally there would be special + /// actions that can be performed in soft crit, such as applying pressure to your own injuries to slow down the bleedout, or other varieties of "Will To Live". + /// + public static readonly CVarDef DamageWhileCritMove = + CVarDef.Create("mobstate.damage_while_crit_move", false, CVar.REPLICATED); + + #endregion } } diff --git a/Content.Shared/Mobs/Systems/MobStateSystem.Subscribers.cs b/Content.Shared/Mobs/Systems/MobStateSystem.Subscribers.cs index 2088bd4161e..3728813406c 100644 --- a/Content.Shared/Mobs/Systems/MobStateSystem.Subscribers.cs +++ b/Content.Shared/Mobs/Systems/MobStateSystem.Subscribers.cs @@ -1,5 +1,6 @@ using Content.Shared.Bed.Sleep; using Content.Shared.Buckle.Components; +using Content.Shared.CCVar; using Content.Shared.CombatMode.Pacification; using Content.Shared.Damage.ForceSay; using Content.Shared.Emoting; @@ -16,17 +17,20 @@ using Content.Shared.Standing; using Content.Shared.Strip.Components; using Content.Shared.Throwing; +using Robust.Shared.Configuration; using Robust.Shared.Physics.Components; namespace Content.Shared.Mobs.Systems; public partial class MobStateSystem { + [Dependency] private readonly IConfigurationManager _configurationManager = default!; + //General purpose event subscriptions. If you can avoid it register these events inside their own systems private void SubscribeEvents() { SubscribeLocalEvent(OnGettingStripped); - SubscribeLocalEvent(CheckAct); + SubscribeLocalEvent(OnDirectionAttempt); SubscribeLocalEvent(CheckAct); SubscribeLocalEvent(CheckAct); SubscribeLocalEvent(CheckAct); @@ -38,7 +42,7 @@ private void SubscribeEvents() SubscribeLocalEvent(CheckAct); SubscribeLocalEvent(CheckAct); SubscribeLocalEvent(CheckAct); - SubscribeLocalEvent(CheckAct); + SubscribeLocalEvent(OnMoveAttempt); SubscribeLocalEvent(CheckAct); SubscribeLocalEvent(CheckAct); SubscribeLocalEvent(OnSleepAttempt); @@ -48,6 +52,23 @@ private void SubscribeEvents() SubscribeLocalEvent(OnUnbuckleAttempt); } + private void OnDirectionAttempt(Entity ent, ref ChangeDirectionAttemptEvent args) + { + if (ent.Comp.CurrentState is MobState.Critical && _configurationManager.GetCVar(CCVars.AllowMovementWhileCrit)) + return; + + CheckAct(ent.Owner, ent.Comp, args); + } + + private void OnMoveAttempt(Entity ent, ref UpdateCanMoveEvent args) + { + if (ent.Comp.CurrentState is MobState.Critical && _configurationManager.GetCVar(CCVars.AllowMovementWhileCrit)) + return; + + CheckAct(ent.Owner, ent.Comp, args); + } + + private void OnUnbuckleAttempt(Entity ent, ref UnbuckleAttemptEvent args) { // TODO is this necessary? @@ -145,6 +166,9 @@ private void OnSpeakAttempt(EntityUid uid, MobStateComponent component, SpeakAtt return; } + if (component.CurrentState is MobState.Critical && _configurationManager.GetCVar(CCVars.AllowTalkingWhileCrit)) + return; + CheckAct(uid, component, args); } diff --git a/Content.Shared/Movement/Systems/SharedMoverController.Input.cs b/Content.Shared/Movement/Systems/SharedMoverController.Input.cs index 1c097ce17bc..2ea60155570 100644 --- a/Content.Shared/Movement/Systems/SharedMoverController.Input.cs +++ b/Content.Shared/Movement/Systems/SharedMoverController.Input.cs @@ -305,8 +305,11 @@ private void HandleDirChange(EntityUid entity, Direction dir, ushort subTick, bo if (MoverQuery.TryGetComponent(entity, out var mover)) SetMoveInput(mover, MoveButtons.None); - if (!_mobState.IsIncapacitated(entity)) - HandleDirChange(relayMover.RelayEntity, dir, subTick, state); + if (_mobState.IsDead(entity) + || _mobState.IsCritical(entity) && !_configManager.GetCVar(CCVars.AllowMovementWhileCrit)) + return; + + HandleDirChange(relayMover.RelayEntity, dir, subTick, state); return; } diff --git a/Content.Shared/Movement/Systems/SharedMoverController.cs b/Content.Shared/Movement/Systems/SharedMoverController.cs index 43a63068cf2..46ee949a4e2 100644 --- a/Content.Shared/Movement/Systems/SharedMoverController.cs +++ b/Content.Shared/Movement/Systems/SharedMoverController.cs @@ -125,9 +125,10 @@ protected void HandleMobMovement( var canMove = mover.CanMove; if (RelayTargetQuery.TryGetComponent(uid, out var relayTarget)) { - if (_mobState.IsIncapacitated(relayTarget.Source) || - TryComp(relayTarget.Source, out _) || - !MoverQuery.TryGetComponent(relayTarget.Source, out var relayedMover)) + if (_mobState.IsDead(relayTarget.Source) + || TryComp(relayTarget.Source, out _) + || !MoverQuery.TryGetComponent(relayTarget.Source, out var relayedMover) + || _mobState.IsCritical(relayTarget.Source) && !_configManager.GetCVar(CCVars.AllowMovementWhileCrit)) { canMove = false; } From 9430b9046a9a40cc2f96bb3c66251aabbaf9e80a Mon Sep 17 00:00:00 2001 From: SimpleStation Changelogs Date: Thu, 26 Dec 2024 03:50:37 +0000 Subject: [PATCH 2/2] Automatic Changelog Update (#1370) --- Resources/Changelog/Changelog.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 95604a1e21c..1e832dea293 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -8787,3 +8787,13 @@ Entries: id: 6591 time: '2024-12-22T19:57:10.0000000+00:00' url: https://github.com/Simple-Station/Einstein-Engines/pull/1334 +- author: VMSolidus + changes: + - type: Add + message: >- + Added server config options for basic "Soft-Crit". When enabled, + characters who are critically injured can still slowly crawl, but are + otherwise still helpless and dying. + id: 6592 + time: '2024-12-26T03:50:10.0000000+00:00' + url: https://github.com/Simple-Station/Einstein-Engines/pull/1370