Skip to content

Commit 7756b44

Browse files
authored
Cyborg crawling fixes (#5863)
## Short description <!-- What do you propose to change with your PR? --> Cyborgs can now crawl unconditionally as long as they aren't down (and at half speed with a module active). ## Why we need to add this <!-- What is the reason for adding these changes? Please post links to Discussions as well as Bug Reports here. Please describe how this will change the game balance. --> For a long while now cyborgs have had an issue wherein they aren't able to crawl if they had a module deployed and it didn't have any freeform hand slots empty (for example if you had the tools module open you just couldn't crawl at all in any situation). This was very unclear behavior and if you aren't in the know just made it seem like cyborgs arbitrarily can't crawl sometimes. This issue was related to how movement speed is calculated based on available hand slots (if all of your hand slots are occupied, you can't crawl at all). To fix this, two components have been created: 1. CanCrawlWithoutHands, a generic component that can be added to anything we want to be able to crawl without hands. This is used by cyborgs when they don't have a module out because in that state they have no hands. 2. BorgModuleCrawlModifier, a component intended specifically for cyborgs that checks if they have a module active then allows them to crawl at half normal crawling speed if they do, regardless of whether any freeform hand slots are open or are otherwise present (half speed is the speed you would be at when one hand is holding something on an entity with hands that is crawling) Both components have been added to base_borg_chassis.yml so that it affects any cyborgs that inherit from it. This ensures that cyborgs retain their ability to crawl in a manner that's more intuitive and doesn't seem arbitrary. This does not impact their ability to move while crit; cyborgs in crit still cannot move, as expected. Compared to #5789, this is implemented as components instead of adding the carveout directly to the hand system, and CanCrawlWithoutHands was added as a component for generic use by request of @walksanatora. ## Media (Video/Screenshots) <!-- If your PR contains in-game changes you must provide screenshots/videos of the changes. --> https://github.com/user-attachments/assets/ab16cc8d-19d0-43bd-bdf0-4606fc7be2e4 ## Checks <!-- check boxes for faster reviewing of your PR --> - [x] I do not require assistance to complete the PR. - [x] Before posting/requesting review of a PR, I have verified that the changes work. - [x] I have added screenshots/videos of the changes, or this PR does not change in-game mechanics. - [x] I affirm that my changes are licensed under the [MIT License](https://github.com/ss14Starlight/space-station-14/blob/Starlight/LICENSE.TXT) and grant permission for use in this repository under its conditions. **Changelog** <!-- If you want the players to know about changes made in this PR, specify them using the template outside the comment. Short and informative. :cl: STARLIGHT TEAM - add: Added Starlight. - remove: Removed SS13. - tweak: Changed SS14. - fix: Fixed Rinary. --> :cl: Rhapsody (Pepta Vismahl) - tweak: Cyborgs can now crawl without a module active, and crawl at half speed with any module active.
1 parent b49e622 commit 7756b44

5 files changed

Lines changed: 114 additions & 0 deletions

File tree

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using Robust.Shared.GameStates;
2+
3+
namespace Content.Shared._Starlight.Silicons.Borgs;
4+
5+
/// <summary>
6+
/// When attached to a cyborg chassis, modifies crawling speed when a module is active.
7+
/// Decouples crawl speed from hand count and applies a fixed multiplier instead.
8+
/// </summary>
9+
[RegisterComponent, NetworkedComponent]
10+
public sealed partial class BorgModuleCrawlModifierComponent : Component
11+
{
12+
/// <summary>
13+
/// Speed multiplier applied while knocked down and a cyborg module is selected.
14+
/// </summary>
15+
[DataField]
16+
public float ActiveSpeedModifier = 0.5f;
17+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using Content.Shared.Hands.Components;
2+
using Content.Shared.Hands.EntitySystems;
3+
using Content.Shared.Silicons.Borgs.Components;
4+
using Content.Shared.Stunnable;
5+
6+
namespace Content.Shared._Starlight.Silicons.Borgs;
7+
8+
/// <summary>
9+
/// Handles crawling speed for cyborgs with <see cref="BorgModuleCrawlModifierComponent"/>.
10+
/// When any module is active, crawl speed is set to a fixed multiplier instead of scaling with free hands.
11+
/// </summary>
12+
public sealed class BorgModuleCrawlModifierSystem : EntitySystem
13+
{
14+
/// <inheritdoc/>
15+
public override void Initialize()
16+
{
17+
base.Initialize();
18+
SubscribeLocalEvent<BorgModuleCrawlModifierComponent, KnockedDownRefreshEvent>(OnKnockedDownRefresh,
19+
after: new[] { typeof(SharedHandsSystem), typeof(SharedStunSystem) });
20+
}
21+
22+
private void OnKnockedDownRefresh(Entity<BorgModuleCrawlModifierComponent> ent, ref KnockedDownRefreshEvent args)
23+
{
24+
if (!TryComp<BorgChassisComponent>(ent.Owner, out _))
25+
return;
26+
27+
if (!TryComp<HandsComponent>(ent.Owner, out var hands))
28+
return;
29+
30+
// Cyborgs have no hands without a module. We use hand count to detect active modules
31+
// instead of SelectedModule to avoid a timing issue where HandCountChanged fires
32+
// before SelectedModule is set during ProvideItems.
33+
if (hands.Hands.Count == 0)
34+
return;
35+
36+
// Overrides the normal hand-based movement speed penalty.
37+
// If a cyborg has a module out, apply ActiveSpeedModifier.
38+
float crawlerMod = 1f;
39+
if (TryComp<CrawlerComponent>(ent.Owner, out var crawler))
40+
crawlerMod = crawler.SpeedModifier;
41+
42+
args.SpeedModifier = crawlerMod * ent.Comp.ActiveSpeedModifier;
43+
}
44+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using Robust.Shared.GameStates;
2+
3+
namespace Content.Shared._Starlight.Stunnable;
4+
5+
/// <summary>
6+
/// Allows an entity to crawl even without hands.
7+
/// Add this component to any entity that should be able to crawl with zero hands,
8+
/// such as cyborgs when no module is selected.
9+
/// </summary>
10+
[RegisterComponent, NetworkedComponent]
11+
public sealed partial class CanCrawlWithoutHandsComponent : Component
12+
{
13+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using Content.Shared.Hands.Components;
2+
using Content.Shared.Hands.EntitySystems;
3+
using Content.Shared.Stunnable;
4+
5+
namespace Content.Shared._Starlight.Stunnable;
6+
7+
/// <summary>
8+
/// Handles <see cref="CanCrawlWithoutHandsComponent"/> - overrides the default
9+
/// hands-required crawl block when the entity has zero hands.
10+
/// Runs after <see cref="SharedHandsSystem"/> to replace the 0 speed with normal crawl speed.
11+
/// </summary>
12+
public sealed partial class CanCrawlWithoutHandsSystem : EntitySystem
13+
{
14+
[Dependency] private SharedHandsSystem _hands = default!;
15+
16+
/// <inheritdoc/>
17+
public override void Initialize()
18+
{
19+
base.Initialize();
20+
SubscribeLocalEvent<CanCrawlWithoutHandsComponent, KnockedDownRefreshEvent>(OnRefresh,
21+
after: new[] { typeof(SharedHandsSystem), typeof(SharedStunSystem) });
22+
}
23+
24+
private void OnRefresh(Entity<CanCrawlWithoutHandsComponent> ent, ref KnockedDownRefreshEvent args)
25+
{
26+
if (!TryComp<HandsComponent>(ent.Owner, out var hands))
27+
return;
28+
29+
var total = _hands.GetHandCount((ent.Owner, hands));
30+
if (total != 0)
31+
return;
32+
33+
if (TryComp<CrawlerComponent>(ent.Owner, out var crawler))
34+
args.SpeedModifier = crawler.SpeedModifier;
35+
else
36+
args.SpeedModifier = 1f;
37+
}
38+
}

Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@
9595
disableExplosionRecursion: true
9696
canBeStripped: false
9797
- type: HandlessDoAfter # Starlight
98+
- type: CanCrawlWithoutHands # Starlight: Allow crawling without hands
99+
- type: BorgModuleCrawlModifier # Starlight: Half crawl speed when module active
98100
- type: ComplexInteraction
99101
- type: IntrinsicRadioReceiver
100102
- type: IntrinsicRadioTransmitter

0 commit comments

Comments
 (0)