Files
wwdpublic/Content.Shared/Damage/Systems/SlowOnDamageSystem.cs
Skubman 410ee8d17e New Traits: Steadfast And Feeble (#1431)
# Description

Adds two new traits, Steadfast and Feeble that modify how affected a
character is by injury slows.

Steadfast (-4 points)
- 25% slow at 60 damage -> 17% slow at 70 damage
- 45% slow at 80 damage -> 30% slow at 90 damage

Feeble (4 points)
- 25% slow at 60 damage -> 30% slow at 45 damage
- 45% slow at 80 damage -> 54% slow at 65 damage

Also *half-reverts* the reduction of injury slows from a Delta-V PR by
ODJ (https://github.com/DeltaV-Station/Delta-v/pull/741) from 30%/50% to
20%/40%, now 25%/45% to incentivize taking Steadfast.

The injury slow resists for jackboot and combat boots has been nerfed
from 50% to 20% to account for Steadfast.

IPCs' injury slow at 60 damage has been decreased from 30% to 25% to be
more consistent with other species.

## Technical details

No trait with jackboots:
- 25% slow -> 20% slow
- 45% slow -> 36% slow

Steadfast with jackboots:
- 17% slow -> 13.6% slow
- 30% slow -> 24.5% slow

Feeble with jackboots:
- 30% slow -> 24% slow
- 54% slow -> 43.2% slow

Although Feeble with jackboots has lower slow values than the base
slows, the slow damage thresholds (-15) are still lower, making the
slows occur with less damage.

## Media

**Steadfast**

![image](https://github.com/user-attachments/assets/8b804040-7f0f-4a49-b0cf-1a83efd4c790)

**Feeble**

![image](https://github.com/user-attachments/assets/a1759f49-f68c-4cc4-991b-b6864e67e016)

**Jackboots**

![image](https://github.com/user-attachments/assets/67132fd0-5a97-43f1-a714-a9deae26f825)

# Changelog

<!--
You can add an author after the `🆑` to change the name that appears
in the changelog (ex: `🆑 Death`)
Leaving it blank will default to your GitHub display name
This includes all available types for the changelog
-->

🆑 Skubman
- add: Added two new traits: Steadfast and Feeble that decrease or
increase the effect of slows from injuries.
- tweak: Injury slows for most species has been slightly increased, but
this can be mitigated with the Steadfast trait.
- tweak: The jackboots' injury slow resistance has been decreased from
50% to 20%.
- tweak: Combat boots now add resistance to injury slows like jackboots.

---------

Signed-off-by: Skubman <ba.fallaria@gmail.com>
Co-authored-by: VMSolidus <evilexecutive@gmail.com>
(cherry picked from commit 68a11dbd5928b3ca3672198c91165755b05b37cc)
2025-01-14 01:27:15 +03:00

91 lines
3.8 KiB
C#

using Content.Shared.Clothing;
using Content.Shared.Damage.Components;
using Content.Shared.Examine;
using Content.Shared.FixedPoint;
using Content.Shared.Inventory;
using Content.Shared.Movement.Systems;
namespace Content.Shared.Damage
{
public sealed class SlowOnDamageSystem : EntitySystem
{
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifierSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SlowOnDamageComponent, DamageChangedEvent>(OnDamageChanged);
SubscribeLocalEvent<SlowOnDamageComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovespeed);
SubscribeLocalEvent<ClothingSlowOnDamageModifierComponent, InventoryRelayedEvent<ModifySlowOnDamageSpeedEvent>>(OnModifySpeed);
SubscribeLocalEvent<ClothingSlowOnDamageModifierComponent, ExaminedEvent>(OnExamined);
SubscribeLocalEvent<ClothingSlowOnDamageModifierComponent, ClothingGotEquippedEvent>(OnGotEquipped);
SubscribeLocalEvent<ClothingSlowOnDamageModifierComponent, ClothingGotUnequippedEvent>(OnGotUnequipped);
}
private void OnRefreshMovespeed(EntityUid uid, SlowOnDamageComponent component, RefreshMovementSpeedModifiersEvent args)
{
if (!EntityManager.TryGetComponent<DamageableComponent>(uid, out var damage))
return;
if (damage.TotalDamage == FixedPoint2.Zero)
return;
// Get closest threshold
FixedPoint2 closest = FixedPoint2.Zero;
var total = damage.TotalDamage;
foreach (var thres in component.SpeedModifierThresholds)
{
if (total >= thres.Key && thres.Key > closest)
closest = thres.Key;
}
if (closest != FixedPoint2.Zero)
{
var speed = component.SpeedModifierThresholds[closest];
var ev = new ModifySlowOnDamageSpeedEvent(speed);
RaiseLocalEvent(uid, ref ev);
args.ModifySpeed(ev.Speed, ev.Speed);
}
}
private void OnDamageChanged(EntityUid uid, SlowOnDamageComponent component, DamageChangedEvent args)
{
// We -could- only refresh if it crossed a threshold but that would kind of be a lot of duplicated
// code and this isn't a super hot path anyway since basically only humans have this
_movementSpeedModifierSystem.RefreshMovementSpeedModifiers(uid);
}
private void OnModifySpeed(Entity<ClothingSlowOnDamageModifierComponent> ent, ref InventoryRelayedEvent<ModifySlowOnDamageSpeedEvent> args)
{
// reduces the slowness modifier by the given coefficient
args.Args.Speed = 1 - (1 - args.Args.Speed) * ent.Comp.Modifier;
}
private void OnExamined(Entity<ClothingSlowOnDamageModifierComponent> ent, ref ExaminedEvent args)
{
var msg = Loc.GetString("slow-on-damage-modifier-examine", ("mod", Math.Round((1 - ent.Comp.Modifier) * 100)));
args.PushMarkup(msg);
}
private void OnGotEquipped(Entity<ClothingSlowOnDamageModifierComponent> ent, ref ClothingGotEquippedEvent args)
{
_movementSpeedModifierSystem.RefreshMovementSpeedModifiers(args.Wearer);
}
private void OnGotUnequipped(Entity<ClothingSlowOnDamageModifierComponent> ent, ref ClothingGotUnequippedEvent args)
{
_movementSpeedModifierSystem.RefreshMovementSpeedModifiers(args.Wearer);
}
}
[ByRefEvent]
public record struct ModifySlowOnDamageSpeedEvent(float Speed) : IInventoryRelayEvent
{
public SlotFlags TargetSlots => SlotFlags.WITHOUT_POCKET;
}
}