Adds an `.editorconfig` file with C# and project-specific conventions. Applies consistent indentation and formatting across backend handlers, runtime models, and AI services.
106 lines
4.1 KiB
C#
106 lines
4.1 KiB
C#
namespace SpaceGame.Api.Industry.Planning;
|
|
|
|
internal static class ProductionGraphBuilder
|
|
{
|
|
internal static ProductionGraph Build(
|
|
IReadOnlyCollection<ItemDefinition> items,
|
|
IReadOnlyCollection<RecipeDefinition> recipes,
|
|
IReadOnlyCollection<ModuleDefinition> modules)
|
|
{
|
|
var commodities = items.ToDictionary(
|
|
item => item.Id,
|
|
item => new ProductionCommodityNode
|
|
{
|
|
ItemId = item.Id,
|
|
Name = item.Name,
|
|
Group = item.Group,
|
|
CargoKind = item.CargoKind,
|
|
},
|
|
StringComparer.Ordinal);
|
|
|
|
var processes = new Dictionary<string, ProductionProcessNode>(StringComparer.Ordinal);
|
|
var processesByOutputId = new Dictionary<string, List<ProductionProcessNode>>(StringComparer.Ordinal);
|
|
var processesByInputId = new Dictionary<string, List<ProductionProcessNode>>(StringComparer.Ordinal);
|
|
var outputsByModuleId = new Dictionary<string, HashSet<string>>(StringComparer.Ordinal);
|
|
|
|
foreach (var recipe in recipes)
|
|
{
|
|
var outputs = recipe.Outputs
|
|
.GroupBy(output => output.ItemId, StringComparer.Ordinal)
|
|
.ToDictionary(group => group.Key, group => group.Sum(output => output.Amount), StringComparer.Ordinal);
|
|
var inputs = recipe.Inputs
|
|
.GroupBy(input => input.ItemId, StringComparer.Ordinal)
|
|
.ToDictionary(group => group.Key, group => group.Sum(input => input.Amount), StringComparer.Ordinal);
|
|
var process = new ProductionProcessNode
|
|
{
|
|
Id = recipe.Id,
|
|
Label = recipe.Label,
|
|
FacilityCategory = recipe.FacilityCategory,
|
|
RequiredModuleIds = recipe.RequiredModules.ToList(),
|
|
Inputs = inputs,
|
|
Outputs = outputs,
|
|
ProducesShip = recipe.ShipOutputId is not null,
|
|
};
|
|
|
|
processes[process.Id] = process;
|
|
|
|
foreach (var output in outputs.Keys)
|
|
{
|
|
if (!commodities.ContainsKey(output))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
commodities[output].ProducerProcessIds.Add(process.Id);
|
|
if (!processesByOutputId.TryGetValue(output, out var outputProcesses))
|
|
{
|
|
outputProcesses = [];
|
|
processesByOutputId[output] = outputProcesses;
|
|
}
|
|
|
|
outputProcesses.Add(process);
|
|
}
|
|
|
|
foreach (var input in inputs.Keys)
|
|
{
|
|
if (!commodities.ContainsKey(input))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
commodities[input].ConsumerProcessIds.Add(process.Id);
|
|
if (!processesByInputId.TryGetValue(input, out var inputProcesses))
|
|
{
|
|
inputProcesses = [];
|
|
processesByInputId[input] = inputProcesses;
|
|
}
|
|
|
|
inputProcesses.Add(process);
|
|
}
|
|
}
|
|
|
|
foreach (var module in modules)
|
|
{
|
|
if (!outputsByModuleId.TryGetValue(module.Id, out var outputs))
|
|
{
|
|
outputs = new HashSet<string>(StringComparer.Ordinal);
|
|
outputsByModuleId[module.Id] = outputs;
|
|
}
|
|
|
|
foreach (var product in module.Products)
|
|
{
|
|
outputs.Add(product);
|
|
}
|
|
}
|
|
|
|
return new ProductionGraph
|
|
{
|
|
Commodities = commodities,
|
|
Processes = processes,
|
|
ProcessesByOutputId = processesByOutputId.ToDictionary(entry => entry.Key, entry => (IReadOnlyList<ProductionProcessNode>)entry.Value, StringComparer.Ordinal),
|
|
ProcessesByInputId = processesByInputId.ToDictionary(entry => entry.Key, entry => (IReadOnlyList<ProductionProcessNode>)entry.Value, StringComparer.Ordinal),
|
|
OutputsByModuleId = outputsByModuleId.ToDictionary(entry => entry.Key, entry => (IReadOnlyList<string>)entry.Value.OrderBy(value => value, StringComparer.Ordinal).ToList(), StringComparer.Ordinal),
|
|
};
|
|
}
|
|
}
|