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:
@@ -4,208 +4,208 @@ namespace SpaceGame.Api.Stations.Simulation;
|
||||
|
||||
internal sealed class StationLifecycleService
|
||||
{
|
||||
private const float WaterConsumptionPerWorkerPerSecond = 0.004f;
|
||||
private const float PopulationGrowthPerSecond = 0.012f;
|
||||
private const float PopulationAttritionPerSecond = 0.018f;
|
||||
private readonly StationSimulationService _stationSimulation;
|
||||
private const float WaterConsumptionPerWorkerPerSecond = 0.004f;
|
||||
private const float PopulationGrowthPerSecond = 0.012f;
|
||||
private const float PopulationAttritionPerSecond = 0.018f;
|
||||
private readonly StationSimulationService _stationSimulation;
|
||||
|
||||
internal StationLifecycleService(StationSimulationService stationSimulation)
|
||||
{
|
||||
_stationSimulation = stationSimulation;
|
||||
}
|
||||
|
||||
internal void UpdateStations(SimulationWorld world, float deltaSeconds, ICollection<SimulationEventRecord> events)
|
||||
{
|
||||
var factionPopulation = new Dictionary<string, float>(StringComparer.Ordinal);
|
||||
foreach (var station in world.Stations)
|
||||
internal StationLifecycleService(StationSimulationService stationSimulation)
|
||||
{
|
||||
UpdateStationPopulation(station, deltaSeconds, events);
|
||||
_stationSimulation.ReviewStationMarketOrders(world, station);
|
||||
_stationSimulation.RunStationProduction(world, station, deltaSeconds, events);
|
||||
factionPopulation[station.FactionId] = GetInventoryAmount(factionPopulation, station.FactionId) + station.Population;
|
||||
_stationSimulation = stationSimulation;
|
||||
}
|
||||
|
||||
foreach (var faction in world.Factions)
|
||||
internal void UpdateStations(SimulationWorld world, float deltaSeconds, ICollection<SimulationEventRecord> events)
|
||||
{
|
||||
faction.PopulationTotal = GetInventoryAmount(factionPopulation, faction.Id);
|
||||
}
|
||||
}
|
||||
var factionPopulation = new Dictionary<string, float>(StringComparer.Ordinal);
|
||||
foreach (var station in world.Stations)
|
||||
{
|
||||
UpdateStationPopulation(station, deltaSeconds, events);
|
||||
_stationSimulation.ReviewStationMarketOrders(world, station);
|
||||
_stationSimulation.RunStationProduction(world, station, deltaSeconds, events);
|
||||
factionPopulation[station.FactionId] = GetInventoryAmount(factionPopulation, station.FactionId) + station.Population;
|
||||
}
|
||||
|
||||
private void UpdateStationPopulation(StationRuntime station, float deltaSeconds, ICollection<SimulationEventRecord> events)
|
||||
{
|
||||
station.WorkforceRequired = MathF.Max(12f, station.Modules.Count * 14f);
|
||||
|
||||
var requiredWater = station.Population * WaterConsumptionPerWorkerPerSecond * deltaSeconds;
|
||||
var consumedWater = RemoveInventory(station.Inventory, "water", requiredWater);
|
||||
var waterSatisfied = requiredWater <= 0.01f || consumedWater + 0.001f >= requiredWater;
|
||||
var habitatModules = CountModules(station.InstalledModules, "module_arg_hab_m_01");
|
||||
station.PopulationCapacity = 40f + (habitatModules * 220f);
|
||||
|
||||
if (waterSatisfied)
|
||||
{
|
||||
if (habitatModules > 0 && station.Population < station.PopulationCapacity)
|
||||
{
|
||||
station.Population = MathF.Min(station.PopulationCapacity, station.Population + (PopulationGrowthPerSecond * deltaSeconds));
|
||||
}
|
||||
}
|
||||
else if (station.Population > 0f)
|
||||
{
|
||||
var previous = station.Population;
|
||||
station.Population = MathF.Max(0f, station.Population - (PopulationAttritionPerSecond * deltaSeconds));
|
||||
if (MathF.Floor(previous) > MathF.Floor(station.Population))
|
||||
{
|
||||
events.Add(new SimulationEventRecord("station", station.Id, "population-loss", $"{station.Label} lost population due to support shortages.", DateTimeOffset.UtcNow));
|
||||
}
|
||||
foreach (var faction in world.Factions)
|
||||
{
|
||||
faction.PopulationTotal = GetInventoryAmount(factionPopulation, faction.Id);
|
||||
}
|
||||
}
|
||||
|
||||
station.WorkforceEffectiveRatio = ComputeWorkforceRatio(station.Population, station.WorkforceRequired);
|
||||
}
|
||||
|
||||
internal static float CompleteShipRecipe(SimulationWorld world, StationRuntime station, RecipeDefinition recipe, ICollection<SimulationEventRecord> events)
|
||||
{
|
||||
if (recipe.ShipOutputId is null || !world.ShipDefinitions.TryGetValue(recipe.ShipOutputId, out var definition))
|
||||
private void UpdateStationPopulation(StationRuntime station, float deltaSeconds, ICollection<SimulationEventRecord> events)
|
||||
{
|
||||
return 0f;
|
||||
station.WorkforceRequired = MathF.Max(12f, station.Modules.Count * 14f);
|
||||
|
||||
var requiredWater = station.Population * WaterConsumptionPerWorkerPerSecond * deltaSeconds;
|
||||
var consumedWater = RemoveInventory(station.Inventory, "water", requiredWater);
|
||||
var waterSatisfied = requiredWater <= 0.01f || consumedWater + 0.001f >= requiredWater;
|
||||
var habitatModules = CountModules(station.InstalledModules, "module_arg_hab_m_01");
|
||||
station.PopulationCapacity = 40f + (habitatModules * 220f);
|
||||
|
||||
if (waterSatisfied)
|
||||
{
|
||||
if (habitatModules > 0 && station.Population < station.PopulationCapacity)
|
||||
{
|
||||
station.Population = MathF.Min(station.PopulationCapacity, station.Population + (PopulationGrowthPerSecond * deltaSeconds));
|
||||
}
|
||||
}
|
||||
else if (station.Population > 0f)
|
||||
{
|
||||
var previous = station.Population;
|
||||
station.Population = MathF.Max(0f, station.Population - (PopulationAttritionPerSecond * deltaSeconds));
|
||||
if (MathF.Floor(previous) > MathF.Floor(station.Population))
|
||||
{
|
||||
events.Add(new SimulationEventRecord("station", station.Id, "population-loss", $"{station.Label} lost population due to support shortages.", DateTimeOffset.UtcNow));
|
||||
}
|
||||
}
|
||||
|
||||
station.WorkforceEffectiveRatio = ComputeWorkforceRatio(station.Population, station.WorkforceRequired);
|
||||
}
|
||||
|
||||
var spawnPosition = new Vector3(station.Position.X + GetStationRadius(world, station) + 32f, station.Position.Y, station.Position.Z);
|
||||
var ship = new ShipRuntime
|
||||
internal static float CompleteShipRecipe(SimulationWorld world, StationRuntime station, RecipeDefinition recipe, ICollection<SimulationEventRecord> events)
|
||||
{
|
||||
Id = $"ship-{world.Ships.Count + 1}",
|
||||
SystemId = station.SystemId,
|
||||
Definition = definition,
|
||||
FactionId = station.FactionId,
|
||||
Position = spawnPosition,
|
||||
TargetPosition = spawnPosition,
|
||||
SpatialState = CreateSpawnedShipSpatialState(station, spawnPosition),
|
||||
DefaultBehavior = CreateSpawnedShipBehavior(definition, station),
|
||||
Skills = WorldSeedingService.CreateSkills(definition),
|
||||
Health = definition.MaxHealth,
|
||||
if (recipe.ShipOutputId is null || !world.ShipDefinitions.TryGetValue(recipe.ShipOutputId, out var definition))
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
var spawnPosition = new Vector3(station.Position.X + GetStationRadius(world, station) + 32f, station.Position.Y, station.Position.Z);
|
||||
var ship = new ShipRuntime
|
||||
{
|
||||
Id = $"ship-{world.Ships.Count + 1}",
|
||||
SystemId = station.SystemId,
|
||||
Definition = definition,
|
||||
FactionId = station.FactionId,
|
||||
Position = spawnPosition,
|
||||
TargetPosition = spawnPosition,
|
||||
SpatialState = CreateSpawnedShipSpatialState(station, spawnPosition),
|
||||
DefaultBehavior = CreateSpawnedShipBehavior(definition, station),
|
||||
Skills = WorldSeedingService.CreateSkills(definition),
|
||||
Health = definition.MaxHealth,
|
||||
};
|
||||
|
||||
world.Ships.Add(ship);
|
||||
EnsureSpawnedShipCommander(world, station, ship);
|
||||
if (world.Factions.FirstOrDefault(candidate => candidate.Id == station.FactionId) is { } faction)
|
||||
{
|
||||
faction.ShipsBuilt += 1;
|
||||
}
|
||||
|
||||
events.Add(new SimulationEventRecord("station", station.Id, "ship-built", $"{station.Label} launched {definition.Label}.", DateTimeOffset.UtcNow));
|
||||
return 1f;
|
||||
}
|
||||
|
||||
private static ShipSpatialStateRuntime CreateSpawnedShipSpatialState(StationRuntime station, Vector3 position) => new()
|
||||
{
|
||||
CurrentSystemId = station.SystemId,
|
||||
SpaceLayer = SpaceLayerKinds.LocalSpace,
|
||||
CurrentCelestialId = station.CelestialId,
|
||||
LocalPosition = position,
|
||||
SystemPosition = position,
|
||||
MovementRegime = MovementRegimeKinds.LocalFlight,
|
||||
};
|
||||
|
||||
world.Ships.Add(ship);
|
||||
EnsureSpawnedShipCommander(world, station, ship);
|
||||
if (world.Factions.FirstOrDefault(candidate => candidate.Id == station.FactionId) is { } faction)
|
||||
private static DefaultBehaviorRuntime CreateSpawnedShipBehavior(ShipDefinition definition, StationRuntime station)
|
||||
{
|
||||
faction.ShipsBuilt += 1;
|
||||
}
|
||||
if (!string.Equals(definition.Kind, "military", StringComparison.Ordinal))
|
||||
{
|
||||
return new DefaultBehaviorRuntime
|
||||
{
|
||||
Kind = string.Equals(definition.Kind, "transport", StringComparison.Ordinal) ? "advanced-auto-trade" : "idle",
|
||||
HomeSystemId = station.SystemId,
|
||||
HomeStationId = station.Id,
|
||||
MaxSystemRange = string.Equals(definition.Kind, "transport", StringComparison.Ordinal) ? 2 : 0,
|
||||
};
|
||||
}
|
||||
|
||||
events.Add(new SimulationEventRecord("station", station.Id, "ship-built", $"{station.Label} launched {definition.Label}.", DateTimeOffset.UtcNow));
|
||||
return 1f;
|
||||
}
|
||||
|
||||
private static ShipSpatialStateRuntime CreateSpawnedShipSpatialState(StationRuntime station, Vector3 position) => new()
|
||||
{
|
||||
CurrentSystemId = station.SystemId,
|
||||
SpaceLayer = SpaceLayerKinds.LocalSpace,
|
||||
CurrentCelestialId = station.CelestialId,
|
||||
LocalPosition = position,
|
||||
SystemPosition = position,
|
||||
MovementRegime = MovementRegimeKinds.LocalFlight,
|
||||
};
|
||||
|
||||
private static DefaultBehaviorRuntime CreateSpawnedShipBehavior(ShipDefinition definition, StationRuntime station)
|
||||
{
|
||||
if (!string.Equals(definition.Kind, "military", StringComparison.Ordinal))
|
||||
{
|
||||
return new DefaultBehaviorRuntime
|
||||
{
|
||||
Kind = string.Equals(definition.Kind, "transport", StringComparison.Ordinal) ? "advanced-auto-trade" : "idle",
|
||||
HomeSystemId = station.SystemId,
|
||||
HomeStationId = station.Id,
|
||||
MaxSystemRange = string.Equals(definition.Kind, "transport", StringComparison.Ordinal) ? 2 : 0,
|
||||
};
|
||||
}
|
||||
|
||||
var patrolRadius = station.Radius + 90f;
|
||||
return new DefaultBehaviorRuntime
|
||||
{
|
||||
Kind = "patrol",
|
||||
HomeSystemId = station.SystemId,
|
||||
HomeStationId = station.Id,
|
||||
AreaSystemId = station.SystemId,
|
||||
PatrolPoints =
|
||||
[
|
||||
new Vector3(station.Position.X + patrolRadius, station.Position.Y, station.Position.Z),
|
||||
var patrolRadius = station.Radius + 90f;
|
||||
return new DefaultBehaviorRuntime
|
||||
{
|
||||
Kind = "patrol",
|
||||
HomeSystemId = station.SystemId,
|
||||
HomeStationId = station.Id,
|
||||
AreaSystemId = station.SystemId,
|
||||
PatrolPoints =
|
||||
[
|
||||
new Vector3(station.Position.X + patrolRadius, station.Position.Y, station.Position.Z),
|
||||
new Vector3(station.Position.X, station.Position.Y, station.Position.Z + patrolRadius),
|
||||
new Vector3(station.Position.X - patrolRadius, station.Position.Y, station.Position.Z),
|
||||
new Vector3(station.Position.X, station.Position.Y, station.Position.Z - patrolRadius),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
internal static void EnsureStationCommander(SimulationWorld world, StationRuntime station)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(station.CommanderId))
|
||||
{
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
var factionCommander = world.Commanders.FirstOrDefault(candidate =>
|
||||
string.Equals(candidate.Kind, CommanderKind.Faction, StringComparison.Ordinal)
|
||||
&& string.Equals(candidate.FactionId, station.FactionId, StringComparison.Ordinal));
|
||||
var faction = world.Factions.FirstOrDefault(candidate => string.Equals(candidate.Id, station.FactionId, StringComparison.Ordinal));
|
||||
if (factionCommander is null || faction is null)
|
||||
internal static void EnsureStationCommander(SimulationWorld world, StationRuntime station)
|
||||
{
|
||||
return;
|
||||
if (!string.IsNullOrWhiteSpace(station.CommanderId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var factionCommander = world.Commanders.FirstOrDefault(candidate =>
|
||||
string.Equals(candidate.Kind, CommanderKind.Faction, StringComparison.Ordinal)
|
||||
&& string.Equals(candidate.FactionId, station.FactionId, StringComparison.Ordinal));
|
||||
var faction = world.Factions.FirstOrDefault(candidate => string.Equals(candidate.Id, station.FactionId, StringComparison.Ordinal));
|
||||
if (factionCommander is null || faction is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var commander = new CommanderRuntime
|
||||
{
|
||||
Id = $"commander-station-{station.Id}",
|
||||
Kind = CommanderKind.Station,
|
||||
FactionId = station.FactionId,
|
||||
ParentCommanderId = factionCommander.Id,
|
||||
ControlledEntityId = station.Id,
|
||||
PolicySetId = factionCommander.PolicySetId,
|
||||
Doctrine = "station-control",
|
||||
Skills = new CommanderSkillProfileRuntime
|
||||
{
|
||||
Leadership = 3,
|
||||
Coordination = Math.Clamp(3 + (station.Modules.Count / 8), 3, 5),
|
||||
Strategy = 3,
|
||||
},
|
||||
};
|
||||
|
||||
station.CommanderId = commander.Id;
|
||||
station.PolicySetId = factionCommander.PolicySetId;
|
||||
factionCommander.SubordinateCommanderIds.Add(commander.Id);
|
||||
faction.CommanderIds.Add(commander.Id);
|
||||
world.Commanders.Add(commander);
|
||||
}
|
||||
|
||||
var commander = new CommanderRuntime
|
||||
private static void EnsureSpawnedShipCommander(SimulationWorld world, StationRuntime station, ShipRuntime ship)
|
||||
{
|
||||
Id = $"commander-station-{station.Id}",
|
||||
Kind = CommanderKind.Station,
|
||||
FactionId = station.FactionId,
|
||||
ParentCommanderId = factionCommander.Id,
|
||||
ControlledEntityId = station.Id,
|
||||
PolicySetId = factionCommander.PolicySetId,
|
||||
Doctrine = "station-control",
|
||||
Skills = new CommanderSkillProfileRuntime
|
||||
{
|
||||
Leadership = 3,
|
||||
Coordination = Math.Clamp(3 + (station.Modules.Count / 8), 3, 5),
|
||||
Strategy = 3,
|
||||
},
|
||||
};
|
||||
var factionCommander = world.Commanders.FirstOrDefault(candidate =>
|
||||
string.Equals(candidate.Kind, CommanderKind.Faction, StringComparison.Ordinal)
|
||||
&& string.Equals(candidate.FactionId, station.FactionId, StringComparison.Ordinal));
|
||||
var faction = world.Factions.FirstOrDefault(candidate => string.Equals(candidate.Id, station.FactionId, StringComparison.Ordinal));
|
||||
if (factionCommander is null || faction is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
station.CommanderId = commander.Id;
|
||||
station.PolicySetId = factionCommander.PolicySetId;
|
||||
factionCommander.SubordinateCommanderIds.Add(commander.Id);
|
||||
faction.CommanderIds.Add(commander.Id);
|
||||
world.Commanders.Add(commander);
|
||||
}
|
||||
var commander = new CommanderRuntime
|
||||
{
|
||||
Id = $"commander-ship-{ship.Id}",
|
||||
Kind = CommanderKind.Ship,
|
||||
FactionId = ship.FactionId,
|
||||
ParentCommanderId = factionCommander.Id,
|
||||
ControlledEntityId = ship.Id,
|
||||
PolicySetId = factionCommander.PolicySetId,
|
||||
Doctrine = "ship-control",
|
||||
Skills = new CommanderSkillProfileRuntime
|
||||
{
|
||||
Leadership = Math.Clamp((ship.Skills.Navigation + ship.Skills.Combat + 1) / 2, 2, 5),
|
||||
Coordination = Math.Clamp((ship.Skills.Trade + ship.Skills.Mining + 1) / 2, 2, 5),
|
||||
Strategy = Math.Clamp((ship.Skills.Combat + ship.Skills.Construction + 1) / 2, 2, 5),
|
||||
},
|
||||
};
|
||||
|
||||
private static void EnsureSpawnedShipCommander(SimulationWorld world, StationRuntime station, ShipRuntime ship)
|
||||
{
|
||||
var factionCommander = world.Commanders.FirstOrDefault(candidate =>
|
||||
string.Equals(candidate.Kind, CommanderKind.Faction, StringComparison.Ordinal)
|
||||
&& string.Equals(candidate.FactionId, station.FactionId, StringComparison.Ordinal));
|
||||
var faction = world.Factions.FirstOrDefault(candidate => string.Equals(candidate.Id, station.FactionId, StringComparison.Ordinal));
|
||||
if (factionCommander is null || faction is null)
|
||||
{
|
||||
return;
|
||||
ship.CommanderId = commander.Id;
|
||||
ship.PolicySetId = factionCommander.PolicySetId;
|
||||
factionCommander.SubordinateCommanderIds.Add(commander.Id);
|
||||
faction.CommanderIds.Add(commander.Id);
|
||||
world.Commanders.Add(commander);
|
||||
}
|
||||
|
||||
var commander = new CommanderRuntime
|
||||
{
|
||||
Id = $"commander-ship-{ship.Id}",
|
||||
Kind = CommanderKind.Ship,
|
||||
FactionId = ship.FactionId,
|
||||
ParentCommanderId = factionCommander.Id,
|
||||
ControlledEntityId = ship.Id,
|
||||
PolicySetId = factionCommander.PolicySetId,
|
||||
Doctrine = "ship-control",
|
||||
Skills = new CommanderSkillProfileRuntime
|
||||
{
|
||||
Leadership = Math.Clamp((ship.Skills.Navigation + ship.Skills.Combat + 1) / 2, 2, 5),
|
||||
Coordination = Math.Clamp((ship.Skills.Trade + ship.Skills.Mining + 1) / 2, 2, 5),
|
||||
Strategy = Math.Clamp((ship.Skills.Combat + ship.Skills.Construction + 1) / 2, 2, 5),
|
||||
},
|
||||
};
|
||||
|
||||
ship.CommanderId = commander.Id;
|
||||
ship.PolicySetId = factionCommander.PolicySetId;
|
||||
factionCommander.SubordinateCommanderIds.Add(commander.Id);
|
||||
faction.CommanderIds.Add(commander.Id);
|
||||
world.Commanders.Add(commander);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user