166 lines
3.8 KiB
C#
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)),
|
|
};
|
|
}
|
|
}
|