Damage movespeed (#5244)
This commit is contained in:
22
Content.Shared/Damage/Components/SlowOnDamageComponent.cs
Normal file
22
Content.Shared/Damage/Components/SlowOnDamageComponent.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System.Collections.Generic;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
namespace Content.Shared.Damage.Components
|
||||
{
|
||||
// TODO It'd be nice if this could be a destructible threshold, but on the other hand,
|
||||
// that doesn't really work with events at all, and
|
||||
[RegisterComponent, NetworkedComponent]
|
||||
public class SlowOnDamageComponent : Component
|
||||
{
|
||||
public override string Name => "SlowOnDamage";
|
||||
|
||||
/// <summary>
|
||||
/// Damage -> movespeed dictionary. This is -damage-, not -health-.
|
||||
/// </summary>
|
||||
[DataField("speedModifierThresholds", required: true)]
|
||||
public readonly Dictionary<FixedPoint2, float> SpeedModifierThresholds = default!;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Content.Shared.Damage.Prototypes;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Movement.EntitySystems;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.IoC;
|
||||
54
Content.Shared/Damage/Systems/SlowOnDamageSystem.cs
Normal file
54
Content.Shared/Damage/Systems/SlowOnDamageSystem.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using Content.Shared.Damage.Components;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Movement.EntitySystems;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Shared.Damage.Systems
|
||||
{
|
||||
public class SlowOnDamageSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly MovementSpeedModifierSystem _movementSpeedModifierSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<SlowOnDamageComponent, DamageChangedEvent>(OnDamageChanged);
|
||||
SubscribeLocalEvent<SlowOnDamageComponent, RefreshMovementSpeedModifiersEvent>(OnRefreshMovespeed);
|
||||
}
|
||||
|
||||
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 (FixedPoint2.Dist(thres.Key, total) < FixedPoint2.Dist(closest, total))
|
||||
closest = thres.Key;
|
||||
}
|
||||
|
||||
if (closest != FixedPoint2.Zero)
|
||||
{
|
||||
var speed = component.SpeedModifierThresholds[closest];
|
||||
args.ModifySpeed(speed, 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Content.Shared.ActionBlocker;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.FixedPoint
|
||||
@@ -210,6 +211,16 @@ namespace Content.Shared.FixedPoint
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
public static FixedPoint2 Abs(FixedPoint2 a)
|
||||
{
|
||||
return FixedPoint2.New(Math.Abs(a._value));
|
||||
}
|
||||
|
||||
public static FixedPoint2 Dist(FixedPoint2 a, FixedPoint2 b)
|
||||
{
|
||||
return FixedPoint2.Abs(a - b);
|
||||
}
|
||||
|
||||
public static FixedPoint2 Clamp(FixedPoint2 reagent, FixedPoint2 min, FixedPoint2 max)
|
||||
{
|
||||
if (min > max)
|
||||
|
||||
@@ -232,6 +232,12 @@
|
||||
damage: 400
|
||||
behaviors:
|
||||
- !type:GibBehavior { }
|
||||
- type: SlowOnDamage
|
||||
speedModifierThresholds:
|
||||
40: 0.8
|
||||
60: 0.6
|
||||
80: 0.4
|
||||
90: 0.2
|
||||
- type: HeatResistance
|
||||
- type: Appearance
|
||||
visuals:
|
||||
|
||||
Reference in New Issue
Block a user