chore: convert movement regime kinds to enum
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
using SpaceGame.Api.Shared.Runtime;
|
||||||
|
|
||||||
namespace SpaceGame.Api.Definitions;
|
namespace SpaceGame.Api.Definitions;
|
||||||
|
|
||||||
@@ -196,6 +197,8 @@ public sealed class ModuleDefinition
|
|||||||
public string Description { get; set; } = string.Empty;
|
public string Description { get; set; } = string.Empty;
|
||||||
public required string Type { get; set; }
|
public required string Type { get; set; }
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
|
public ModuleType ModuleType { get; set; }
|
||||||
|
[JsonIgnore]
|
||||||
public string? Product { get; set; }
|
public string? Product { get; set; }
|
||||||
public List<string> Products { get; set; } = [];
|
public List<string> Products { get; set; } = [];
|
||||||
public string ProductionMode { get; set; } = "passive";
|
public string ProductionMode { get; set; } = "passive";
|
||||||
|
|||||||
@@ -94,12 +94,25 @@ public enum SpaceLayerKind
|
|||||||
LocalSpace,
|
LocalSpace,
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class MovementRegimeKinds
|
public enum MovementRegimeKind
|
||||||
{
|
{
|
||||||
public const string LocalFlight = "local-flight";
|
LocalFlight,
|
||||||
public const string Warp = "warp";
|
Warp,
|
||||||
public const string StargateTransit = "stargate-transit";
|
StargateTransit,
|
||||||
public const string FtlTransit = "ftl-transit";
|
FtlTransit,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ModuleType
|
||||||
|
{
|
||||||
|
BuildModule,
|
||||||
|
ConnectionModule,
|
||||||
|
DefenceModule,
|
||||||
|
DockArea,
|
||||||
|
Habitation,
|
||||||
|
Pier,
|
||||||
|
ProcessingModule,
|
||||||
|
Production,
|
||||||
|
Storage,
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class CommanderKind
|
public static class CommanderKind
|
||||||
@@ -182,6 +195,34 @@ public static class MarketOrderStateKinds
|
|||||||
|
|
||||||
public static class SimulationEnumMappings
|
public static class SimulationEnumMappings
|
||||||
{
|
{
|
||||||
|
public static string ToDataValue(this ModuleType moduleType) => moduleType switch
|
||||||
|
{
|
||||||
|
ModuleType.BuildModule => "buildmodule",
|
||||||
|
ModuleType.ConnectionModule => "connectionmodule",
|
||||||
|
ModuleType.DefenceModule => "defencemodule",
|
||||||
|
ModuleType.DockArea => "dockarea",
|
||||||
|
ModuleType.Habitation => "habitation",
|
||||||
|
ModuleType.Pier => "pier",
|
||||||
|
ModuleType.ProcessingModule => "processingmodule",
|
||||||
|
ModuleType.Production => "production",
|
||||||
|
ModuleType.Storage => "storage",
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(moduleType), moduleType, null),
|
||||||
|
};
|
||||||
|
|
||||||
|
public static ModuleType ToModuleType(this string value) => value.Trim() switch
|
||||||
|
{
|
||||||
|
"buildmodule" => ModuleType.BuildModule,
|
||||||
|
"connectionmodule" => ModuleType.ConnectionModule,
|
||||||
|
"defencemodule" => ModuleType.DefenceModule,
|
||||||
|
"dockarea" => ModuleType.DockArea,
|
||||||
|
"habitation" => ModuleType.Habitation,
|
||||||
|
"pier" => ModuleType.Pier,
|
||||||
|
"processingmodule" => ModuleType.ProcessingModule,
|
||||||
|
"production" => ModuleType.Production,
|
||||||
|
"storage" => ModuleType.Storage,
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(value), value, "Unsupported module type."),
|
||||||
|
};
|
||||||
|
|
||||||
public static string ToContractValue(this SpatialNodeKind kind) => kind switch
|
public static string ToContractValue(this SpatialNodeKind kind) => kind switch
|
||||||
{
|
{
|
||||||
SpatialNodeKind.Star => "star",
|
SpatialNodeKind.Star => "star",
|
||||||
@@ -283,4 +324,13 @@ public static class SimulationEnumMappings
|
|||||||
SpaceLayerKind.LocalSpace => "local-space",
|
SpaceLayerKind.LocalSpace => "local-space",
|
||||||
_ => throw new ArgumentOutOfRangeException(nameof(kind), kind, null),
|
_ => throw new ArgumentOutOfRangeException(nameof(kind), kind, null),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static string ToContractValue(this MovementRegimeKind kind) => kind switch
|
||||||
|
{
|
||||||
|
MovementRegimeKind.LocalFlight => "local-flight",
|
||||||
|
MovementRegimeKind.Warp => "warp",
|
||||||
|
MovementRegimeKind.StargateTransit => "stargate-transit",
|
||||||
|
MovementRegimeKind.FtlTransit => "ftl-transit",
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(kind), kind, null),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,11 @@ internal static class SimulationRuntimeSupport
|
|||||||
internal static int CountStationModules(StationRuntime station, string moduleId) =>
|
internal static int CountStationModules(StationRuntime station, string moduleId) =>
|
||||||
station.Modules.Count(module => string.Equals(module.ModuleId, moduleId, StringComparison.Ordinal));
|
station.Modules.Count(module => string.Equals(module.ModuleId, moduleId, StringComparison.Ordinal));
|
||||||
|
|
||||||
|
internal static int CountStationModules(SimulationWorld world, StationRuntime station, ModuleType moduleType) =>
|
||||||
|
station.Modules.Count(module =>
|
||||||
|
world.ModuleDefinitions.TryGetValue(module.ModuleId, out var definition)
|
||||||
|
&& definition.ModuleType == moduleType);
|
||||||
|
|
||||||
internal static void AddStationModule(SimulationWorld world, StationRuntime station, string moduleId)
|
internal static void AddStationModule(SimulationWorld world, StationRuntime station, string moduleId)
|
||||||
{
|
{
|
||||||
if (!world.ModuleDefinitions.TryGetValue(moduleId, out var definition))
|
if (!world.ModuleDefinitions.TryGetValue(moduleId, out var definition))
|
||||||
@@ -61,6 +66,14 @@ internal static class SimulationRuntimeSupport
|
|||||||
internal static int CountModules(IEnumerable<string> modules, string moduleId) =>
|
internal static int CountModules(IEnumerable<string> modules, string moduleId) =>
|
||||||
modules.Count(candidate => string.Equals(candidate, moduleId, StringComparison.Ordinal));
|
modules.Count(candidate => string.Equals(candidate, moduleId, StringComparison.Ordinal));
|
||||||
|
|
||||||
|
internal static int CountModules(
|
||||||
|
IEnumerable<string> modules,
|
||||||
|
IReadOnlyDictionary<string, ModuleDefinition> moduleDefinitions,
|
||||||
|
ModuleType moduleType) =>
|
||||||
|
modules.Count(moduleId =>
|
||||||
|
moduleDefinitions.TryGetValue(moduleId, out var definition)
|
||||||
|
&& definition.ModuleType == moduleType);
|
||||||
|
|
||||||
internal static float GetInventoryAmount(IReadOnlyDictionary<string, float> inventory, string itemId) =>
|
internal static float GetInventoryAmount(IReadOnlyDictionary<string, float> inventory, string itemId) =>
|
||||||
inventory.TryGetValue(itemId, out var amount) ? amount : 0f;
|
inventory.TryGetValue(itemId, out var amount) ? amount : 0f;
|
||||||
|
|
||||||
|
|||||||
@@ -1647,7 +1647,7 @@ internal sealed class ShipAiService
|
|||||||
{
|
{
|
||||||
var distance = ship.Position.DistanceTo(targetPosition);
|
var distance = ship.Position.DistanceTo(targetPosition);
|
||||||
ship.SpatialState.SpaceLayer = SpaceLayerKind.LocalSpace;
|
ship.SpatialState.SpaceLayer = SpaceLayerKind.LocalSpace;
|
||||||
ship.SpatialState.MovementRegime = MovementRegimeKinds.LocalFlight;
|
ship.SpatialState.MovementRegime = MovementRegimeKind.LocalFlight;
|
||||||
ship.SpatialState.Transit = null;
|
ship.SpatialState.Transit = null;
|
||||||
ship.SpatialState.DestinationNodeId = targetCelestial?.Id;
|
ship.SpatialState.DestinationNodeId = targetCelestial?.Id;
|
||||||
subTask.Progress = Math.Clamp(1f - (distance / MathF.Max(distance + GetLocalTravelSpeed(ship), 1f)), 0f, 1f);
|
subTask.Progress = Math.Clamp(1f - (distance / MathF.Max(distance + GetLocalTravelSpeed(ship), 1f)), 0f, 1f);
|
||||||
@@ -1678,11 +1678,11 @@ internal sealed class ShipAiService
|
|||||||
bool completeOnArrival)
|
bool completeOnArrival)
|
||||||
{
|
{
|
||||||
var transit = ship.SpatialState.Transit;
|
var transit = ship.SpatialState.Transit;
|
||||||
if (transit is null || transit.Regime != MovementRegimeKinds.Warp || transit.DestinationNodeId != targetCelestial.Id)
|
if (transit is null || transit.Regime != MovementRegimeKind.Warp || transit.DestinationNodeId != targetCelestial.Id)
|
||||||
{
|
{
|
||||||
transit = new ShipTransitRuntime
|
transit = new ShipTransitRuntime
|
||||||
{
|
{
|
||||||
Regime = MovementRegimeKinds.Warp,
|
Regime = MovementRegimeKind.Warp,
|
||||||
OriginNodeId = ship.SpatialState.CurrentCelestialId,
|
OriginNodeId = ship.SpatialState.CurrentCelestialId,
|
||||||
DestinationNodeId = targetCelestial.Id,
|
DestinationNodeId = targetCelestial.Id,
|
||||||
StartedAtUtc = world.GeneratedAtUtc,
|
StartedAtUtc = world.GeneratedAtUtc,
|
||||||
@@ -1692,7 +1692,7 @@ internal sealed class ShipAiService
|
|||||||
}
|
}
|
||||||
|
|
||||||
ship.SpatialState.SpaceLayer = SpaceLayerKind.SystemSpace;
|
ship.SpatialState.SpaceLayer = SpaceLayerKind.SystemSpace;
|
||||||
ship.SpatialState.MovementRegime = MovementRegimeKinds.Warp;
|
ship.SpatialState.MovementRegime = MovementRegimeKind.Warp;
|
||||||
ship.SpatialState.CurrentCelestialId = null;
|
ship.SpatialState.CurrentCelestialId = null;
|
||||||
ship.SpatialState.DestinationNodeId = targetCelestial.Id;
|
ship.SpatialState.DestinationNodeId = targetCelestial.Id;
|
||||||
|
|
||||||
@@ -1735,11 +1735,11 @@ internal sealed class ShipAiService
|
|||||||
{
|
{
|
||||||
var destinationNodeId = targetCelestial?.Id;
|
var destinationNodeId = targetCelestial?.Id;
|
||||||
var transit = ship.SpatialState.Transit;
|
var transit = ship.SpatialState.Transit;
|
||||||
if (transit is null || transit.Regime != MovementRegimeKinds.FtlTransit || transit.DestinationNodeId != destinationNodeId)
|
if (transit is null || transit.Regime != MovementRegimeKind.FtlTransit || transit.DestinationNodeId != destinationNodeId)
|
||||||
{
|
{
|
||||||
transit = new ShipTransitRuntime
|
transit = new ShipTransitRuntime
|
||||||
{
|
{
|
||||||
Regime = MovementRegimeKinds.FtlTransit,
|
Regime = MovementRegimeKind.FtlTransit,
|
||||||
OriginNodeId = ship.SpatialState.CurrentCelestialId,
|
OriginNodeId = ship.SpatialState.CurrentCelestialId,
|
||||||
DestinationNodeId = destinationNodeId,
|
DestinationNodeId = destinationNodeId,
|
||||||
StartedAtUtc = world.GeneratedAtUtc,
|
StartedAtUtc = world.GeneratedAtUtc,
|
||||||
@@ -1749,7 +1749,7 @@ internal sealed class ShipAiService
|
|||||||
}
|
}
|
||||||
|
|
||||||
ship.SpatialState.SpaceLayer = SpaceLayerKind.GalaxySpace;
|
ship.SpatialState.SpaceLayer = SpaceLayerKind.GalaxySpace;
|
||||||
ship.SpatialState.MovementRegime = MovementRegimeKinds.FtlTransit;
|
ship.SpatialState.MovementRegime = MovementRegimeKind.FtlTransit;
|
||||||
ship.SpatialState.CurrentCelestialId = null;
|
ship.SpatialState.CurrentCelestialId = null;
|
||||||
ship.SpatialState.DestinationNodeId = destinationNodeId;
|
ship.SpatialState.DestinationNodeId = destinationNodeId;
|
||||||
|
|
||||||
@@ -1780,7 +1780,7 @@ internal sealed class ShipAiService
|
|||||||
ship.SpatialState.CurrentSystemId = targetSystemId;
|
ship.SpatialState.CurrentSystemId = targetSystemId;
|
||||||
ship.SpatialState.Transit = null;
|
ship.SpatialState.Transit = null;
|
||||||
ship.SpatialState.SpaceLayer = SpaceLayerKind.LocalSpace;
|
ship.SpatialState.SpaceLayer = SpaceLayerKind.LocalSpace;
|
||||||
ship.SpatialState.MovementRegime = MovementRegimeKinds.LocalFlight;
|
ship.SpatialState.MovementRegime = MovementRegimeKind.LocalFlight;
|
||||||
ship.SpatialState.CurrentCelestialId = targetCelestial?.Id;
|
ship.SpatialState.CurrentCelestialId = targetCelestial?.Id;
|
||||||
ship.SpatialState.DestinationNodeId = targetCelestial?.Id;
|
ship.SpatialState.DestinationNodeId = targetCelestial?.Id;
|
||||||
ship.State = ShipState.Arriving;
|
ship.State = ShipState.Arriving;
|
||||||
@@ -1795,7 +1795,7 @@ internal sealed class ShipAiService
|
|||||||
ship.SpatialState.CurrentSystemId = targetSystemId;
|
ship.SpatialState.CurrentSystemId = targetSystemId;
|
||||||
ship.SpatialState.Transit = null;
|
ship.SpatialState.Transit = null;
|
||||||
ship.SpatialState.SpaceLayer = SpaceLayerKind.LocalSpace;
|
ship.SpatialState.SpaceLayer = SpaceLayerKind.LocalSpace;
|
||||||
ship.SpatialState.MovementRegime = MovementRegimeKinds.LocalFlight;
|
ship.SpatialState.MovementRegime = MovementRegimeKind.LocalFlight;
|
||||||
ship.SpatialState.CurrentCelestialId = targetCelestial?.Id;
|
ship.SpatialState.CurrentCelestialId = targetCelestial?.Id;
|
||||||
ship.SpatialState.DestinationNodeId = targetCelestial?.Id;
|
ship.SpatialState.DestinationNodeId = targetCelestial?.Id;
|
||||||
ship.State = ShipState.Arriving;
|
ship.State = ShipState.Arriving;
|
||||||
|
|||||||
@@ -580,9 +580,9 @@ internal sealed class SimulationProjectionService
|
|||||||
ship.PolicySetId ?? "none",
|
ship.PolicySetId ?? "none",
|
||||||
ship.SpatialState.SpaceLayer.ToContractValue(),
|
ship.SpatialState.SpaceLayer.ToContractValue(),
|
||||||
ship.SpatialState.CurrentCelestialId ?? "none",
|
ship.SpatialState.CurrentCelestialId ?? "none",
|
||||||
ship.SpatialState.MovementRegime,
|
ship.SpatialState.MovementRegime.ToContractValue(),
|
||||||
ship.SpatialState.DestinationNodeId ?? "none",
|
ship.SpatialState.DestinationNodeId ?? "none",
|
||||||
ship.SpatialState.Transit?.Regime ?? "none",
|
ship.SpatialState.Transit?.Regime.ToContractValue() ?? "none",
|
||||||
ship.SpatialState.Transit?.OriginNodeId ?? "none",
|
ship.SpatialState.Transit?.OriginNodeId ?? "none",
|
||||||
ship.SpatialState.Transit?.DestinationNodeId ?? "none",
|
ship.SpatialState.Transit?.DestinationNodeId ?? "none",
|
||||||
ship.SpatialState.Transit?.Progress.ToString("0.###") ?? "0",
|
ship.SpatialState.Transit?.Progress.ToString("0.###") ?? "0",
|
||||||
@@ -921,8 +921,8 @@ internal sealed class SimulationProjectionService
|
|||||||
{
|
{
|
||||||
return ship.SpatialState.MovementRegime switch
|
return ship.SpatialState.MovementRegime switch
|
||||||
{
|
{
|
||||||
MovementRegimeKinds.FtlTransit => (ship.State == ShipState.Ftl ? ship.Definition.FtlSpeed : 0f, "ly/s"),
|
MovementRegimeKind.FtlTransit => (ship.State == ShipState.Ftl ? ship.Definition.FtlSpeed : 0f, "ly/s"),
|
||||||
MovementRegimeKinds.Warp => (ship.State == ShipState.Warping ? ship.Definition.WarpSpeed : 0f, "AU/s"),
|
MovementRegimeKind.Warp => (ship.State == ShipState.Warping ? ship.Definition.WarpSpeed : 0f, "AU/s"),
|
||||||
_ => (MathF.Sqrt(MathF.Max(0f, ship.Velocity.LengthSquared())) * SimulationUnits.MetersPerKilometer, "m/s"),
|
_ => (MathF.Sqrt(MathF.Max(0f, ship.Velocity.LengthSquared())) * SimulationUnits.MetersPerKilometer, "m/s"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1877,10 +1877,10 @@ internal sealed class SimulationProjectionService
|
|||||||
state.CurrentCelestialId,
|
state.CurrentCelestialId,
|
||||||
state.LocalPosition is null ? null : ToDto(state.LocalPosition.Value),
|
state.LocalPosition is null ? null : ToDto(state.LocalPosition.Value),
|
||||||
state.SystemPosition is null ? null : ToDto(state.SystemPosition.Value),
|
state.SystemPosition is null ? null : ToDto(state.SystemPosition.Value),
|
||||||
state.MovementRegime,
|
state.MovementRegime.ToContractValue(),
|
||||||
state.DestinationNodeId,
|
state.DestinationNodeId,
|
||||||
state.Transit is null ? null : new ShipTransitSnapshot(
|
state.Transit is null ? null : new ShipTransitSnapshot(
|
||||||
state.Transit.Regime,
|
state.Transit.Regime.ToContractValue(),
|
||||||
state.Transit.OriginNodeId,
|
state.Transit.OriginNodeId,
|
||||||
state.Transit.DestinationNodeId,
|
state.Transit.DestinationNodeId,
|
||||||
state.Transit.StartedAtUtc,
|
state.Transit.StartedAtUtc,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using SpaceGame.Api.Shared.Runtime;
|
||||||
using static SpaceGame.Api.Shared.Runtime.SimulationRuntimeSupport;
|
using static SpaceGame.Api.Shared.Runtime.SimulationRuntimeSupport;
|
||||||
|
|
||||||
namespace SpaceGame.Api.Stations.Simulation;
|
namespace SpaceGame.Api.Stations.Simulation;
|
||||||
@@ -19,7 +20,7 @@ internal sealed class StationLifecycleService
|
|||||||
var factionPopulation = new Dictionary<string, float>(StringComparer.Ordinal);
|
var factionPopulation = new Dictionary<string, float>(StringComparer.Ordinal);
|
||||||
foreach (var station in world.Stations)
|
foreach (var station in world.Stations)
|
||||||
{
|
{
|
||||||
UpdateStationPopulation(station, deltaSeconds, events);
|
UpdateStationPopulation(world, station, deltaSeconds, events);
|
||||||
_stationSimulation.ReviewStationMarketOrders(world, station);
|
_stationSimulation.ReviewStationMarketOrders(world, station);
|
||||||
_stationSimulation.RunStationProduction(world, station, deltaSeconds, events);
|
_stationSimulation.RunStationProduction(world, station, deltaSeconds, events);
|
||||||
factionPopulation[station.FactionId] = GetInventoryAmount(factionPopulation, station.FactionId) + station.Population;
|
factionPopulation[station.FactionId] = GetInventoryAmount(factionPopulation, station.FactionId) + station.Population;
|
||||||
@@ -31,14 +32,14 @@ internal sealed class StationLifecycleService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateStationPopulation(StationRuntime station, float deltaSeconds, ICollection<SimulationEventRecord> events)
|
private void UpdateStationPopulation(SimulationWorld world, StationRuntime station, float deltaSeconds, ICollection<SimulationEventRecord> events)
|
||||||
{
|
{
|
||||||
station.WorkforceRequired = MathF.Max(12f, station.Modules.Count * 14f);
|
station.WorkforceRequired = MathF.Max(12f, station.Modules.Count * 14f);
|
||||||
|
|
||||||
var requiredWater = station.Population * WaterConsumptionPerWorkerPerSecond * deltaSeconds;
|
var requiredWater = station.Population * WaterConsumptionPerWorkerPerSecond * deltaSeconds;
|
||||||
var consumedWater = RemoveInventory(station.Inventory, "water", requiredWater);
|
var consumedWater = RemoveInventory(station.Inventory, "water", requiredWater);
|
||||||
var waterSatisfied = requiredWater <= 0.01f || consumedWater + 0.001f >= requiredWater;
|
var waterSatisfied = requiredWater <= 0.01f || consumedWater + 0.001f >= requiredWater;
|
||||||
var habitatModules = CountModules(station.InstalledModules, "module_arg_hab_m_01");
|
var habitatModules = CountModules(station.InstalledModules, world.ModuleDefinitions, ModuleType.Habitation);
|
||||||
station.PopulationCapacity = 40f + (habitatModules * 220f);
|
station.PopulationCapacity = 40f + (habitatModules * 220f);
|
||||||
|
|
||||||
if (waterSatisfied)
|
if (waterSatisfied)
|
||||||
@@ -101,7 +102,7 @@ internal sealed class StationLifecycleService
|
|||||||
CurrentCelestialId = station.CelestialId,
|
CurrentCelestialId = station.CelestialId,
|
||||||
LocalPosition = position,
|
LocalPosition = position,
|
||||||
SystemPosition = position,
|
SystemPosition = position,
|
||||||
MovementRegime = MovementRegimeKinds.LocalFlight,
|
MovementRegime = MovementRegimeKind.LocalFlight,
|
||||||
};
|
};
|
||||||
|
|
||||||
private static DefaultBehaviorRuntime CreateSpawnedShipBehavior(ShipDefinition definition, StationRuntime station)
|
private static DefaultBehaviorRuntime CreateSpawnedShipBehavior(ShipDefinition definition, StationRuntime station)
|
||||||
|
|||||||
@@ -55,14 +55,14 @@ public sealed class ShipSpatialStateRuntime
|
|||||||
public string? CurrentCelestialId { get; set; }
|
public string? CurrentCelestialId { get; set; }
|
||||||
public Vector3? LocalPosition { get; set; }
|
public Vector3? LocalPosition { get; set; }
|
||||||
public Vector3? SystemPosition { get; set; }
|
public Vector3? SystemPosition { get; set; }
|
||||||
public string MovementRegime { get; set; } = MovementRegimeKinds.LocalFlight;
|
public MovementRegimeKind MovementRegime { get; set; } = MovementRegimeKind.LocalFlight;
|
||||||
public string? DestinationNodeId { get; set; }
|
public string? DestinationNodeId { get; set; }
|
||||||
public ShipTransitRuntime? Transit { get; set; }
|
public ShipTransitRuntime? Transit { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class ShipTransitRuntime
|
public sealed class ShipTransitRuntime
|
||||||
{
|
{
|
||||||
public required string Regime { get; init; }
|
public required MovementRegimeKind Regime { get; init; }
|
||||||
public string? OriginNodeId { get; init; }
|
public string? OriginNodeId { get; init; }
|
||||||
public string? DestinationNodeId { get; init; }
|
public string? DestinationNodeId { get; init; }
|
||||||
public DateTimeOffset? StartedAtUtc { get; set; }
|
public DateTimeOffset? StartedAtUtc { get; set; }
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using SpaceGame.Api.Shared.Runtime;
|
||||||
using static SpaceGame.Api.Universe.Scenario.LoaderSupport;
|
using static SpaceGame.Api.Universe.Scenario.LoaderSupport;
|
||||||
|
|
||||||
namespace SpaceGame.Api.Universe.Scenario;
|
namespace SpaceGame.Api.Universe.Scenario;
|
||||||
@@ -271,6 +272,17 @@ internal sealed class DataCatalogLoader(string dataRoot)
|
|||||||
{
|
{
|
||||||
foreach (var module in modules)
|
foreach (var module in modules)
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
module.ModuleType = module.Type.ToModuleType();
|
||||||
|
}
|
||||||
|
catch (ArgumentOutOfRangeException exception)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Module '{module.Id}' has unsupported type '{module.Type}'.", exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.Type = module.ModuleType.ToDataValue();
|
||||||
|
|
||||||
if (module.Products.Count == 0 && !string.IsNullOrWhiteSpace(module.Product))
|
if (module.Products.Count == 0 && !string.IsNullOrWhiteSpace(module.Product))
|
||||||
{
|
{
|
||||||
module.Products = [module.Product];
|
module.Products = [module.Product];
|
||||||
@@ -278,7 +290,7 @@ internal sealed class DataCatalogLoader(string dataRoot)
|
|||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(module.ProductionMode))
|
if (string.IsNullOrWhiteSpace(module.ProductionMode))
|
||||||
{
|
{
|
||||||
module.ProductionMode = string.Equals(module.Type, "buildmodule", StringComparison.Ordinal)
|
module.ProductionMode = module.ModuleType == ModuleType.BuildModule
|
||||||
? "commanded"
|
? "commanded"
|
||||||
: "passive";
|
: "passive";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
|
||||||
|
using SpaceGame.Api.Shared.Runtime;
|
||||||
|
|
||||||
namespace SpaceGame.Api.Universe.Scenario;
|
namespace SpaceGame.Api.Universe.Scenario;
|
||||||
|
|
||||||
internal static class LoaderSupport
|
internal static class LoaderSupport
|
||||||
@@ -124,6 +126,14 @@ internal static class LoaderSupport
|
|||||||
internal static int CountModules(IEnumerable<string> modules, string moduleId) =>
|
internal static int CountModules(IEnumerable<string> modules, string moduleId) =>
|
||||||
modules.Count(candidate => string.Equals(candidate, moduleId, StringComparison.Ordinal));
|
modules.Count(candidate => string.Equals(candidate, moduleId, StringComparison.Ordinal));
|
||||||
|
|
||||||
|
internal static int CountModules(
|
||||||
|
IEnumerable<string> modules,
|
||||||
|
IReadOnlyDictionary<string, ModuleDefinition> moduleDefinitions,
|
||||||
|
ModuleType moduleType) =>
|
||||||
|
modules.Count(moduleId =>
|
||||||
|
moduleDefinitions.TryGetValue(moduleId, out var definition)
|
||||||
|
&& definition.ModuleType == moduleType);
|
||||||
|
|
||||||
internal static float ComputeWorkforceRatio(float population, float workforceRequired)
|
internal static float ComputeWorkforceRatio(float population, float workforceRequired)
|
||||||
{
|
{
|
||||||
if (workforceRequired <= 0.01f)
|
if (workforceRequired <= 0.01f)
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ internal sealed class SpatialBuilder
|
|||||||
CurrentCelestialId = nearestCelestial?.Id,
|
CurrentCelestialId = nearestCelestial?.Id,
|
||||||
LocalPosition = position,
|
LocalPosition = position,
|
||||||
SystemPosition = position,
|
SystemPosition = position,
|
||||||
MovementRegime = MovementRegimeKinds.LocalFlight,
|
MovementRegime = MovementRegimeKind.LocalFlight,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ internal sealed class WorldBuilder(
|
|||||||
catalog.ModuleDefinitions,
|
catalog.ModuleDefinitions,
|
||||||
catalog.ItemDefinitions);
|
catalog.ItemDefinitions);
|
||||||
|
|
||||||
seedingService.InitializeStationStockpiles(stations);
|
seedingService.InitializeStationStockpiles(stations, catalog.ModuleDefinitions);
|
||||||
var refinery = seedingService.SelectRefineryStation(stations, scenario);
|
var refinery = seedingService.SelectRefineryStation(stations, scenario);
|
||||||
var patrolRoutes = BuildPatrolRoutes(scenario, systemsById);
|
var patrolRoutes = BuildPatrolRoutes(scenario, systemsById);
|
||||||
var ships = CreateShips(scenario, systemsById, spatialLayout.Celestials, catalog.Balance, catalog.ShipDefinitions, patrolRoutes, stations, refinery);
|
var ships = CreateShips(scenario, systemsById, spatialLayout.Celestials, catalog.Balance, catalog.ShipDefinitions, patrolRoutes, stations, refinery);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using SpaceGame.Api.Shared.Runtime;
|
||||||
using static SpaceGame.Api.Universe.Scenario.LoaderSupport;
|
using static SpaceGame.Api.Universe.Scenario.LoaderSupport;
|
||||||
|
|
||||||
namespace SpaceGame.Api.Universe.Scenario;
|
namespace SpaceGame.Api.Universe.Scenario;
|
||||||
@@ -60,11 +61,13 @@ internal sealed class WorldSeedingService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void InitializeStationStockpiles(IReadOnlyCollection<StationRuntime> stations)
|
internal void InitializeStationStockpiles(
|
||||||
|
IReadOnlyCollection<StationRuntime> stations,
|
||||||
|
IReadOnlyDictionary<string, ModuleDefinition> moduleDefinitions)
|
||||||
{
|
{
|
||||||
foreach (var station in stations)
|
foreach (var station in stations)
|
||||||
{
|
{
|
||||||
InitializeStationPopulation(station);
|
InitializeStationPopulation(station, moduleDefinitions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -551,9 +554,11 @@ internal sealed class WorldSeedingService
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void InitializeStationPopulation(StationRuntime station)
|
private static void InitializeStationPopulation(
|
||||||
|
StationRuntime station,
|
||||||
|
IReadOnlyDictionary<string, ModuleDefinition> moduleDefinitions)
|
||||||
{
|
{
|
||||||
var habitatModules = CountModules(station.InstalledModules, "module_arg_hab_m_01");
|
var habitatModules = CountModules(station.InstalledModules, moduleDefinitions, ModuleType.Habitation);
|
||||||
station.PopulationCapacity = 40f + (habitatModules * 220f);
|
station.PopulationCapacity = 40f + (habitatModules * 220f);
|
||||||
station.WorkforceRequired = MathF.Max(12f, station.Modules.Count * 14f);
|
station.WorkforceRequired = MathF.Max(12f, station.Modules.Count * 14f);
|
||||||
station.Population = habitatModules > 0
|
station.Population = habitatModules > 0
|
||||||
|
|||||||
@@ -269,7 +269,7 @@ internal sealed class OrbitalStateUpdater
|
|||||||
}
|
}
|
||||||
|
|
||||||
ship.SpatialState.SpaceLayer = SpaceLayerKind.LocalSpace;
|
ship.SpatialState.SpaceLayer = SpaceLayerKind.LocalSpace;
|
||||||
ship.SpatialState.MovementRegime = MovementRegimeKinds.LocalFlight;
|
ship.SpatialState.MovementRegime = MovementRegimeKind.LocalFlight;
|
||||||
var nearestCelestial = world.Celestials
|
var nearestCelestial = world.Celestials
|
||||||
.Where(candidate => candidate.SystemId == ship.SystemId)
|
.Where(candidate => candidate.SystemId == ship.SystemId)
|
||||||
.OrderBy(candidate => candidate.Position.DistanceTo(ship.Position))
|
.OrderBy(candidate => candidate.Position.DistanceTo(ship.Position))
|
||||||
|
|||||||
Reference in New Issue
Block a user