459 lines
17 KiB
C#
459 lines
17 KiB
C#
using SpaceGame.Simulation.Api.Data;
|
|
|
|
namespace SpaceGame.Simulation.Api.Simulation;
|
|
|
|
public sealed class SimulationWorld
|
|
{
|
|
public required string Label { get; init; }
|
|
public required int Seed { get; init; }
|
|
public required BalanceDefinition Balance { get; init; }
|
|
public required List<SystemRuntime> Systems { get; init; }
|
|
public required List<ResourceNodeRuntime> Nodes { get; init; }
|
|
public required List<NodeRuntime> SpatialNodes { get; init; }
|
|
public required List<LocalBubbleRuntime> LocalBubbles { get; init; }
|
|
public required List<StationRuntime> Stations { get; init; }
|
|
public required List<ShipRuntime> Ships { get; init; }
|
|
public required List<FactionRuntime> Factions { get; init; }
|
|
public required List<CommanderRuntime> Commanders { get; init; }
|
|
public required List<ClaimRuntime> Claims { get; init; }
|
|
public required List<ConstructionSiteRuntime> ConstructionSites { get; init; }
|
|
public required List<MarketOrderRuntime> MarketOrders { get; init; }
|
|
public required List<PolicySetRuntime> Policies { get; init; }
|
|
public required Dictionary<string, ShipDefinition> ShipDefinitions { get; init; }
|
|
public required Dictionary<string, ItemDefinition> ItemDefinitions { get; init; }
|
|
public required Dictionary<string, ModuleRecipeDefinition> ModuleRecipes { get; init; }
|
|
public required Dictionary<string, RecipeDefinition> Recipes { get; init; }
|
|
public int TickIntervalMs { get; init; } = 200;
|
|
public DateTimeOffset GeneratedAtUtc { get; set; }
|
|
}
|
|
|
|
public sealed class SystemRuntime
|
|
{
|
|
public required SolarSystemDefinition Definition { get; init; }
|
|
public required Vector3 Position { get; init; }
|
|
}
|
|
|
|
public sealed class ResourceNodeRuntime
|
|
{
|
|
public required string Id { get; init; }
|
|
public required string SystemId { get; init; }
|
|
public required Vector3 Position { get; init; }
|
|
public required string SourceKind { get; init; }
|
|
public required string ItemId { get; init; }
|
|
public float OreRemaining { get; set; }
|
|
public float MaxOre { get; init; }
|
|
public string LastDeltaSignature { get; set; } = string.Empty;
|
|
}
|
|
|
|
public sealed class NodeRuntime
|
|
{
|
|
public required string Id { get; init; }
|
|
public required string SystemId { get; init; }
|
|
public required string Kind { get; init; }
|
|
public required Vector3 Position { get; set; }
|
|
public required string BubbleId { get; init; }
|
|
public string? ParentNodeId { get; set; }
|
|
public string? OccupyingStructureId { get; set; }
|
|
public string? OrbitReferenceId { get; set; }
|
|
public string LastDeltaSignature { get; set; } = string.Empty;
|
|
}
|
|
|
|
public sealed class LocalBubbleRuntime
|
|
{
|
|
public required string Id { get; init; }
|
|
public required string NodeId { get; init; }
|
|
public required string SystemId { get; init; }
|
|
public float Radius { get; init; }
|
|
public HashSet<string> OccupantShipIds { get; } = new(StringComparer.Ordinal);
|
|
public HashSet<string> OccupantStationIds { get; } = new(StringComparer.Ordinal);
|
|
public HashSet<string> OccupantClaimIds { get; } = new(StringComparer.Ordinal);
|
|
public HashSet<string> OccupantConstructionSiteIds { get; } = new(StringComparer.Ordinal);
|
|
public string LastDeltaSignature { get; set; } = string.Empty;
|
|
}
|
|
|
|
public sealed class StationRuntime
|
|
{
|
|
public required string Id { get; init; }
|
|
public required string SystemId { get; init; }
|
|
public required ConstructibleDefinition Definition { get; init; }
|
|
public required Vector3 Position { get; set; }
|
|
public required string FactionId { get; init; }
|
|
public string? NodeId { get; set; }
|
|
public string? BubbleId { get; set; }
|
|
public string? AnchorNodeId { get; set; }
|
|
public string? CommanderId { get; set; }
|
|
public string? PolicySetId { get; set; }
|
|
public HashSet<string> InstalledModules { get; } = new(StringComparer.Ordinal);
|
|
public Dictionary<string, float> Inventory { get; } = new(StringComparer.Ordinal);
|
|
public Dictionary<int, string> DockingPadAssignments { get; } = new();
|
|
public HashSet<string> MarketOrderIds { get; } = new(StringComparer.Ordinal);
|
|
public float EnergyStored { get; set; }
|
|
public float ProcessTimer { get; set; }
|
|
public float Population { get; set; }
|
|
public float PopulationCapacity { get; set; }
|
|
public float WorkforceRequired { get; set; }
|
|
public float WorkforceEffectiveRatio { get; set; } = 0.1f;
|
|
public float PopulationGrowthProgress { get; set; }
|
|
public HashSet<string> DockedShipIds { get; } = [];
|
|
public ModuleConstructionRuntime? ActiveConstruction { get; set; }
|
|
public string LastDeltaSignature { get; set; } = string.Empty;
|
|
}
|
|
|
|
public sealed class ModuleConstructionRuntime
|
|
{
|
|
public required string ModuleId { get; init; }
|
|
public float ProgressSeconds { get; set; }
|
|
public float RequiredSeconds { get; init; }
|
|
public string AssignedConstructorShipId { get; set; } = string.Empty;
|
|
}
|
|
|
|
public sealed class ShipRuntime
|
|
{
|
|
public required string Id { get; init; }
|
|
public required string SystemId { get; set; }
|
|
public required ShipDefinition Definition { get; init; }
|
|
public required string FactionId { get; init; }
|
|
public required Vector3 Position { get; set; }
|
|
public required Vector3 TargetPosition { get; set; }
|
|
public required ShipSpatialStateRuntime SpatialState { get; set; }
|
|
public Vector3 Velocity { get; set; } = Vector3.Zero;
|
|
public string State { get; set; } = "idle";
|
|
public ShipOrderRuntime? Order { get; set; }
|
|
public required DefaultBehaviorRuntime DefaultBehavior { get; set; }
|
|
public required ControllerTaskRuntime ControllerTask { get; set; }
|
|
public float ActionTimer { get; set; }
|
|
public Dictionary<string, float> Inventory { get; } = new(StringComparer.Ordinal);
|
|
public float WorkerPopulation { get; set; }
|
|
public float EnergyStored { get; set; }
|
|
public string? DockedStationId { get; set; }
|
|
public int? AssignedDockingPadIndex { get; set; }
|
|
public string? CommanderId { get; set; }
|
|
public string? PolicySetId { get; set; }
|
|
public float Health { get; set; }
|
|
public List<string> History { get; } = [];
|
|
public string LastSignature { get; set; } = string.Empty;
|
|
public string LastDeltaSignature { get; set; } = string.Empty;
|
|
}
|
|
|
|
public sealed class FactionRuntime
|
|
{
|
|
public required string Id { get; init; }
|
|
public required string Label { get; init; }
|
|
public required string Color { get; init; }
|
|
public float Credits { get; set; }
|
|
public float PopulationTotal { get; set; }
|
|
public float OreMined { get; set; }
|
|
public float GoodsProduced { get; set; }
|
|
public int ShipsBuilt { get; set; }
|
|
public int ShipsLost { get; set; }
|
|
public HashSet<string> CommanderIds { get; } = new(StringComparer.Ordinal);
|
|
public string? DefaultPolicySetId { get; set; }
|
|
public string LastDeltaSignature { get; set; } = string.Empty;
|
|
}
|
|
|
|
public sealed class CommanderRuntime
|
|
{
|
|
public required string Id { get; init; }
|
|
public required string Kind { get; set; }
|
|
public required string FactionId { get; init; }
|
|
public string? ParentCommanderId { get; set; }
|
|
public string? ControlledEntityId { get; set; }
|
|
public string? PolicySetId { get; set; }
|
|
public string? Doctrine { get; set; }
|
|
public List<string> Goals { get; } = [];
|
|
public CommanderBehaviorRuntime? ActiveBehavior { get; set; }
|
|
public CommanderOrderRuntime? ActiveOrder { get; set; }
|
|
public CommanderTaskRuntime? ActiveTask { get; set; }
|
|
public HashSet<string> SubordinateCommanderIds { get; } = new(StringComparer.Ordinal);
|
|
public bool IsAlive { get; set; } = true;
|
|
}
|
|
|
|
public sealed class CommanderBehaviorRuntime
|
|
{
|
|
public required string Kind { get; set; }
|
|
public string? Phase { get; set; }
|
|
public string? NodeId { get; set; }
|
|
public string? StationId { get; set; }
|
|
public string? ModuleId { get; set; }
|
|
public string? AreaSystemId { get; set; }
|
|
public int PatrolIndex { get; set; }
|
|
}
|
|
|
|
public sealed class CommanderOrderRuntime
|
|
{
|
|
public required string Kind { get; init; }
|
|
public string Status { get; set; } = "accepted";
|
|
public string? TargetEntityId { get; set; }
|
|
public string? DestinationNodeId { get; set; }
|
|
public required string DestinationSystemId { get; init; }
|
|
public required Vector3 DestinationPosition { get; init; }
|
|
}
|
|
|
|
public sealed class CommanderTaskRuntime
|
|
{
|
|
public required string Kind { get; set; }
|
|
public string Status { get; set; } = "pending";
|
|
public string? TargetEntityId { get; set; }
|
|
public string? TargetSystemId { get; set; }
|
|
public string? TargetNodeId { get; set; }
|
|
public Vector3? TargetPosition { get; set; }
|
|
public float Threshold { get; set; }
|
|
}
|
|
|
|
public sealed class ClaimRuntime
|
|
{
|
|
public required string Id { get; init; }
|
|
public required string FactionId { get; init; }
|
|
public required string SystemId { get; init; }
|
|
public required string NodeId { get; init; }
|
|
public required string BubbleId { get; init; }
|
|
public string? CommanderId { get; set; }
|
|
public DateTimeOffset PlacedAtUtc { get; init; }
|
|
public DateTimeOffset ActivatesAtUtc { get; set; }
|
|
public string State { get; set; } = ClaimStateKinds.Placed;
|
|
public float Health { get; set; }
|
|
public string LastDeltaSignature { get; set; } = string.Empty;
|
|
}
|
|
|
|
public sealed class ConstructionSiteRuntime
|
|
{
|
|
public required string Id { get; init; }
|
|
public required string FactionId { get; init; }
|
|
public required string SystemId { get; init; }
|
|
public required string NodeId { get; init; }
|
|
public required string BubbleId { get; init; }
|
|
public required string TargetKind { get; init; }
|
|
public required string TargetDefinitionId { get; init; }
|
|
public string? BlueprintId { get; set; }
|
|
public string? ClaimId { get; set; }
|
|
public string? StationId { get; set; }
|
|
public Dictionary<string, float> Inventory { get; } = new(StringComparer.Ordinal);
|
|
public Dictionary<string, float> RequiredItems { get; } = new(StringComparer.Ordinal);
|
|
public Dictionary<string, float> DeliveredItems { get; } = new(StringComparer.Ordinal);
|
|
public HashSet<string> AssignedConstructorShipIds { get; } = new(StringComparer.Ordinal);
|
|
public HashSet<string> MarketOrderIds { get; } = new(StringComparer.Ordinal);
|
|
public float Progress { get; set; }
|
|
public string State { get; set; } = ConstructionSiteStateKinds.Planned;
|
|
public string LastDeltaSignature { get; set; } = string.Empty;
|
|
}
|
|
|
|
public sealed class MarketOrderRuntime
|
|
{
|
|
public required string Id { get; init; }
|
|
public required string FactionId { get; init; }
|
|
public string? StationId { get; init; }
|
|
public string? ConstructionSiteId { get; init; }
|
|
public required string Kind { get; init; }
|
|
public required string ItemId { get; init; }
|
|
public float Amount { get; init; }
|
|
public float RemainingAmount { get; set; }
|
|
public float Valuation { get; set; }
|
|
public float? ReserveThreshold { get; set; }
|
|
public string? PolicySetId { get; set; }
|
|
public string State { get; set; } = MarketOrderStateKinds.Open;
|
|
public string LastDeltaSignature { get; set; } = string.Empty;
|
|
}
|
|
|
|
public sealed class PolicySetRuntime
|
|
{
|
|
public required string Id { get; init; }
|
|
public required string OwnerKind { get; init; }
|
|
public required string OwnerId { get; init; }
|
|
public string TradeAccessPolicy { get; set; } = "owner-and-allies";
|
|
public string DockingAccessPolicy { get; set; } = "owner-and-allies";
|
|
public string ConstructionAccessPolicy { get; set; } = "owner-only";
|
|
public string OperationalRangePolicy { get; set; } = "unrestricted";
|
|
public string LastDeltaSignature { get; set; } = string.Empty;
|
|
}
|
|
|
|
public sealed class ShipOrderRuntime
|
|
{
|
|
public required string Kind { get; init; }
|
|
public string Status { get; set; } = "accepted";
|
|
public required string DestinationSystemId { get; init; }
|
|
public required Vector3 DestinationPosition { get; init; }
|
|
}
|
|
|
|
public sealed class DefaultBehaviorRuntime
|
|
{
|
|
public required string Kind { get; set; }
|
|
public string? AreaSystemId { get; set; }
|
|
public string? StationId { get; set; }
|
|
public string? RefineryId { get; set; }
|
|
public string? NodeId { get; set; }
|
|
public string? ModuleId { get; set; }
|
|
public string? Phase { get; set; }
|
|
public List<Vector3> PatrolPoints { get; set; } = [];
|
|
public int PatrolIndex { get; set; }
|
|
}
|
|
|
|
public sealed class ControllerTaskRuntime
|
|
{
|
|
public required string Kind { get; set; }
|
|
public string Status { get; set; } = "pending";
|
|
public string? CommanderId { get; set; }
|
|
public string? TargetEntityId { get; set; }
|
|
public string? TargetSystemId { get; set; }
|
|
public string? TargetNodeId { get; set; }
|
|
public Vector3? TargetPosition { get; set; }
|
|
public float Threshold { get; set; }
|
|
}
|
|
|
|
public sealed class ShipSpatialStateRuntime
|
|
{
|
|
public string SpaceLayer { get; set; } = SpaceLayerKinds.LocalSpace;
|
|
public required string CurrentSystemId { get; set; }
|
|
public string? CurrentNodeId { get; set; }
|
|
public string? CurrentBubbleId { get; set; }
|
|
public Vector3? LocalPosition { get; set; }
|
|
public Vector3? SystemPosition { get; set; }
|
|
public string MovementRegime { get; set; } = MovementRegimeKinds.LocalFlight;
|
|
public string? DestinationNodeId { get; set; }
|
|
public ShipTransitRuntime? Transit { get; set; }
|
|
}
|
|
|
|
public sealed class ShipTransitRuntime
|
|
{
|
|
public required string Regime { get; init; }
|
|
public string? OriginNodeId { get; init; }
|
|
public string? DestinationNodeId { get; init; }
|
|
public DateTimeOffset? StartedAtUtc { get; set; }
|
|
public DateTimeOffset? ArrivalDueAtUtc { get; set; }
|
|
public float Progress { get; set; }
|
|
}
|
|
|
|
public static class SpaceLayerKinds
|
|
{
|
|
public const string UniverseSpace = "universe-space";
|
|
public const string GalaxySpace = "galaxy-space";
|
|
public const string SystemSpace = "system-space";
|
|
public const string LocalSpace = "local-space";
|
|
}
|
|
|
|
public static class MovementRegimeKinds
|
|
{
|
|
public const string LocalFlight = "local-flight";
|
|
public const string Warp = "warp";
|
|
public const string StargateTransit = "stargate-transit";
|
|
public const string FtlTransit = "ftl-transit";
|
|
}
|
|
|
|
public static class CommanderKind
|
|
{
|
|
public const string Faction = "faction";
|
|
public const string Station = "station";
|
|
public const string Ship = "ship";
|
|
public const string Fleet = "fleet";
|
|
public const string Sector = "sector";
|
|
public const string TaskGroup = "task-group";
|
|
}
|
|
|
|
public static class ShipTaskKinds
|
|
{
|
|
public const string Idle = "idle";
|
|
public const string LocalMove = "local-move";
|
|
public const string WarpToNode = "warp-to-node";
|
|
public const string UseStargate = "use-stargate";
|
|
public const string UseFtl = "use-ftl";
|
|
public const string Dock = "dock";
|
|
public const string Undock = "undock";
|
|
public const string LoadCargo = "load-cargo";
|
|
public const string UnloadCargo = "unload-cargo";
|
|
public const string LoadWorkers = "load-workers";
|
|
public const string UnloadWorkers = "unload-workers";
|
|
public const string MineNode = "mine-node";
|
|
public const string HarvestGas = "harvest-gas";
|
|
public const string DeliverToStation = "deliver-to-station";
|
|
public const string ClaimLagrangePoint = "claim-lagrange-point";
|
|
public const string BuildConstructionSite = "build-construction-site";
|
|
public const string EscortTarget = "escort-target";
|
|
public const string AttackTarget = "attack-target";
|
|
public const string DefendBubble = "defend-bubble";
|
|
public const string Retreat = "retreat";
|
|
public const string HoldPosition = "hold-position";
|
|
}
|
|
|
|
public static class ShipOrderKinds
|
|
{
|
|
public const string DirectMove = "direct-move";
|
|
public const string TravelToNode = "travel-to-node";
|
|
public const string DockAtStation = "dock-at-station";
|
|
public const string DeliverCargo = "deliver-cargo";
|
|
public const string BuildAtSite = "build-at-site";
|
|
public const string AttackTarget = "attack-target";
|
|
public const string HoldPosition = "hold-position";
|
|
}
|
|
|
|
public static class ClaimStateKinds
|
|
{
|
|
public const string Placed = "placed";
|
|
public const string Activating = "activating";
|
|
public const string Active = "active";
|
|
public const string Destroyed = "destroyed";
|
|
}
|
|
|
|
public static class ConstructionSiteStateKinds
|
|
{
|
|
public const string Planned = "planned";
|
|
public const string Active = "active";
|
|
public const string Paused = "paused";
|
|
public const string Completed = "completed";
|
|
public const string Destroyed = "destroyed";
|
|
}
|
|
|
|
public static class MarketOrderKinds
|
|
{
|
|
public const string Buy = "buy";
|
|
public const string Sell = "sell";
|
|
}
|
|
|
|
public static class MarketOrderStateKinds
|
|
{
|
|
public const string Open = "open";
|
|
public const string PartiallyFilled = "partially-filled";
|
|
public const string Filled = "filled";
|
|
public const string Cancelled = "cancelled";
|
|
}
|
|
|
|
public readonly record struct Vector3(float X, float Y, float Z)
|
|
{
|
|
public static Vector3 Zero => new(0f, 0f, 0f);
|
|
|
|
public float LengthSquared() => (X * X) + (Y * Y) + (Z * Z);
|
|
|
|
public float DistanceTo(Vector3 other)
|
|
{
|
|
var dx = X - other.X;
|
|
var dy = Y - other.Y;
|
|
var dz = Z - other.Z;
|
|
return MathF.Sqrt((dx * dx) + (dy * dy) + (dz * dz));
|
|
}
|
|
|
|
public Vector3 MoveToward(Vector3 target, float maxDistance)
|
|
{
|
|
var distance = DistanceTo(target);
|
|
if (distance <= maxDistance || distance <= 0.0001f)
|
|
{
|
|
return target;
|
|
}
|
|
|
|
var t = maxDistance / distance;
|
|
return new Vector3(
|
|
X + ((target.X - X) * t),
|
|
Y + ((target.Y - Y) * t),
|
|
Z + ((target.Z - Z) * t));
|
|
}
|
|
|
|
public Vector3 Subtract(Vector3 other) => new(X - other.X, Y - other.Y, Z - other.Z);
|
|
|
|
public Vector3 Divide(float value)
|
|
{
|
|
if (value == 0f)
|
|
{
|
|
return Zero;
|
|
}
|
|
|
|
return new(X / value, Y / value, Z / value);
|
|
}
|
|
}
|