Files
tbd-station-14/Content.Shared/_Offbrand/Wounds/Damages.cs
Janet Blackquill 300a78a791 Fix floating damages
2025-09-29 22:20:31 -04:00

132 lines
3.2 KiB
C#

using System.Linq;
using Content.Shared.Damage.Prototypes;
using Content.Shared.Damage;
using Content.Shared.FixedPoint;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
namespace Content.Shared._Offbrand.Wounds;
// like DamageSpecifier but with non-fucked network behaviour
[DataDefinition, Serializable, NetSerializable]
public sealed partial class Damages : IEquatable<Damages>, IRobustCloneable<Damages>
{
[DataField]
public Dictionary<ProtoId<DamageTypePrototype>, FixedPoint2> DamageDict;
public bool Empty => DamageDict.Count == 0;
public Damages()
{
DamageDict = new();
}
public Damages(DamageSpecifier origin) : this()
{
foreach (var (damage, value) in origin.DamageDict)
{
DamageDict[damage] = value;
}
}
public FixedPoint2 GetTotal()
{
var total = FixedPoint2.Zero;
foreach (var value in DamageDict.Values)
{
total += value;
}
return total;
}
public void TrimZeros()
{
foreach (var (key, value) in DamageDict)
{
if (value == 0)
{
DamageDict.Remove(key);
}
}
}
public DamageSpecifier ToSpecifier()
{
var specifier = new DamageSpecifier();
foreach (var (type, value) in DamageDict)
{
specifier.DamageDict[type] = value;
}
return specifier;
}
public Damages Heal(DamageSpecifier incoming)
{
var remainder = new Damages(incoming);
foreach (var (type, value) in remainder.DamageDict)
{
DebugTools.Assert(value <= 0);
if (!DamageDict.TryGetValue(type, out var existing))
continue;
var newValue = existing + value;
if (newValue <= 0)
{
remainder.DamageDict[type] = newValue;
newValue = 0;
}
else
{
remainder.DamageDict[type] = 0;
}
DamageDict[type] = newValue;
}
remainder.TrimZeros();
return remainder;
}
public static Damages operator +(Damages damages, DamageSpecifier specifier)
{
var newDamages = damages.Clone();
foreach (var entry in specifier.DamageDict)
{
if (!newDamages.DamageDict.TryAdd(entry.Key, entry.Value))
{
newDamages.DamageDict[entry.Key] += entry.Value;
}
}
return newDamages;
}
public Damages Clone()
{
return new() { DamageDict = new(this.DamageDict) };
}
public override string ToString()
{
return "Damages(" + string.Join("; ", DamageDict.Select(x => x.Key + ":" + x.Value)) + ")";
}
public bool Equals(Damages? other)
{
if (other == null || DamageDict.Count != other.DamageDict.Count)
return false;
foreach (var (key, value) in DamageDict)
{
if (!other.DamageDict.TryGetValue(key, out var otherValue) || value != otherValue)
return false;
}
return true;
}
}