Damage movespeed (#5244)

This commit is contained in:
mirrorcult
2021-11-10 03:06:27 -07:00
committed by GitHub
parent c7f802c0a9
commit 5ba9529414
6 changed files with 94 additions and 0 deletions

View 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!;
}
}

View File

@@ -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;

View 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);
}
}
}

View File

@@ -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)

View File

@@ -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: