TemperatureScaling.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // SPDX-FileCopyrightText: 2025 Aiden <28298836+Aidenkrz@users.noreply.github.com>
  2. // SPDX-FileCopyrightText: 2025 Aidenkrz <aiden@djkraz.com>
  3. // SPDX-FileCopyrightText: 2025 Solstice <solsticeofthewinter@gmail.com>
  4. //
  5. // SPDX-License-Identifier: AGPL-3.0-or-later
  6. using Robust.Shared.Serialization;
  7. using Robust.Shared.GameObjects;
  8. using Content.Shared.FixedPoint;
  9. namespace Content.Shared._Shitmed.EntityEffects.Effects;
  10. /// <summary>
  11. /// Scales the efficiency of an effect based on the temperature of the entity.
  12. /// <param name="Min">The minimum temperature to scale the effect.</param>
  13. /// <param name="Max">The maximum temperature to scale the effect.</param>
  14. /// <param name="Scale">The scale to use for the efficiency.</param>
  15. /// </summary>
  16. [DataRecord, Serializable]
  17. public record struct TemperatureScaling(FixedPoint2 Min, FixedPoint2 Max, FixedPoint2 Scale)
  18. {
  19. public static implicit operator (FixedPoint2, FixedPoint2, FixedPoint2)(TemperatureScaling p) => (p.Min, p.Max, p.Scale);
  20. public static implicit operator TemperatureScaling((FixedPoint2, FixedPoint2, FixedPoint2) p) => new(p.Item1, p.Item2, p.Item3);
  21. // <summary>
  22. // Calculates the efficiency multiplier based on the given temperature.
  23. // </summary>
  24. // <param name="temperature">The temperature to calculate efficiency for.</param>
  25. // <param name="scale">The scale factor to apply to the efficiency calculation.</param>
  26. // <param name="invert"> If true, efficiency increases with temperature. If false, efficiency decreases with temperature.</param>
  27. // <returns>The calculated efficiency multiplier.</returns>
  28. public FixedPoint2 GetEfficiencyMultiplier(FixedPoint2 temperature, FixedPoint2 scale, bool invert = false)
  29. {
  30. if (Min > Max) // If the minimum is greater than the max, swap them to prevent issues.
  31. (Min, Max) = (Max, Min);
  32. if (Min == Max)
  33. return FixedPoint2.New(1); // If the min is equal to the max, return one or full efficiency since the range is meaningless.
  34. // Clamp the temperature within a given range.
  35. temperature = FixedPoint2.Clamp(temperature, Min, Max);
  36. // Calculate the distance from the minimum.
  37. var distance = FixedPoint2.Abs(temperature - Min);
  38. // Calculate the full possible temperature range between min and max.
  39. var totalRange = Max - Min;
  40. // Calculate scaled distance
  41. var scaledDistance = distance / totalRange;
  42. // Calculate final efficiency based on the inversion flag:
  43. // If inverted, efficiency increases with temperature (1 + scaled distance)
  44. // If not inverted, efficiency decreases with temperature (1 - scaled distance)
  45. // Then apply the scale factor to the result
  46. return invert
  47. ? FixedPoint2.New(1) + (scaledDistance * scale)
  48. : (FixedPoint2.New(1) - scaledDistance) * scale;
  49. }
  50. }