feat: production chain
This commit is contained in:
@@ -21,7 +21,12 @@ public sealed partial class ScenarioLoader
|
||||
factionIds.Add(DefaultFactionId);
|
||||
}
|
||||
|
||||
return factionIds.Select(CreateFaction).ToList();
|
||||
factionIds.Add(UnclaimedFactionId);
|
||||
|
||||
return factionIds
|
||||
.Distinct(StringComparer.Ordinal)
|
||||
.Select(CreateFaction)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static FactionRuntime CreateFaction(string factionId)
|
||||
@@ -35,6 +40,13 @@ public sealed partial class ScenarioLoader
|
||||
Color = "#7ed4ff",
|
||||
Credits = MinimumFactionCredits,
|
||||
},
|
||||
UnclaimedFactionId => new FactionRuntime
|
||||
{
|
||||
Id = factionId,
|
||||
Label = "Unclaimed",
|
||||
Color = "#7f8794",
|
||||
Credits = 0f,
|
||||
},
|
||||
_ => new FactionRuntime
|
||||
{
|
||||
Id = factionId,
|
||||
@@ -89,30 +101,32 @@ public sealed partial class ScenarioLoader
|
||||
IReadOnlyCollection<NodeRuntime> nodes,
|
||||
DateTimeOffset nowUtc)
|
||||
{
|
||||
var claims = new List<ClaimRuntime>(stations.Count);
|
||||
foreach (var station in stations)
|
||||
var stationsByAnchorNodeId = stations
|
||||
.Where((station) => station.AnchorNodeId is not null)
|
||||
.ToDictionary((station) => station.AnchorNodeId!, StringComparer.Ordinal);
|
||||
var claims = new List<ClaimRuntime>();
|
||||
foreach (var node in nodes.Where((candidate) => candidate.Kind == SpatialNodeKind.LagrangePoint))
|
||||
{
|
||||
if (station.AnchorNodeId is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var anchorNode = nodes.FirstOrDefault((node) => node.Id == station.AnchorNodeId);
|
||||
if (anchorNode is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var owningFactionId = stationsByAnchorNodeId.TryGetValue(node.Id, out var station)
|
||||
? station.FactionId
|
||||
: UnclaimedFactionId;
|
||||
var activatesAtUtc = owningFactionId == UnclaimedFactionId
|
||||
? nowUtc
|
||||
: nowUtc.AddSeconds(8);
|
||||
var state = owningFactionId == UnclaimedFactionId
|
||||
? ClaimStateKinds.Active
|
||||
: ClaimStateKinds.Activating;
|
||||
|
||||
claims.Add(new ClaimRuntime
|
||||
{
|
||||
Id = $"claim-{station.Id}",
|
||||
FactionId = station.FactionId,
|
||||
SystemId = station.SystemId,
|
||||
NodeId = anchorNode.Id,
|
||||
BubbleId = anchorNode.BubbleId,
|
||||
Id = $"claim-{node.Id}",
|
||||
FactionId = owningFactionId,
|
||||
SystemId = node.SystemId,
|
||||
NodeId = node.Id,
|
||||
BubbleId = node.BubbleId,
|
||||
PlacedAtUtc = nowUtc,
|
||||
ActivatesAtUtc = nowUtc.AddSeconds(8),
|
||||
State = ClaimStateKinds.Activating,
|
||||
ActivatesAtUtc = activatesAtUtc,
|
||||
State = state,
|
||||
Health = 100f,
|
||||
});
|
||||
}
|
||||
@@ -138,8 +152,13 @@ public sealed partial class ScenarioLoader
|
||||
}
|
||||
|
||||
var anchorNode = nodes.FirstOrDefault((node) => node.Id == station.AnchorNodeId);
|
||||
var claim = claims.FirstOrDefault((candidate) => candidate.Id == $"claim-{station.Id}");
|
||||
if (anchorNode is null || claim is null || !moduleRecipes.TryGetValue(moduleId, out var recipe))
|
||||
if (anchorNode is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var claim = claims.FirstOrDefault((candidate) => candidate.NodeId == anchorNode.Id);
|
||||
if (claim is null || !moduleRecipes.TryGetValue(moduleId, out var recipe))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -192,9 +211,20 @@ public sealed partial class ScenarioLoader
|
||||
StationRuntime station,
|
||||
IReadOnlyDictionary<string, ModuleRecipeDefinition> moduleRecipes)
|
||||
{
|
||||
foreach (var moduleId in new[] { "gas-tank", "fuel-processor", "refinery-stack", "dock-bay-small" })
|
||||
foreach (var (moduleId, targetCount) in new (string ModuleId, int TargetCount)[]
|
||||
{
|
||||
if (!station.InstalledModules.Contains(moduleId, StringComparer.Ordinal)
|
||||
("gas-tank", 1),
|
||||
("fuel-processor", 1),
|
||||
("refinery-stack", 1),
|
||||
("container-bay", 1),
|
||||
("fabricator-array", 2),
|
||||
("component-factory", 1),
|
||||
("ship-factory", 1),
|
||||
("solar-array", 2),
|
||||
("dock-bay-small", 2),
|
||||
})
|
||||
{
|
||||
if (CountModules(station.InstalledModules, moduleId) < targetCount
|
||||
&& moduleRecipes.ContainsKey(moduleId))
|
||||
{
|
||||
return moduleId;
|
||||
@@ -220,6 +250,11 @@ public sealed partial class ScenarioLoader
|
||||
var policies = new List<PolicySetRuntime>(factions.Count);
|
||||
foreach (var faction in factions)
|
||||
{
|
||||
if (string.Equals(faction.Id, UnclaimedFactionId, StringComparison.Ordinal))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var policyId = $"policy-{faction.Id}";
|
||||
faction.DefaultPolicySetId = policyId;
|
||||
policies.Add(new PolicySetRuntime
|
||||
@@ -244,6 +279,11 @@ public sealed partial class ScenarioLoader
|
||||
|
||||
foreach (var faction in factions)
|
||||
{
|
||||
if (string.Equals(faction.Id, UnclaimedFactionId, StringComparison.Ordinal))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var commander = new CommanderRuntime
|
||||
{
|
||||
Id = $"commander-faction-{faction.Id}",
|
||||
@@ -251,9 +291,16 @@ public sealed partial class ScenarioLoader
|
||||
FactionId = faction.Id,
|
||||
ControlledEntityId = faction.Id,
|
||||
PolicySetId = faction.DefaultPolicySetId,
|
||||
Doctrine = "strategic-default",
|
||||
Doctrine = "strategic-expansionist",
|
||||
};
|
||||
|
||||
commander.Goals.Add("control-all-systems");
|
||||
commander.Goals.Add("control-five-systems-fast");
|
||||
commander.Goals.Add("expand-industrial-base");
|
||||
commander.Goals.Add("grow-war-fleet");
|
||||
commander.Goals.Add("deter-pirate-harassment");
|
||||
commander.Goals.Add("contest-rival-expansion");
|
||||
|
||||
commanders.Add(commander);
|
||||
factionCommanders[faction.Id] = commander;
|
||||
faction.CommanderIds.Add(commander.Id);
|
||||
@@ -334,7 +381,7 @@ public sealed partial class ScenarioLoader
|
||||
IReadOnlyDictionary<string, List<Vector3>> patrolRoutes,
|
||||
StationRuntime? refinery)
|
||||
{
|
||||
if (HasModules(definition, "fabricator-array", "docking-clamps") && refinery is not null)
|
||||
if (string.Equals(definition.Role, "construction", StringComparison.Ordinal) && refinery is not null)
|
||||
{
|
||||
return new DefaultBehaviorRuntime
|
||||
{
|
||||
@@ -345,24 +392,23 @@ public sealed partial class ScenarioLoader
|
||||
}
|
||||
|
||||
if (HasModules(definition, "reactor-core", "capacitor-bank", "gas-extractor") && refinery is not null)
|
||||
{
|
||||
return CreateResourceHarvestBehavior("auto-harvest-gas", scenario.MiningDefaults.NodeSystemId, refinery.Id);
|
||||
}
|
||||
|
||||
if (string.Equals(definition.Role, "transport", StringComparison.Ordinal) && refinery is not null)
|
||||
{
|
||||
return new DefaultBehaviorRuntime
|
||||
{
|
||||
Kind = "auto-harvest-gas",
|
||||
Kind = "auto-supply-energy",
|
||||
StationId = refinery.Id,
|
||||
Phase = "travel-to-node",
|
||||
Phase = "travel-to-source",
|
||||
};
|
||||
}
|
||||
|
||||
if (HasModules(definition, "reactor-core", "capacitor-bank", "mining-turret") && refinery is not null)
|
||||
{
|
||||
return new DefaultBehaviorRuntime
|
||||
{
|
||||
Kind = "auto-mine",
|
||||
AreaSystemId = scenario.MiningDefaults.NodeSystemId,
|
||||
StationId = refinery.Id,
|
||||
Phase = "travel-to-node",
|
||||
};
|
||||
return CreateResourceHarvestBehavior("auto-mine", scenario.MiningDefaults.NodeSystemId, refinery.Id);
|
||||
}
|
||||
|
||||
if (HasModules(definition, "reactor-core", "capacitor-bank", "gun-turret") && patrolRoutes.TryGetValue(systemId, out var route))
|
||||
@@ -381,6 +427,14 @@ public sealed partial class ScenarioLoader
|
||||
};
|
||||
}
|
||||
|
||||
private static DefaultBehaviorRuntime CreateResourceHarvestBehavior(string kind, string areaSystemId, string stationId) => new()
|
||||
{
|
||||
Kind = kind,
|
||||
AreaSystemId = areaSystemId,
|
||||
StationId = stationId,
|
||||
Phase = "travel-to-node",
|
||||
};
|
||||
|
||||
private static CommanderBehaviorRuntime CopyBehavior(DefaultBehaviorRuntime behavior) => new()
|
||||
{
|
||||
Kind = behavior.Kind,
|
||||
@@ -402,7 +456,7 @@ public sealed partial class ScenarioLoader
|
||||
|
||||
private static CommanderTaskRuntime CopyTask(ControllerTaskRuntime task, string? targetNodeId) => new()
|
||||
{
|
||||
Kind = task.Kind,
|
||||
Kind = task.Kind.ToContractValue(),
|
||||
Status = task.Status,
|
||||
TargetEntityId = task.TargetEntityId,
|
||||
TargetNodeId = targetNodeId ?? task.TargetNodeId,
|
||||
|
||||
Reference in New Issue
Block a user