refactor: replace SpaceLayerKinds with strongly-typed SpaceLayerKind enum

Replaces string-based `SpaceLayerKinds` constants with a strongly-typed `SpaceLayerKind` enum. Updates backend services, runtime models, and projection logic to use the new enum. Adds `ToContractValue` method for compatibility with existing contracts.
This commit is contained in:
2026-03-24 03:03:13 -04:00
parent 766fef1c8f
commit 85a055ec91
7 changed files with 43 additions and 34 deletions

View File

@@ -86,12 +86,12 @@ public enum ShipState
Fleeing, Fleeing,
} }
public static class SpaceLayerKinds public enum SpaceLayerKind
{ {
public const string UniverseSpace = "universe-space"; UniverseSpace,
public const string GalaxySpace = "galaxy-space"; GalaxySpace,
public const string SystemSpace = "system-space"; SystemSpace,
public const string LocalSpace = "local-space"; LocalSpace,
} }
public static class MovementRegimeKinds public static class MovementRegimeKinds
@@ -274,4 +274,13 @@ public static class SimulationEnumMappings
ShipState.Fleeing => "fleeing", ShipState.Fleeing => "fleeing",
_ => throw new ArgumentOutOfRangeException(nameof(state), state, null), _ => throw new ArgumentOutOfRangeException(nameof(state), state, null),
}; };
public static string ToContractValue(this SpaceLayerKind kind) => kind switch
{
SpaceLayerKind.UniverseSpace => "universe-space",
SpaceLayerKind.GalaxySpace => "galaxy-space",
SpaceLayerKind.SystemSpace => "system-space",
SpaceLayerKind.LocalSpace => "local-space",
_ => throw new ArgumentOutOfRangeException(nameof(kind), kind, null),
};
} }

View File

@@ -1646,7 +1646,7 @@ internal sealed class ShipAiService
bool completeOnArrival) bool completeOnArrival)
{ {
var distance = ship.Position.DistanceTo(targetPosition); var distance = ship.Position.DistanceTo(targetPosition);
ship.SpatialState.SpaceLayer = SpaceLayerKinds.LocalSpace; ship.SpatialState.SpaceLayer = SpaceLayerKind.LocalSpace;
ship.SpatialState.MovementRegime = MovementRegimeKinds.LocalFlight; ship.SpatialState.MovementRegime = MovementRegimeKinds.LocalFlight;
ship.SpatialState.Transit = null; ship.SpatialState.Transit = null;
ship.SpatialState.DestinationNodeId = targetCelestial?.Id; ship.SpatialState.DestinationNodeId = targetCelestial?.Id;
@@ -1691,7 +1691,7 @@ internal sealed class ShipAiService
subTask.ElapsedSeconds = 0f; subTask.ElapsedSeconds = 0f;
} }
ship.SpatialState.SpaceLayer = SpaceLayerKinds.SystemSpace; ship.SpatialState.SpaceLayer = SpaceLayerKind.SystemSpace;
ship.SpatialState.MovementRegime = MovementRegimeKinds.Warp; ship.SpatialState.MovementRegime = MovementRegimeKinds.Warp;
ship.SpatialState.CurrentCelestialId = null; ship.SpatialState.CurrentCelestialId = null;
ship.SpatialState.DestinationNodeId = targetCelestial.Id; ship.SpatialState.DestinationNodeId = targetCelestial.Id;
@@ -1748,7 +1748,7 @@ internal sealed class ShipAiService
subTask.ElapsedSeconds = 0f; subTask.ElapsedSeconds = 0f;
} }
ship.SpatialState.SpaceLayer = SpaceLayerKinds.GalaxySpace; ship.SpatialState.SpaceLayer = SpaceLayerKind.GalaxySpace;
ship.SpatialState.MovementRegime = MovementRegimeKinds.FtlTransit; ship.SpatialState.MovementRegime = MovementRegimeKinds.FtlTransit;
ship.SpatialState.CurrentCelestialId = null; ship.SpatialState.CurrentCelestialId = null;
ship.SpatialState.DestinationNodeId = destinationNodeId; ship.SpatialState.DestinationNodeId = destinationNodeId;
@@ -1779,7 +1779,7 @@ internal sealed class ShipAiService
ship.SystemId = targetSystemId; ship.SystemId = targetSystemId;
ship.SpatialState.CurrentSystemId = targetSystemId; ship.SpatialState.CurrentSystemId = targetSystemId;
ship.SpatialState.Transit = null; ship.SpatialState.Transit = null;
ship.SpatialState.SpaceLayer = SpaceLayerKinds.LocalSpace; ship.SpatialState.SpaceLayer = SpaceLayerKind.LocalSpace;
ship.SpatialState.MovementRegime = MovementRegimeKinds.LocalFlight; ship.SpatialState.MovementRegime = MovementRegimeKinds.LocalFlight;
ship.SpatialState.CurrentCelestialId = targetCelestial?.Id; ship.SpatialState.CurrentCelestialId = targetCelestial?.Id;
ship.SpatialState.DestinationNodeId = targetCelestial?.Id; ship.SpatialState.DestinationNodeId = targetCelestial?.Id;
@@ -1794,7 +1794,7 @@ internal sealed class ShipAiService
ship.SystemId = targetSystemId; ship.SystemId = targetSystemId;
ship.SpatialState.CurrentSystemId = targetSystemId; ship.SpatialState.CurrentSystemId = targetSystemId;
ship.SpatialState.Transit = null; ship.SpatialState.Transit = null;
ship.SpatialState.SpaceLayer = SpaceLayerKinds.LocalSpace; ship.SpatialState.SpaceLayer = SpaceLayerKind.LocalSpace;
ship.SpatialState.MovementRegime = MovementRegimeKinds.LocalFlight; ship.SpatialState.MovementRegime = MovementRegimeKinds.LocalFlight;
ship.SpatialState.CurrentCelestialId = targetCelestial?.Id; ship.SpatialState.CurrentCelestialId = targetCelestial?.Id;
ship.SpatialState.DestinationNodeId = targetCelestial?.Id; ship.SpatialState.DestinationNodeId = targetCelestial?.Id;
@@ -2095,27 +2095,27 @@ internal sealed class ShipAiService
var source = stationsById.Values var source = stationsById.Values
.Where(station => .Where(station =>
{ {
if (station.Id == destination.Id || GetInventoryAmount(station.Inventory, order.ItemId) <= GetStationReserveFloor(world, station, order.ItemId) + 1f) if (station.Id == destination.Id || GetInventoryAmount(station.Inventory, order.ItemId) <= GetStationReserveFloor(world, station, order.ItemId) + 1f)
{ {
return false; return false;
} }
if (!TryCheckSystemAllowed(world, policy, ship.FactionId, station.SystemId, "trade", out var sourceDeniedReason)) if (!TryCheckSystemAllowed(world, policy, ship.FactionId, station.SystemId, "trade", out var sourceDeniedReason))
{ {
deniedReason ??= sourceDeniedReason; deniedReason ??= sourceDeniedReason;
return false; return false;
} }
if (!IsWithinSystemRange(world, originSystemId, station.SystemId, rangeBudget)) if (!IsWithinSystemRange(world, originSystemId, station.SystemId, rangeBudget))
{ {
return false; return false;
} }
return !requireKnownStations return !requireKnownStations
|| ship.KnownStationIds.Count == 0 || ship.KnownStationIds.Count == 0
|| ship.KnownStationIds.Contains(station.Id) || ship.KnownStationIds.Contains(station.Id)
|| (homeStation is not null && string.Equals(station.Id, homeStation.Id, StringComparison.Ordinal)); || (homeStation is not null && string.Equals(station.Id, homeStation.Id, StringComparison.Ordinal));
}) })
.OrderByDescending(station => GetInventoryAmount(station.Inventory, order.ItemId) - GetStationReserveFloor(world, station, order.ItemId)) .OrderByDescending(station => GetInventoryAmount(station.Inventory, order.ItemId) - GetStationReserveFloor(world, station, order.ItemId))
.ThenByDescending(station => homeStation is not null && station.Id == homeStation.Id ? 1 : 0) .ThenByDescending(station => homeStation is not null && station.Id == homeStation.Id ? 1 : 0)
.ThenBy(station => station.Id, StringComparer.Ordinal) .ThenBy(station => station.Id, StringComparer.Ordinal)

View File

@@ -578,7 +578,7 @@ internal sealed class SimulationProjectionService
ship.DockedStationId ?? "none", ship.DockedStationId ?? "none",
ship.CommanderId ?? "none", ship.CommanderId ?? "none",
ship.PolicySetId ?? "none", ship.PolicySetId ?? "none",
ship.SpatialState.SpaceLayer, ship.SpatialState.SpaceLayer.ToContractValue(),
ship.SpatialState.CurrentCelestialId ?? "none", ship.SpatialState.CurrentCelestialId ?? "none",
ship.SpatialState.MovementRegime, ship.SpatialState.MovementRegime,
ship.SpatialState.DestinationNodeId ?? "none", ship.SpatialState.DestinationNodeId ?? "none",
@@ -1872,7 +1872,7 @@ internal sealed class SimulationProjectionService
} }
private static ShipSpatialStateSnapshot ToShipSpatialStateSnapshot(ShipSpatialStateRuntime state) => new( private static ShipSpatialStateSnapshot ToShipSpatialStateSnapshot(ShipSpatialStateRuntime state) => new(
state.SpaceLayer, state.SpaceLayer.ToContractValue(),
state.CurrentSystemId, state.CurrentSystemId,
state.CurrentCelestialId, state.CurrentCelestialId,
state.LocalPosition is null ? null : ToDto(state.LocalPosition.Value), state.LocalPosition is null ? null : ToDto(state.LocalPosition.Value),

View File

@@ -97,7 +97,7 @@ internal sealed class StationLifecycleService
private static ShipSpatialStateRuntime CreateSpawnedShipSpatialState(StationRuntime station, Vector3 position) => new() private static ShipSpatialStateRuntime CreateSpawnedShipSpatialState(StationRuntime station, Vector3 position) => new()
{ {
CurrentSystemId = station.SystemId, CurrentSystemId = station.SystemId,
SpaceLayer = SpaceLayerKinds.LocalSpace, SpaceLayer = SpaceLayerKind.LocalSpace,
CurrentCelestialId = station.CelestialId, CurrentCelestialId = station.CelestialId,
LocalPosition = position, LocalPosition = position,
SystemPosition = position, SystemPosition = position,

View File

@@ -50,7 +50,7 @@ public sealed class WreckRuntime
public sealed class ShipSpatialStateRuntime public sealed class ShipSpatialStateRuntime
{ {
public string SpaceLayer { get; set; } = SpaceLayerKinds.LocalSpace; public SpaceLayerKind SpaceLayer { get; set; } = SpaceLayerKind.LocalSpace;
public required string CurrentSystemId { get; set; } public required string CurrentSystemId { get; set; }
public string? CurrentCelestialId { get; set; } public string? CurrentCelestialId { get; set; }
public Vector3? LocalPosition { get; set; } public Vector3? LocalPosition { get; set; }

View File

@@ -296,7 +296,7 @@ internal sealed class SpatialBuilder
return new ShipSpatialStateRuntime return new ShipSpatialStateRuntime
{ {
CurrentSystemId = systemId, CurrentSystemId = systemId,
SpaceLayer = SpaceLayerKinds.LocalSpace, SpaceLayer = SpaceLayerKind.LocalSpace,
CurrentCelestialId = nearestCelestial?.Id, CurrentCelestialId = nearestCelestial?.Id,
LocalPosition = position, LocalPosition = position,
SystemPosition = position, SystemPosition = position,

View File

@@ -268,7 +268,7 @@ internal sealed class OrbitalStateUpdater
continue; continue;
} }
ship.SpatialState.SpaceLayer = SpaceLayerKinds.LocalSpace; ship.SpatialState.SpaceLayer = SpaceLayerKind.LocalSpace;
ship.SpatialState.MovementRegime = MovementRegimeKinds.LocalFlight; ship.SpatialState.MovementRegime = MovementRegimeKinds.LocalFlight;
var nearestCelestial = world.Celestials var nearestCelestial = world.Celestials
.Where(candidate => candidate.SystemId == ship.SystemId) .Where(candidate => candidate.SystemId == ship.SystemId)