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 System.Linq;
|
||||||
using Content.Shared.Damage.Prototypes;
|
using Content.Shared.Damage.Prototypes;
|
||||||
using Content.Shared.FixedPoint;
|
using Content.Shared.FixedPoint;
|
||||||
|
using Content.Shared.Movement.EntitySystems;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
using Robust.Shared.IoC;
|
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.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Content.Shared.ActionBlocker;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
|
|
||||||
namespace Content.Shared.FixedPoint
|
namespace Content.Shared.FixedPoint
|
||||||
@@ -210,6 +211,16 @@ namespace Content.Shared.FixedPoint
|
|||||||
return a > b ? a : b;
|
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)
|
public static FixedPoint2 Clamp(FixedPoint2 reagent, FixedPoint2 min, FixedPoint2 max)
|
||||||
{
|
{
|
||||||
if (min > max)
|
if (min > max)
|
||||||
|
|||||||
@@ -232,6 +232,12 @@
|
|||||||
damage: 400
|
damage: 400
|
||||||
behaviors:
|
behaviors:
|
||||||
- !type:GibBehavior { }
|
- !type:GibBehavior { }
|
||||||
|
- type: SlowOnDamage
|
||||||
|
speedModifierThresholds:
|
||||||
|
40: 0.8
|
||||||
|
60: 0.6
|
||||||
|
80: 0.4
|
||||||
|
90: 0.2
|
||||||
- type: HeatResistance
|
- type: HeatResistance
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
visuals:
|
visuals:
|
||||||
|
|||||||
Reference in New Issue
Block a user