refactor(backend): align station module production semantics
This commit is contained in:
@@ -103,12 +103,12 @@ internal sealed class DataCatalogLoader(string dataRoot)
|
||||
|
||||
private static List<ModuleRecipeDefinition> BuildModuleRecipes(IEnumerable<ModuleDefinition> modules) =>
|
||||
modules
|
||||
.Where(module => module.Construction is not null || module.Production.Count > 0)
|
||||
.Where(module => module.BuildRecipes.Count > 0)
|
||||
.Select(module => new ModuleRecipeDefinition
|
||||
{
|
||||
ModuleId = module.Id,
|
||||
Duration = module.Construction?.ProductionTime ?? module.Production[0].Time,
|
||||
Inputs = (module.Construction?.Requirements ?? module.Production[0].Wares)
|
||||
Duration = module.BuildRecipes[0].Time,
|
||||
Inputs = module.BuildRecipes[0].Wares
|
||||
.Select(input => new RecipeInputDefinition
|
||||
{
|
||||
ItemId = input.ItemId,
|
||||
@@ -122,8 +122,8 @@ internal sealed class DataCatalogLoader(string dataRoot)
|
||||
{
|
||||
var recipes = new List<RecipeDefinition>();
|
||||
var preferredProducerByItemId = modules
|
||||
.Where(module => module.Products.Count > 0)
|
||||
.GroupBy(module => module.Products[0], StringComparer.Ordinal)
|
||||
.Where(module => module.ProductItemIds.Count > 0)
|
||||
.GroupBy(module => module.ProductItemIds[0], StringComparer.Ordinal)
|
||||
.ToDictionary(
|
||||
group => group.Key,
|
||||
group => group.OrderBy(module => module.Id, StringComparer.Ordinal).First().Id,
|
||||
@@ -271,23 +271,6 @@ internal sealed class DataCatalogLoader(string dataRoot)
|
||||
|
||||
module.Type = module.ModuleType.ToDataValue();
|
||||
|
||||
if (module.Products.Count == 0 && !string.IsNullOrWhiteSpace(module.Product))
|
||||
{
|
||||
module.Products = [module.Product];
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(module.ProductionMode))
|
||||
{
|
||||
module.ProductionMode = module.ModuleType == ModuleType.BuildModule
|
||||
? "commanded"
|
||||
: "passive";
|
||||
}
|
||||
|
||||
if (module.WorkforceNeeded <= 0f)
|
||||
{
|
||||
module.WorkforceNeeded = module.WorkForce?.Max ?? 0f;
|
||||
}
|
||||
|
||||
modules[index] = CreateSpecializedModuleDefinition(module);
|
||||
}
|
||||
|
||||
@@ -313,9 +296,19 @@ internal sealed class DataCatalogLoader(string dataRoot)
|
||||
}
|
||||
}
|
||||
|
||||
if (module.Products.Count > 0)
|
||||
if (module.ModuleType == ModuleType.Habitation)
|
||||
{
|
||||
return new ProductionModuleDefinition(module);
|
||||
return new HabitationModuleDefinition(module, module.SerializedWorkforce?.SupportedPopulation ?? 0f);
|
||||
}
|
||||
|
||||
if (module.ModuleType == ModuleType.BuildModule)
|
||||
{
|
||||
return new BuildModuleDefinition(module, module.SerializedWorkforce?.RequiredWorkforce ?? 0f);
|
||||
}
|
||||
|
||||
if (module.ModuleType == ModuleType.Production)
|
||||
{
|
||||
return new ProductionModuleDefinition(module, module.SerializedWorkforce?.RequiredWorkforce ?? 0f);
|
||||
}
|
||||
|
||||
return module;
|
||||
|
||||
@@ -38,7 +38,7 @@ internal sealed class WorldBuilder(
|
||||
catalog.ModuleDefinitions,
|
||||
catalog.ItemDefinitions);
|
||||
|
||||
seedingService.InitializeStationStockpiles(stations);
|
||||
seedingService.InitializeStationStockpiles(stations, catalog.ModuleDefinitions);
|
||||
var refinery = seedingService.SelectRefineryStation(stations, scenario);
|
||||
var patrolRoutes = BuildPatrolRoutes(scenario, systemsById);
|
||||
var ships = CreateShips(scenario, systemsById, spatialLayout.Celestials, catalog.Balance, catalog.ShipDefinitions, patrolRoutes, stations, refinery);
|
||||
@@ -208,9 +208,9 @@ internal sealed class WorldBuilder(
|
||||
yield break;
|
||||
}
|
||||
|
||||
foreach (var wareId in moduleDefinition.Production
|
||||
foreach (var wareId in moduleDefinition.BuildRecipes
|
||||
.SelectMany(production => production.Wares.Select(ware => ware.ItemId))
|
||||
.Concat(moduleDefinition.Products)
|
||||
.Concat(moduleDefinition.ProductItemIds)
|
||||
.Distinct(StringComparer.Ordinal))
|
||||
{
|
||||
if (!itemDefinitions.TryGetValue(wareId, out var itemDefinition))
|
||||
|
||||
@@ -60,11 +60,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)
|
||||
{
|
||||
InitializeStationPopulation(station);
|
||||
InitializeStationPopulation(station, moduleDefinitions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,9 +233,9 @@ internal sealed class WorldSeedingService
|
||||
yield break;
|
||||
}
|
||||
|
||||
foreach (var wareId in moduleDefinition.Production
|
||||
foreach (var wareId in moduleDefinition.BuildRecipes
|
||||
.SelectMany(production => production.Wares.Select(ware => ware.ItemId))
|
||||
.Concat(moduleDefinition.Products)
|
||||
.Concat(moduleDefinition.ProductItemIds)
|
||||
.Distinct(StringComparer.Ordinal))
|
||||
{
|
||||
if (!world.ItemDefinitions.TryGetValue(wareId, out var itemDefinition))
|
||||
@@ -549,12 +551,13 @@ internal sealed class WorldSeedingService
|
||||
};
|
||||
}
|
||||
|
||||
private static void InitializeStationPopulation(StationRuntime station)
|
||||
private static void InitializeStationPopulation(
|
||||
StationRuntime station,
|
||||
IReadOnlyDictionary<string, ModuleDefinition> moduleDefinitions)
|
||||
{
|
||||
var habitatModules = station.Modules.Count(module => module.ModuleType == ModuleType.Habitation);
|
||||
station.PopulationCapacity = 40f + (habitatModules * 220f);
|
||||
station.WorkforceRequired = MathF.Max(12f, station.Modules.Count * 14f);
|
||||
station.Population = habitatModules > 0
|
||||
station.PopulationCapacity = SpaceGame.Api.Shared.Runtime.SimulationRuntimeSupport.GetStationSupportedPopulation(moduleDefinitions, station);
|
||||
station.WorkforceRequired = SpaceGame.Api.Shared.Runtime.SimulationRuntimeSupport.GetStationRequiredWorkforce(moduleDefinitions, station);
|
||||
station.Population = station.PopulationCapacity > 40f
|
||||
? MathF.Min(station.PopulationCapacity * 0.65f, station.WorkforceRequired * 1.05f)
|
||||
: MathF.Min(28f, station.PopulationCapacity);
|
||||
station.WorkforceEffectiveRatio = ComputeWorkforceRatio(station.Population, station.WorkforceRequired);
|
||||
|
||||
Reference in New Issue
Block a user