Files
space-game/apps/backend/Universe/Simulation/BalanceService.cs

166 lines
3.8 KiB
C#

using Microsoft.Extensions.Options;
namespace SpaceGame.Api.Universe.Simulation;
public sealed class BalanceService : IBalanceService
{
private readonly Lock _sync = new();
private BalanceOptions _current;
public BalanceService(IOptions<BalanceOptions> defaults)
{
_current = Sanitize(defaults.Value);
}
public float SimulationSpeedMultiplier
{
get
{
lock (_sync)
{
return _current.SimulationSpeedMultiplier;
}
}
}
public float YPlane
{
get
{
lock (_sync)
{
return _current.YPlane;
}
}
}
public float ArrivalThreshold
{
get
{
lock (_sync)
{
return _current.ArrivalThreshold;
}
}
}
public float MiningRate
{
get
{
lock (_sync)
{
return _current.MiningRate;
}
}
}
public float MiningCycleSeconds
{
get
{
lock (_sync)
{
return _current.MiningCycleSeconds;
}
}
}
public float TransferRate
{
get
{
lock (_sync)
{
return _current.TransferRate;
}
}
}
public float DockingDuration
{
get
{
lock (_sync)
{
return _current.DockingDuration;
}
}
}
public float UndockingDuration
{
get
{
lock (_sync)
{
return _current.UndockingDuration;
}
}
}
public float UndockDistance
{
get
{
lock (_sync)
{
return _current.UndockDistance;
}
}
}
public BalanceOptions GetCurrent()
{
lock (_sync)
{
return Clone(_current);
}
}
public BalanceOptions Update(BalanceOptions candidate)
{
lock (_sync)
{
_current = Sanitize(candidate);
return Clone(_current);
}
}
private static BalanceOptions Clone(BalanceOptions value)
{
return new BalanceOptions
{
SimulationSpeedMultiplier = value.SimulationSpeedMultiplier,
YPlane = value.YPlane,
ArrivalThreshold = value.ArrivalThreshold,
MiningRate = value.MiningRate,
MiningCycleSeconds = value.MiningCycleSeconds,
TransferRate = value.TransferRate,
DockingDuration = value.DockingDuration,
UndockingDuration = value.UndockingDuration,
UndockDistance = value.UndockDistance,
};
}
private static BalanceOptions Sanitize(BalanceOptions candidate)
{
static float finiteOr(float value, float fallback) =>
float.IsFinite(value) ? value : fallback;
return new BalanceOptions
{
SimulationSpeedMultiplier = MathF.Max(0.01f, finiteOr(candidate.SimulationSpeedMultiplier, 1f)),
YPlane = MathF.Max(0f, finiteOr(candidate.YPlane, 0f)),
ArrivalThreshold = MathF.Max(0.1f, finiteOr(candidate.ArrivalThreshold, 16f)),
MiningRate = MathF.Max(0f, finiteOr(candidate.MiningRate, 10f)),
MiningCycleSeconds = MathF.Max(0.1f, finiteOr(candidate.MiningCycleSeconds, 10f)),
TransferRate = MathF.Max(0f, finiteOr(candidate.TransferRate, 56f)),
DockingDuration = MathF.Max(0.1f, finiteOr(candidate.DockingDuration, 1.2f)),
UndockingDuration = MathF.Max(0.1f, finiteOr(candidate.UndockingDuration, 1.2f)),
UndockDistance = MathF.Max(0f, finiteOr(candidate.UndockDistance, 42f)),
};
}
}