Re-organize all projects (#4166)
This commit is contained in:
55
Content.Shared/Chemistry/Reagent/ReagentEntityReaction.cs
Normal file
55
Content.Shared/Chemistry/Reagent/ReagentEntityReaction.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Shared.Chemistry.Reagent
|
||||
{
|
||||
public enum ReactionMethod
|
||||
{
|
||||
Touch,
|
||||
Injection,
|
||||
Ingestion,
|
||||
}
|
||||
|
||||
[DataDefinition]
|
||||
public abstract class ReagentEntityReaction
|
||||
{
|
||||
[ViewVariables]
|
||||
[DataField("touch")]
|
||||
public bool Touch { get; } = false;
|
||||
|
||||
[ViewVariables]
|
||||
[DataField("injection")]
|
||||
public bool Injection { get; } = false;
|
||||
|
||||
[ViewVariables]
|
||||
[DataField("ingestion")]
|
||||
public bool Ingestion { get; } = false;
|
||||
|
||||
public void React(ReactionMethod method, IEntity entity, ReagentPrototype reagent, ReagentUnit volume, Solution.Solution? source)
|
||||
{
|
||||
switch (method)
|
||||
{
|
||||
case ReactionMethod.Touch:
|
||||
if (!Touch)
|
||||
return;
|
||||
break;
|
||||
case ReactionMethod.Injection:
|
||||
if(!Injection)
|
||||
return;
|
||||
break;
|
||||
case ReactionMethod.Ingestion:
|
||||
if(!Ingestion)
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(method), method, null);
|
||||
}
|
||||
|
||||
React(entity, reagent, volume, source);
|
||||
}
|
||||
|
||||
protected abstract void React(IEntity entity, ReagentPrototype reagent, ReagentUnit volume, Solution.Solution? source);
|
||||
}
|
||||
}
|
||||
118
Content.Shared/Chemistry/Reagent/ReagentPrototype.cs
Normal file
118
Content.Shared/Chemistry/Reagent/ReagentPrototype.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Shared.Botany;
|
||||
using Content.Shared.Chemistry.Metabolizable;
|
||||
using Content.Shared.Chemistry.Reaction;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Content.Shared.Chemistry.Reagent
|
||||
{
|
||||
[Prototype("reagent")]
|
||||
[DataDefinition]
|
||||
public class ReagentPrototype : IPrototype
|
||||
{
|
||||
[DataField("metabolism", serverOnly: true)]
|
||||
private readonly List<IMetabolizable> _metabolism = new() {new DefaultMetabolizable()};
|
||||
|
||||
[DataField("tileReactions", serverOnly: true)]
|
||||
private readonly List<ITileReaction> _tileReactions = new(0);
|
||||
|
||||
[DataField("plantMetabolism", serverOnly: true)]
|
||||
private readonly List<IPlantMetabolizable> _plantMetabolism = new(0);
|
||||
|
||||
[DataField("customPlantMetabolism")]
|
||||
private readonly float _customPlantMetabolism = 1f;
|
||||
|
||||
[ViewVariables]
|
||||
[DataField("id", required: true)]
|
||||
public string ID { get; } = default!;
|
||||
|
||||
[DataField("name")]
|
||||
public string Name { get; } = string.Empty;
|
||||
|
||||
[DataField("desc")]
|
||||
public string Description { get; } = string.Empty;
|
||||
|
||||
[DataField("physicalDesc")]
|
||||
public string PhysicalDescription { get; } = string.Empty;
|
||||
|
||||
[DataField("color")]
|
||||
public Color SubstanceColor { get; } = Color.White;
|
||||
|
||||
[DataField("toxin")]
|
||||
public bool Toxin { get; }
|
||||
|
||||
[DataField("boozePower")]
|
||||
public int BoozePower { get; }
|
||||
|
||||
[DataField("boilingPoint")]
|
||||
public float? BoilingPoint { get; }
|
||||
|
||||
[DataField("meltingPoint")]
|
||||
public float? MeltingPoint { get; }
|
||||
|
||||
[DataField("spritePath")]
|
||||
public string SpriteReplacementPath { get; } = string.Empty;
|
||||
|
||||
//List of metabolism effects this reagent has, should really only be used server-side.
|
||||
public IReadOnlyList<IMetabolizable> Metabolism => _metabolism;
|
||||
public IReadOnlyList<ITileReaction> TileReactions => _tileReactions;
|
||||
public IReadOnlyList<IPlantMetabolizable> PlantMetabolism => _plantMetabolism;
|
||||
|
||||
/// <summary>
|
||||
/// If the substance color is too dark we user a lighter version to make the text color readable when the user examines a solution.
|
||||
/// </summary>
|
||||
public Color GetSubstanceTextColor()
|
||||
{
|
||||
var highestValue = MathF.Max(SubstanceColor.R, MathF.Max(SubstanceColor.G, SubstanceColor.B));
|
||||
var difference = 0.5f - highestValue;
|
||||
|
||||
if (difference > 0f)
|
||||
{
|
||||
return new Color(SubstanceColor.R + difference,
|
||||
SubstanceColor.G + difference,
|
||||
SubstanceColor.B + difference);
|
||||
}
|
||||
|
||||
return SubstanceColor;
|
||||
}
|
||||
|
||||
public ReagentUnit ReactionTile(TileRef tile, ReagentUnit reactVolume)
|
||||
{
|
||||
var removed = ReagentUnit.Zero;
|
||||
|
||||
if (tile.Tile.IsEmpty)
|
||||
return removed;
|
||||
|
||||
foreach (var reaction in _tileReactions)
|
||||
{
|
||||
removed += reaction.TileReact(tile, this, reactVolume - removed);
|
||||
|
||||
if (removed > reactVolume)
|
||||
throw new Exception("Removed more than we have!");
|
||||
|
||||
if (removed == reactVolume)
|
||||
break;
|
||||
}
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
public void ReactionPlant(IEntity? plantHolder)
|
||||
{
|
||||
if (plantHolder == null || plantHolder.Deleted)
|
||||
return;
|
||||
|
||||
foreach (var plantMetabolizable in _plantMetabolism)
|
||||
{
|
||||
plantMetabolizable.Metabolize(plantHolder, _customPlantMetabolism);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
250
Content.Shared/Chemistry/Reagent/ReagentUnit.cs
Normal file
250
Content.Shared/Chemistry/Reagent/ReagentUnit.cs
Normal file
@@ -0,0 +1,250 @@
|
||||
#nullable enable
|
||||
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.ShiftDown() <= b;
|
||||
}
|
||||
|
||||
public static bool operator >=(ReagentUnit a, int b)
|
||||
{
|
||||
return a.ShiftDown() >= b;
|
||||
}
|
||||
|
||||
public static bool operator <(ReagentUnit a, int b)
|
||||
{
|
||||
return a.ShiftDown() < b;
|
||||
}
|
||||
|
||||
public static bool operator >(ReagentUnit a, int b)
|
||||
{
|
||||
return a.ShiftDown() > b;
|
||||
}
|
||||
|
||||
public static bool operator ==(ReagentUnit a, int b)
|
||||
{
|
||||
return a.Int() == b;
|
||||
}
|
||||
|
||||
public static bool operator !=(ReagentUnit a, int b)
|
||||
{
|
||||
return a.Int() != 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user