Generalize ReagentUnit into FixedPoint2 and use it for damage calculations (#5151)

* Damage units

* sum ext method
This commit is contained in:
mirrorcult
2021-11-03 16:48:03 -07:00
committed by GitHub
parent 8165d8f38c
commit 3ab4a30a0f
100 changed files with 730 additions and 601 deletions

View File

@@ -1,4 +1,5 @@
using System;
using Content.Shared.FixedPoint;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.ViewVariables;
@@ -27,7 +28,7 @@ namespace Content.Shared.Chemistry.Reagent
[DataField("ingestion")]
public bool Ingestion { get; } = false;
public void React(ReactionMethod method, IEntity entity, ReagentPrototype reagent, ReagentUnit volume, Components.Solution? source)
public void React(ReactionMethod method, IEntity entity, ReagentPrototype reagent, FixedPoint2 volume, Components.Solution? source)
{
switch (method)
{
@@ -50,6 +51,6 @@ namespace Content.Shared.Chemistry.Reagent
React(entity, reagent, volume, source);
}
protected abstract void React(IEntity entity, ReagentPrototype reagent, ReagentUnit volume, Components.Solution? source);
protected abstract void React(IEntity entity, ReagentPrototype reagent, FixedPoint2 volume, Components.Solution? source);
}
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using Content.Shared.Botany;
using Content.Shared.Chemistry.Reaction;
using Content.Shared.FixedPoint;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Maths;
@@ -77,9 +78,9 @@ namespace Content.Shared.Chemistry.Reagent
return SubstanceColor;
}
public ReagentUnit ReactionTile(TileRef tile, ReagentUnit reactVolume)
public FixedPoint2 ReactionTile(TileRef tile, FixedPoint2 reactVolume)
{
var removed = ReagentUnit.Zero;
var removed = FixedPoint2.Zero;
if (tile.Tile.IsEmpty)
return removed;

View File

@@ -1,249 +0,0 @@
using System;
using System.Globalization;
using System.Linq;
using Robust.Shared.Serialization;
namespace Content.Shared.Chemistry.Reagent
{
/// <summary>
/// Represents a quantity of reagent, to a precision of 0.01.
/// To enforce this level of precision, floats are shifted by 2 decimal points, rounded, and converted to an int.
/// </summary>
[Serializable]
public struct ReagentUnit : ISelfSerialize, IComparable<ReagentUnit>, IEquatable<ReagentUnit>
{
private int _value;
private static readonly int Shift = 2;
public static ReagentUnit MaxValue { get; } = new(int.MaxValue);
public static ReagentUnit Epsilon { get; } = new(1);
public static ReagentUnit Zero { get; } = new(0);
private readonly double ShiftDown()
{
return _value / Math.Pow(10, Shift);
}
private ReagentUnit(int value)
{
_value = value;
}
public static ReagentUnit New(int value)
{
return new(value * (int) Math.Pow(10, Shift));
}
public static ReagentUnit New(float value)
{
return new(FromFloat(value));
}
private static int FromFloat(float value)
{
return (int) MathF.Round(value * MathF.Pow(10, Shift), MidpointRounding.AwayFromZero);
}
public static ReagentUnit New(double value)
{
return new((int) Math.Round(value * Math.Pow(10, Shift), MidpointRounding.AwayFromZero));
}
public static ReagentUnit New(string value)
{
return New(FloatFromString(value));
}
private static float FloatFromString(string value)
{
return float.Parse(value, CultureInfo.InvariantCulture);
}
public static ReagentUnit operator +(ReagentUnit a) => a;
public static ReagentUnit operator -(ReagentUnit a) => new(-a._value);
public static ReagentUnit operator +(ReagentUnit a, ReagentUnit b)
=> new(a._value + b._value);
public static ReagentUnit operator -(ReagentUnit a, ReagentUnit b)
=> a + -b;
public static ReagentUnit operator *(ReagentUnit a, ReagentUnit b)
{
var aD = a.ShiftDown();
var bD = b.ShiftDown();
return New(aD * bD);
}
public static ReagentUnit operator *(ReagentUnit a, float b)
{
var aD = (float) a.ShiftDown();
return New(aD * b);
}
public static ReagentUnit operator *(ReagentUnit a, double b)
{
var aD = a.ShiftDown();
return New(aD * b);
}
public static ReagentUnit operator *(ReagentUnit a, int b)
{
return new(a._value * b);
}
public static ReagentUnit operator /(ReagentUnit a, ReagentUnit b)
{
if (b._value == 0)
{
throw new DivideByZeroException();
}
var aD = a.ShiftDown();
var bD = b.ShiftDown();
return New(aD / bD);
}
public static bool operator <=(ReagentUnit a, int b)
{
return a <= New(b);
}
public static bool operator >=(ReagentUnit a, int b)
{
return a >= New(b);
}
public static bool operator <(ReagentUnit a, int b)
{
return a < New(b);
}
public static bool operator >(ReagentUnit a, int b)
{
return a > New(b);
}
public static bool operator ==(ReagentUnit a, int b)
{
return a == New(b);
}
public static bool operator !=(ReagentUnit a, int b)
{
return a != New(b);
}
public static bool operator ==(ReagentUnit a, ReagentUnit b)
{
return a.Equals(b);
}
public static bool operator !=(ReagentUnit a, ReagentUnit b)
{
return !a.Equals(b);
}
public static bool operator <=(ReagentUnit a, ReagentUnit b)
{
return a._value <= b._value;
}
public static bool operator >=(ReagentUnit a, ReagentUnit b)
{
return a._value >= b._value;
}
public static bool operator <(ReagentUnit a, ReagentUnit b)
{
return a._value < b._value;
}
public static bool operator >(ReagentUnit a, ReagentUnit b)
{
return a._value > b._value;
}
public readonly float Float()
{
return (float) ShiftDown();
}
public readonly double Double()
{
return ShiftDown();
}
public readonly int Int()
{
return (int) ShiftDown();
}
public static ReagentUnit Min(params ReagentUnit[] reagentUnits)
{
return reagentUnits.Min();
}
public static ReagentUnit Min(ReagentUnit a, ReagentUnit b)
{
return a < b ? a : b;
}
public static ReagentUnit Max(ReagentUnit a, ReagentUnit b)
{
return a > b ? a : b;
}
public static ReagentUnit Clamp(ReagentUnit reagent, ReagentUnit min, ReagentUnit max)
{
if (min > max)
{
throw new ArgumentException($"{nameof(min)} {min} cannot be larger than {nameof(max)} {max}");
}
return reagent < min ? min : reagent > max ? max : reagent;
}
public override readonly bool Equals(object? obj)
{
return obj is ReagentUnit unit &&
_value == unit._value;
}
public override readonly int GetHashCode()
{
// ReSharper disable once NonReadonlyMemberInGetHashCode
return HashCode.Combine(_value);
}
public void Deserialize(string value)
{
_value = FromFloat(FloatFromString(value));
}
public override readonly string ToString() => $"{ShiftDown().ToString(CultureInfo.InvariantCulture)}";
public readonly string Serialize()
{
return ToString();
}
public readonly bool Equals(ReagentUnit other)
{
return _value == other._value;
}
public readonly int CompareTo(ReagentUnit other)
{
if(other._value > _value)
{
return -1;
}
if(other._value < _value)
{
return 1;
}
return 0;
}
}
}