chore: add .editorconfig and consistent formatting for backend projects
Adds an `.editorconfig` file with C# and project-specific conventions. Applies consistent indentation and formatting across backend handlers, runtime models, and AI services.
This commit is contained in:
@@ -2,276 +2,276 @@ namespace SpaceGame.Api.Shared.Runtime;
|
||||
|
||||
public enum SpatialNodeKind
|
||||
{
|
||||
Star,
|
||||
Planet,
|
||||
Moon,
|
||||
LagrangePoint,
|
||||
Star,
|
||||
Planet,
|
||||
Moon,
|
||||
LagrangePoint,
|
||||
}
|
||||
|
||||
public enum WorkStatus
|
||||
{
|
||||
Pending,
|
||||
Active,
|
||||
Blocked,
|
||||
Completed,
|
||||
Failed,
|
||||
Interrupted,
|
||||
Pending,
|
||||
Active,
|
||||
Blocked,
|
||||
Completed,
|
||||
Failed,
|
||||
Interrupted,
|
||||
}
|
||||
|
||||
public enum OrderStatus
|
||||
{
|
||||
Queued,
|
||||
Active,
|
||||
Completed,
|
||||
Cancelled,
|
||||
Failed,
|
||||
Interrupted,
|
||||
Queued,
|
||||
Active,
|
||||
Completed,
|
||||
Cancelled,
|
||||
Failed,
|
||||
Interrupted,
|
||||
}
|
||||
|
||||
public enum AiPlanStatus
|
||||
{
|
||||
Planned,
|
||||
Running,
|
||||
Blocked,
|
||||
Completed,
|
||||
Failed,
|
||||
Interrupted,
|
||||
Planned,
|
||||
Running,
|
||||
Blocked,
|
||||
Completed,
|
||||
Failed,
|
||||
Interrupted,
|
||||
}
|
||||
|
||||
public enum AiPlanStepStatus
|
||||
{
|
||||
Planned,
|
||||
Running,
|
||||
Blocked,
|
||||
Completed,
|
||||
Failed,
|
||||
Interrupted,
|
||||
Planned,
|
||||
Running,
|
||||
Blocked,
|
||||
Completed,
|
||||
Failed,
|
||||
Interrupted,
|
||||
}
|
||||
|
||||
public enum AiPlanSourceKind
|
||||
{
|
||||
Rule,
|
||||
Order,
|
||||
DefaultBehavior,
|
||||
Rule,
|
||||
Order,
|
||||
DefaultBehavior,
|
||||
}
|
||||
|
||||
public enum ShipState
|
||||
{
|
||||
Idle,
|
||||
Arriving,
|
||||
LocalFlight,
|
||||
SpoolingWarp,
|
||||
Warping,
|
||||
SpoolingFtl,
|
||||
Ftl,
|
||||
CargoFull,
|
||||
MiningApproach,
|
||||
Mining,
|
||||
NodeDepleted,
|
||||
AwaitingDock,
|
||||
DockingApproach,
|
||||
Docking,
|
||||
Docked,
|
||||
Transferring,
|
||||
Loading,
|
||||
Unloading,
|
||||
WaitingMaterials,
|
||||
ConstructionBlocked,
|
||||
Constructing,
|
||||
DeliveringConstruction,
|
||||
Blocked,
|
||||
Undocking,
|
||||
EngagingTarget,
|
||||
HoldingPosition,
|
||||
Fleeing,
|
||||
Idle,
|
||||
Arriving,
|
||||
LocalFlight,
|
||||
SpoolingWarp,
|
||||
Warping,
|
||||
SpoolingFtl,
|
||||
Ftl,
|
||||
CargoFull,
|
||||
MiningApproach,
|
||||
Mining,
|
||||
NodeDepleted,
|
||||
AwaitingDock,
|
||||
DockingApproach,
|
||||
Docking,
|
||||
Docked,
|
||||
Transferring,
|
||||
Loading,
|
||||
Unloading,
|
||||
WaitingMaterials,
|
||||
ConstructionBlocked,
|
||||
Constructing,
|
||||
DeliveringConstruction,
|
||||
Blocked,
|
||||
Undocking,
|
||||
EngagingTarget,
|
||||
HoldingPosition,
|
||||
Fleeing,
|
||||
}
|
||||
|
||||
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 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 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 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 HoldPosition = "hold-position";
|
||||
public const string Travel = "travel";
|
||||
public const string FollowTarget = "follow-target";
|
||||
public const string MineNode = "mine-node";
|
||||
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 TransferCargoToShip = "transfer-cargo-to-ship";
|
||||
public const string SalvageWreck = "salvage-wreck";
|
||||
public const string DeliverConstruction = "deliver-construction";
|
||||
public const string ConstructModule = "construct-module";
|
||||
public const string BuildConstructionSite = "build-construction-site";
|
||||
public const string AttackTarget = "attack-target";
|
||||
public const string Flee = "flee";
|
||||
public const string Wait = "wait";
|
||||
public const string HoldPosition = "hold-position";
|
||||
public const string Travel = "travel";
|
||||
public const string FollowTarget = "follow-target";
|
||||
public const string MineNode = "mine-node";
|
||||
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 TransferCargoToShip = "transfer-cargo-to-ship";
|
||||
public const string SalvageWreck = "salvage-wreck";
|
||||
public const string DeliverConstruction = "deliver-construction";
|
||||
public const string ConstructModule = "construct-module";
|
||||
public const string BuildConstructionSite = "build-construction-site";
|
||||
public const string AttackTarget = "attack-target";
|
||||
public const string Flee = "flee";
|
||||
public const string Wait = "wait";
|
||||
}
|
||||
|
||||
public static class ShipOrderKinds
|
||||
{
|
||||
public const string Move = "move";
|
||||
public const string DockAtStation = "dock-at-station";
|
||||
public const string DockAndWait = "dock-and-wait";
|
||||
public const string FlyAndWait = "fly-and-wait";
|
||||
public const string FlyToObject = "fly-to-object";
|
||||
public const string FollowShip = "follow-ship";
|
||||
public const string TradeRoute = "trade-route";
|
||||
public const string MineAndDeliver = "mine-and-deliver";
|
||||
public const string BuildAtSite = "build-at-site";
|
||||
public const string AttackTarget = "attack-target";
|
||||
public const string HoldPosition = "hold-position";
|
||||
public const string RepeatOrders = "repeat-orders";
|
||||
public const string Flee = "flee";
|
||||
public const string Move = "move";
|
||||
public const string DockAtStation = "dock-at-station";
|
||||
public const string DockAndWait = "dock-and-wait";
|
||||
public const string FlyAndWait = "fly-and-wait";
|
||||
public const string FlyToObject = "fly-to-object";
|
||||
public const string FollowShip = "follow-ship";
|
||||
public const string TradeRoute = "trade-route";
|
||||
public const string MineAndDeliver = "mine-and-deliver";
|
||||
public const string BuildAtSite = "build-at-site";
|
||||
public const string AttackTarget = "attack-target";
|
||||
public const string HoldPosition = "hold-position";
|
||||
public const string RepeatOrders = "repeat-orders";
|
||||
public const string Flee = "flee";
|
||||
}
|
||||
|
||||
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 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 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 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 const string Open = "open";
|
||||
public const string PartiallyFilled = "partially-filled";
|
||||
public const string Filled = "filled";
|
||||
public const string Cancelled = "cancelled";
|
||||
}
|
||||
|
||||
public static class SimulationEnumMappings
|
||||
{
|
||||
public static string ToContractValue(this SpatialNodeKind kind) => kind switch
|
||||
{
|
||||
SpatialNodeKind.Star => "star",
|
||||
SpatialNodeKind.Planet => "planet",
|
||||
SpatialNodeKind.Moon => "moon",
|
||||
SpatialNodeKind.LagrangePoint => "lagrange-point",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(kind), kind, null),
|
||||
};
|
||||
public static string ToContractValue(this SpatialNodeKind kind) => kind switch
|
||||
{
|
||||
SpatialNodeKind.Star => "star",
|
||||
SpatialNodeKind.Planet => "planet",
|
||||
SpatialNodeKind.Moon => "moon",
|
||||
SpatialNodeKind.LagrangePoint => "lagrange-point",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(kind), kind, null),
|
||||
};
|
||||
|
||||
public static string ToContractValue(this WorkStatus status) => status switch
|
||||
{
|
||||
WorkStatus.Pending => "pending",
|
||||
WorkStatus.Active => "active",
|
||||
WorkStatus.Blocked => "blocked",
|
||||
WorkStatus.Completed => "completed",
|
||||
WorkStatus.Failed => "failed",
|
||||
WorkStatus.Interrupted => "interrupted",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(status), status, null),
|
||||
};
|
||||
public static string ToContractValue(this WorkStatus status) => status switch
|
||||
{
|
||||
WorkStatus.Pending => "pending",
|
||||
WorkStatus.Active => "active",
|
||||
WorkStatus.Blocked => "blocked",
|
||||
WorkStatus.Completed => "completed",
|
||||
WorkStatus.Failed => "failed",
|
||||
WorkStatus.Interrupted => "interrupted",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(status), status, null),
|
||||
};
|
||||
|
||||
public static string ToContractValue(this OrderStatus status) => status switch
|
||||
{
|
||||
OrderStatus.Queued => "queued",
|
||||
OrderStatus.Active => "active",
|
||||
OrderStatus.Completed => "completed",
|
||||
OrderStatus.Cancelled => "cancelled",
|
||||
OrderStatus.Failed => "failed",
|
||||
OrderStatus.Interrupted => "interrupted",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(status), status, null),
|
||||
};
|
||||
public static string ToContractValue(this OrderStatus status) => status switch
|
||||
{
|
||||
OrderStatus.Queued => "queued",
|
||||
OrderStatus.Active => "active",
|
||||
OrderStatus.Completed => "completed",
|
||||
OrderStatus.Cancelled => "cancelled",
|
||||
OrderStatus.Failed => "failed",
|
||||
OrderStatus.Interrupted => "interrupted",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(status), status, null),
|
||||
};
|
||||
|
||||
public static string ToContractValue(this AiPlanStatus status) => status switch
|
||||
{
|
||||
AiPlanStatus.Planned => "planned",
|
||||
AiPlanStatus.Running => "running",
|
||||
AiPlanStatus.Blocked => "blocked",
|
||||
AiPlanStatus.Completed => "completed",
|
||||
AiPlanStatus.Failed => "failed",
|
||||
AiPlanStatus.Interrupted => "interrupted",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(status), status, null),
|
||||
};
|
||||
public static string ToContractValue(this AiPlanStatus status) => status switch
|
||||
{
|
||||
AiPlanStatus.Planned => "planned",
|
||||
AiPlanStatus.Running => "running",
|
||||
AiPlanStatus.Blocked => "blocked",
|
||||
AiPlanStatus.Completed => "completed",
|
||||
AiPlanStatus.Failed => "failed",
|
||||
AiPlanStatus.Interrupted => "interrupted",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(status), status, null),
|
||||
};
|
||||
|
||||
public static string ToContractValue(this AiPlanStepStatus status) => status switch
|
||||
{
|
||||
AiPlanStepStatus.Planned => "planned",
|
||||
AiPlanStepStatus.Running => "running",
|
||||
AiPlanStepStatus.Blocked => "blocked",
|
||||
AiPlanStepStatus.Completed => "completed",
|
||||
AiPlanStepStatus.Failed => "failed",
|
||||
AiPlanStepStatus.Interrupted => "interrupted",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(status), status, null),
|
||||
};
|
||||
public static string ToContractValue(this AiPlanStepStatus status) => status switch
|
||||
{
|
||||
AiPlanStepStatus.Planned => "planned",
|
||||
AiPlanStepStatus.Running => "running",
|
||||
AiPlanStepStatus.Blocked => "blocked",
|
||||
AiPlanStepStatus.Completed => "completed",
|
||||
AiPlanStepStatus.Failed => "failed",
|
||||
AiPlanStepStatus.Interrupted => "interrupted",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(status), status, null),
|
||||
};
|
||||
|
||||
public static string ToContractValue(this AiPlanSourceKind kind) => kind switch
|
||||
{
|
||||
AiPlanSourceKind.Rule => "rule",
|
||||
AiPlanSourceKind.Order => "order",
|
||||
AiPlanSourceKind.DefaultBehavior => "default-behavior",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(kind), kind, null),
|
||||
};
|
||||
public static string ToContractValue(this AiPlanSourceKind kind) => kind switch
|
||||
{
|
||||
AiPlanSourceKind.Rule => "rule",
|
||||
AiPlanSourceKind.Order => "order",
|
||||
AiPlanSourceKind.DefaultBehavior => "default-behavior",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(kind), kind, null),
|
||||
};
|
||||
|
||||
public static string ToContractValue(this ShipState state) => state switch
|
||||
{
|
||||
ShipState.Idle => "idle",
|
||||
ShipState.Arriving => "arriving",
|
||||
ShipState.LocalFlight => "local-flight",
|
||||
ShipState.SpoolingWarp => "spooling-warp",
|
||||
ShipState.Warping => "warping",
|
||||
ShipState.SpoolingFtl => "spooling-ftl",
|
||||
ShipState.Ftl => "ftl",
|
||||
ShipState.CargoFull => "cargo-full",
|
||||
ShipState.MiningApproach => "mining-approach",
|
||||
ShipState.Mining => "mining",
|
||||
ShipState.NodeDepleted => "node-depleted",
|
||||
ShipState.AwaitingDock => "awaiting-dock",
|
||||
ShipState.DockingApproach => "docking-approach",
|
||||
ShipState.Docking => "docking",
|
||||
ShipState.Docked => "docked",
|
||||
ShipState.Transferring => "transferring",
|
||||
ShipState.Loading => "loading",
|
||||
ShipState.Unloading => "unloading",
|
||||
ShipState.WaitingMaterials => "waiting-materials",
|
||||
ShipState.ConstructionBlocked => "construction-blocked",
|
||||
ShipState.Constructing => "constructing",
|
||||
ShipState.DeliveringConstruction => "delivering-construction",
|
||||
ShipState.Blocked => "blocked",
|
||||
ShipState.Undocking => "undocking",
|
||||
ShipState.EngagingTarget => "engaging-target",
|
||||
ShipState.HoldingPosition => "holding-position",
|
||||
ShipState.Fleeing => "fleeing",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(state), state, null),
|
||||
};
|
||||
public static string ToContractValue(this ShipState state) => state switch
|
||||
{
|
||||
ShipState.Idle => "idle",
|
||||
ShipState.Arriving => "arriving",
|
||||
ShipState.LocalFlight => "local-flight",
|
||||
ShipState.SpoolingWarp => "spooling-warp",
|
||||
ShipState.Warping => "warping",
|
||||
ShipState.SpoolingFtl => "spooling-ftl",
|
||||
ShipState.Ftl => "ftl",
|
||||
ShipState.CargoFull => "cargo-full",
|
||||
ShipState.MiningApproach => "mining-approach",
|
||||
ShipState.Mining => "mining",
|
||||
ShipState.NodeDepleted => "node-depleted",
|
||||
ShipState.AwaitingDock => "awaiting-dock",
|
||||
ShipState.DockingApproach => "docking-approach",
|
||||
ShipState.Docking => "docking",
|
||||
ShipState.Docked => "docked",
|
||||
ShipState.Transferring => "transferring",
|
||||
ShipState.Loading => "loading",
|
||||
ShipState.Unloading => "unloading",
|
||||
ShipState.WaitingMaterials => "waiting-materials",
|
||||
ShipState.ConstructionBlocked => "construction-blocked",
|
||||
ShipState.Constructing => "constructing",
|
||||
ShipState.DeliveringConstruction => "delivering-construction",
|
||||
ShipState.Blocked => "blocked",
|
||||
ShipState.Undocking => "undocking",
|
||||
ShipState.EngagingTarget => "engaging-target",
|
||||
ShipState.HoldingPosition => "holding-position",
|
||||
ShipState.Fleeing => "fleeing",
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(state), state, null),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,179 +3,179 @@ namespace SpaceGame.Api.Shared.Runtime;
|
||||
|
||||
internal static class SimulationRuntimeSupport
|
||||
{
|
||||
internal static bool HasShipCapabilities(ShipDefinition definition, params string[] capabilities) =>
|
||||
capabilities.All(cap => definition.Capabilities.Contains(cap, StringComparer.Ordinal));
|
||||
internal static bool HasShipCapabilities(ShipDefinition definition, params string[] capabilities) =>
|
||||
capabilities.All(cap => definition.Capabilities.Contains(cap, StringComparer.Ordinal));
|
||||
|
||||
internal static int CountStationModules(StationRuntime station, string moduleId) =>
|
||||
station.Modules.Count(module => string.Equals(module.ModuleId, moduleId, StringComparison.Ordinal));
|
||||
internal static int CountStationModules(StationRuntime station, string moduleId) =>
|
||||
station.Modules.Count(module => string.Equals(module.ModuleId, moduleId, StringComparison.Ordinal));
|
||||
|
||||
internal static void AddStationModule(SimulationWorld world, StationRuntime station, string moduleId)
|
||||
{
|
||||
if (!world.ModuleDefinitions.TryGetValue(moduleId, out var definition))
|
||||
internal static void AddStationModule(SimulationWorld world, StationRuntime station, string moduleId)
|
||||
{
|
||||
return;
|
||||
if (!world.ModuleDefinitions.TryGetValue(moduleId, out var definition))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
station.Modules.Add(new StationModuleRuntime
|
||||
{
|
||||
Id = $"{station.Id}-module-{station.Modules.Count + 1}",
|
||||
ModuleId = moduleId,
|
||||
Health = definition.Hull,
|
||||
MaxHealth = definition.Hull,
|
||||
});
|
||||
station.Radius = GetStationRadius(world, station);
|
||||
}
|
||||
|
||||
station.Modules.Add(new StationModuleRuntime
|
||||
internal static float GetStationRadius(SimulationWorld world, StationRuntime station)
|
||||
{
|
||||
Id = $"{station.Id}-module-{station.Modules.Count + 1}",
|
||||
ModuleId = moduleId,
|
||||
Health = definition.Hull,
|
||||
MaxHealth = definition.Hull,
|
||||
});
|
||||
station.Radius = GetStationRadius(world, station);
|
||||
}
|
||||
|
||||
internal static float GetStationRadius(SimulationWorld world, StationRuntime station)
|
||||
{
|
||||
var totalArea = station.Modules
|
||||
.Select(module => world.ModuleDefinitions.TryGetValue(module.ModuleId, out var definition) ? definition.Radius * definition.Radius : 0f)
|
||||
.Sum();
|
||||
return MathF.Max(24f, MathF.Sqrt(MathF.Max(totalArea, 1f)));
|
||||
}
|
||||
|
||||
internal static float GetStationStorageCapacity(StationRuntime station, string storageClass)
|
||||
{
|
||||
var baseCapacity = storageClass switch
|
||||
{
|
||||
"manufactured" => 400f,
|
||||
_ => 0f,
|
||||
};
|
||||
|
||||
var bulkBays = CountStationModules(station, "module_arg_stor_solid_m_01");
|
||||
var liquidTanks = CountStationModules(station, "module_arg_stor_liquid_m_01");
|
||||
var containerBays = CountStationModules(station, "module_arg_stor_container_m_01");
|
||||
|
||||
var moduleCapacity = storageClass switch
|
||||
{
|
||||
"solid" => bulkBays * 1000f,
|
||||
"liquid" => liquidTanks * 500f,
|
||||
"container" => containerBays * 800f,
|
||||
"manufactured" => containerBays * 200f,
|
||||
_ => 0f,
|
||||
};
|
||||
|
||||
return baseCapacity + moduleCapacity;
|
||||
}
|
||||
|
||||
internal static int CountModules(IEnumerable<string> modules, string moduleId) =>
|
||||
modules.Count(candidate => string.Equals(candidate, moduleId, StringComparison.Ordinal));
|
||||
|
||||
internal static float GetInventoryAmount(IReadOnlyDictionary<string, float> inventory, string itemId) =>
|
||||
inventory.TryGetValue(itemId, out var amount) ? amount : 0f;
|
||||
|
||||
internal static void AddInventory(IDictionary<string, float> inventory, string itemId, float amount)
|
||||
{
|
||||
if (amount <= 0f)
|
||||
{
|
||||
return;
|
||||
var totalArea = station.Modules
|
||||
.Select(module => world.ModuleDefinitions.TryGetValue(module.ModuleId, out var definition) ? definition.Radius * definition.Radius : 0f)
|
||||
.Sum();
|
||||
return MathF.Max(24f, MathF.Sqrt(MathF.Max(totalArea, 1f)));
|
||||
}
|
||||
|
||||
inventory[itemId] = GetInventoryAmount((IReadOnlyDictionary<string, float>)inventory, itemId) + amount;
|
||||
}
|
||||
internal static float GetStationStorageCapacity(StationRuntime station, string storageClass)
|
||||
{
|
||||
var baseCapacity = storageClass switch
|
||||
{
|
||||
"manufactured" => 400f,
|
||||
_ => 0f,
|
||||
};
|
||||
|
||||
internal static float RemoveInventory(IDictionary<string, float> inventory, string itemId, float amount)
|
||||
{
|
||||
var current = GetInventoryAmount((IReadOnlyDictionary<string, float>)inventory, itemId);
|
||||
var removed = MathF.Min(current, amount);
|
||||
var remaining = current - removed;
|
||||
if (remaining <= 0.001f)
|
||||
{
|
||||
inventory.Remove(itemId);
|
||||
}
|
||||
else
|
||||
{
|
||||
inventory[itemId] = remaining;
|
||||
var bulkBays = CountStationModules(station, "module_arg_stor_solid_m_01");
|
||||
var liquidTanks = CountStationModules(station, "module_arg_stor_liquid_m_01");
|
||||
var containerBays = CountStationModules(station, "module_arg_stor_container_m_01");
|
||||
|
||||
var moduleCapacity = storageClass switch
|
||||
{
|
||||
"solid" => bulkBays * 1000f,
|
||||
"liquid" => liquidTanks * 500f,
|
||||
"container" => containerBays * 800f,
|
||||
"manufactured" => containerBays * 200f,
|
||||
_ => 0f,
|
||||
};
|
||||
|
||||
return baseCapacity + moduleCapacity;
|
||||
}
|
||||
|
||||
return removed;
|
||||
}
|
||||
internal static int CountModules(IEnumerable<string> modules, string moduleId) =>
|
||||
modules.Count(candidate => string.Equals(candidate, moduleId, StringComparison.Ordinal));
|
||||
|
||||
internal static bool HasStationModules(StationRuntime station, params string[] modules) =>
|
||||
modules.All(moduleId => station.Modules.Any(candidate => string.Equals(candidate.ModuleId, moduleId, StringComparison.Ordinal)));
|
||||
internal static float GetInventoryAmount(IReadOnlyDictionary<string, float> inventory, string itemId) =>
|
||||
inventory.TryGetValue(itemId, out var amount) ? amount : 0f;
|
||||
|
||||
internal static bool CanExtractNode(ShipRuntime ship, ResourceNodeRuntime node, SimulationWorld world) =>
|
||||
HasShipCapabilities(ship.Definition, "mining")
|
||||
&& world.ItemDefinitions.TryGetValue(node.ItemId, out var item)
|
||||
&& string.Equals(item.CargoKind, ship.Definition.CargoKind, StringComparison.Ordinal);
|
||||
|
||||
internal static bool CanBuildClaimBeacon(ShipRuntime ship) =>
|
||||
string.Equals(ship.Definition.Kind, "military", StringComparison.Ordinal);
|
||||
|
||||
internal static float ComputeWorkforceRatio(float population, float workforceRequired)
|
||||
{
|
||||
if (workforceRequired <= 0.01f)
|
||||
internal static void AddInventory(IDictionary<string, float> inventory, string itemId, float amount)
|
||||
{
|
||||
return 1f;
|
||||
if (amount <= 0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
inventory[itemId] = GetInventoryAmount((IReadOnlyDictionary<string, float>)inventory, itemId) + amount;
|
||||
}
|
||||
|
||||
var staffedRatio = MathF.Min(1f, population / workforceRequired);
|
||||
return 0.1f + (0.9f * staffedRatio);
|
||||
}
|
||||
|
||||
internal static string? GetStorageRequirement(string storageClass) =>
|
||||
storageClass switch
|
||||
{
|
||||
"solid" => "module_arg_stor_solid_m_01",
|
||||
"liquid" => "module_arg_stor_liquid_m_01",
|
||||
_ => null,
|
||||
};
|
||||
|
||||
internal static float TryAddStationInventory(SimulationWorld world, StationRuntime station, string itemId, float amount)
|
||||
{
|
||||
if (amount <= 0f || !world.ItemDefinitions.TryGetValue(itemId, out var itemDefinition))
|
||||
internal static float RemoveInventory(IDictionary<string, float> inventory, string itemId, float amount)
|
||||
{
|
||||
return 0f;
|
||||
var current = GetInventoryAmount((IReadOnlyDictionary<string, float>)inventory, itemId);
|
||||
var removed = MathF.Min(current, amount);
|
||||
var remaining = current - removed;
|
||||
if (remaining <= 0.001f)
|
||||
{
|
||||
inventory.Remove(itemId);
|
||||
}
|
||||
else
|
||||
{
|
||||
inventory[itemId] = remaining;
|
||||
}
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
var storageClass = itemDefinition.CargoKind;
|
||||
var requiredModule = GetStorageRequirement(storageClass);
|
||||
if (requiredModule is not null && !station.InstalledModules.Contains(requiredModule, StringComparer.Ordinal))
|
||||
internal static bool HasStationModules(StationRuntime station, params string[] modules) =>
|
||||
modules.All(moduleId => station.Modules.Any(candidate => string.Equals(candidate.ModuleId, moduleId, StringComparison.Ordinal)));
|
||||
|
||||
internal static bool CanExtractNode(ShipRuntime ship, ResourceNodeRuntime node, SimulationWorld world) =>
|
||||
HasShipCapabilities(ship.Definition, "mining")
|
||||
&& world.ItemDefinitions.TryGetValue(node.ItemId, out var item)
|
||||
&& string.Equals(item.CargoKind, ship.Definition.CargoKind, StringComparison.Ordinal);
|
||||
|
||||
internal static bool CanBuildClaimBeacon(ShipRuntime ship) =>
|
||||
string.Equals(ship.Definition.Kind, "military", StringComparison.Ordinal);
|
||||
|
||||
internal static float ComputeWorkforceRatio(float population, float workforceRequired)
|
||||
{
|
||||
return 0f;
|
||||
if (workforceRequired <= 0.01f)
|
||||
{
|
||||
return 1f;
|
||||
}
|
||||
|
||||
var staffedRatio = MathF.Min(1f, population / workforceRequired);
|
||||
return 0.1f + (0.9f * staffedRatio);
|
||||
}
|
||||
|
||||
var capacity = GetStationStorageCapacity(station, storageClass);
|
||||
if (capacity <= 0.01f)
|
||||
internal static string? GetStorageRequirement(string storageClass) =>
|
||||
storageClass switch
|
||||
{
|
||||
"solid" => "module_arg_stor_solid_m_01",
|
||||
"liquid" => "module_arg_stor_liquid_m_01",
|
||||
_ => null,
|
||||
};
|
||||
|
||||
internal static float TryAddStationInventory(SimulationWorld world, StationRuntime station, string itemId, float amount)
|
||||
{
|
||||
return 0f;
|
||||
if (amount <= 0f || !world.ItemDefinitions.TryGetValue(itemId, out var itemDefinition))
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
var storageClass = itemDefinition.CargoKind;
|
||||
var requiredModule = GetStorageRequirement(storageClass);
|
||||
if (requiredModule is not null && !station.InstalledModules.Contains(requiredModule, StringComparer.Ordinal))
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
var capacity = GetStationStorageCapacity(station, storageClass);
|
||||
if (capacity <= 0.01f)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
var used = station.Inventory
|
||||
.Where(entry => world.ItemDefinitions.TryGetValue(entry.Key, out var definition) && definition.CargoKind == storageClass)
|
||||
.Sum(entry => entry.Value);
|
||||
var accepted = MathF.Min(amount, MathF.Max(0f, capacity - used));
|
||||
if (accepted <= 0.01f)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
AddInventory(station.Inventory, itemId, accepted);
|
||||
return accepted;
|
||||
}
|
||||
|
||||
var used = station.Inventory
|
||||
.Where(entry => world.ItemDefinitions.TryGetValue(entry.Key, out var definition) && definition.CargoKind == storageClass)
|
||||
.Sum(entry => entry.Value);
|
||||
var accepted = MathF.Min(amount, MathF.Max(0f, capacity - used));
|
||||
if (accepted <= 0.01f)
|
||||
internal static bool CanStartModuleConstruction(StationRuntime station, ModuleRecipeDefinition recipe) =>
|
||||
recipe.Inputs.All(input => GetInventoryAmount(station.Inventory, input.ItemId) + 0.001f >= input.Amount);
|
||||
|
||||
internal static ConstructionSiteRuntime? GetConstructionSiteForStation(SimulationWorld world, string stationId) =>
|
||||
world.ConstructionSites.FirstOrDefault(site =>
|
||||
string.Equals(site.StationId, stationId, StringComparison.Ordinal)
|
||||
&& site.State is not ConstructionSiteStateKinds.Completed and not ConstructionSiteStateKinds.Destroyed);
|
||||
|
||||
internal static float GetConstructionDeliveredAmount(SimulationWorld world, ConstructionSiteRuntime site, string itemId)
|
||||
{
|
||||
return 0f;
|
||||
if (site.StationId is not null
|
||||
&& world.Stations.FirstOrDefault(candidate => candidate.Id == site.StationId) is { } station)
|
||||
{
|
||||
return GetInventoryAmount(station.Inventory, itemId);
|
||||
}
|
||||
|
||||
return GetInventoryAmount(site.DeliveredItems, itemId);
|
||||
}
|
||||
|
||||
AddInventory(station.Inventory, itemId, accepted);
|
||||
return accepted;
|
||||
}
|
||||
internal static bool IsConstructionSiteReady(SimulationWorld world, ConstructionSiteRuntime site) =>
|
||||
site.RequiredItems.All(entry => GetConstructionDeliveredAmount(world, site, entry.Key) + 0.001f >= entry.Value);
|
||||
|
||||
internal static bool CanStartModuleConstruction(StationRuntime station, ModuleRecipeDefinition recipe) =>
|
||||
recipe.Inputs.All(input => GetInventoryAmount(station.Inventory, input.ItemId) + 0.001f >= input.Amount);
|
||||
|
||||
internal static ConstructionSiteRuntime? GetConstructionSiteForStation(SimulationWorld world, string stationId) =>
|
||||
world.ConstructionSites.FirstOrDefault(site =>
|
||||
string.Equals(site.StationId, stationId, StringComparison.Ordinal)
|
||||
&& site.State is not ConstructionSiteStateKinds.Completed and not ConstructionSiteStateKinds.Destroyed);
|
||||
|
||||
internal static float GetConstructionDeliveredAmount(SimulationWorld world, ConstructionSiteRuntime site, string itemId)
|
||||
{
|
||||
if (site.StationId is not null
|
||||
&& world.Stations.FirstOrDefault(candidate => candidate.Id == site.StationId) is { } station)
|
||||
{
|
||||
return GetInventoryAmount(station.Inventory, itemId);
|
||||
}
|
||||
|
||||
return GetInventoryAmount(site.DeliveredItems, itemId);
|
||||
}
|
||||
|
||||
internal static bool IsConstructionSiteReady(SimulationWorld world, ConstructionSiteRuntime site) =>
|
||||
site.RequiredItems.All(entry => GetConstructionDeliveredAmount(world, site, entry.Key) + 0.001f >= entry.Value);
|
||||
|
||||
internal static float GetShipCargoAmount(ShipRuntime ship) =>
|
||||
ship.Inventory.Values.Sum();
|
||||
internal static float GetShipCargoAmount(ShipRuntime ship) =>
|
||||
ship.Inventory.Values.Sum();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user