Refactor world bootstrap and allow empty startup worlds
This commit is contained in:
111
apps/backend/Universe/Scenario/ScenarioValidationService.cs
Normal file
111
apps/backend/Universe/Scenario/ScenarioValidationService.cs
Normal file
@@ -0,0 +1,111 @@
|
||||
using SpaceGame.Api.Universe.Bootstrap;
|
||||
|
||||
namespace SpaceGame.Api.Universe.Scenario;
|
||||
|
||||
public sealed class ScenarioValidationService(IStaticDataProvider staticData)
|
||||
{
|
||||
public ScenarioDefinition CreateEmptyScenario(
|
||||
WorldGenerationOptions worldGenerationOptions,
|
||||
IReadOnlyList<SolarSystemDefinition> systems)
|
||||
{
|
||||
if (systems.Count == 0)
|
||||
{
|
||||
throw new InvalidOperationException("World generation produced no systems.");
|
||||
}
|
||||
|
||||
return new ScenarioDefinition
|
||||
{
|
||||
WorldGeneration = worldGenerationOptions,
|
||||
InitialStations = [],
|
||||
ShipFormations = [],
|
||||
PatrolRoutes = [],
|
||||
};
|
||||
}
|
||||
|
||||
public void Validate(
|
||||
ScenarioDefinition scenario,
|
||||
IReadOnlySet<string> availableSystemIds)
|
||||
{
|
||||
foreach (var station in scenario.InitialStations)
|
||||
{
|
||||
ValidateSystemExists(station.SystemId, $"station '{station.Label}' system", availableSystemIds);
|
||||
ValidateFactionId(station.FactionId, $"station '{station.Label}'");
|
||||
|
||||
foreach (var moduleId in station.StartingModules)
|
||||
{
|
||||
ValidateModuleId(moduleId, $"station '{station.Label}' starting module");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var formation in scenario.ShipFormations)
|
||||
{
|
||||
ValidateSystemExists(formation.SystemId, $"ship formation '{formation.ShipId}' system", availableSystemIds);
|
||||
ValidateFactionId(formation.FactionId, $"ship formation '{formation.ShipId}' in system '{formation.SystemId}'");
|
||||
ValidateShipId(formation.ShipId, $"ship formation in system '{formation.SystemId}'");
|
||||
|
||||
foreach (var itemId in formation.StartingInventory.Keys)
|
||||
{
|
||||
ValidateItemId(itemId, $"ship formation '{formation.ShipId}' starting inventory");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var route in scenario.PatrolRoutes)
|
||||
{
|
||||
ValidateSystemExists(route.SystemId, "patrol route system", availableSystemIds);
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetRequiredFactionId(string? factionId, string context)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(factionId))
|
||||
{
|
||||
return factionId;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"Scenario {context} is missing a factionId.");
|
||||
}
|
||||
|
||||
private static void ValidateSystemExists(
|
||||
string systemId,
|
||||
string context,
|
||||
IReadOnlySet<string> availableSystemIds)
|
||||
{
|
||||
if (!availableSystemIds.Contains(systemId))
|
||||
{
|
||||
throw new InvalidOperationException($"Scenario {context} references unknown generated system '{systemId}'.");
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateFactionId(string? factionId, string context)
|
||||
{
|
||||
var requiredFactionId = GetRequiredFactionId(factionId, context);
|
||||
if (!staticData.FactionDefinitions.ContainsKey(requiredFactionId))
|
||||
{
|
||||
throw new InvalidOperationException($"Scenario {context} references unknown faction '{requiredFactionId}'.");
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateModuleId(string moduleId, string context)
|
||||
{
|
||||
if (!staticData.ModuleDefinitions.ContainsKey(moduleId))
|
||||
{
|
||||
throw new InvalidOperationException($"Scenario {context} references unknown module '{moduleId}'.");
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateShipId(string shipId, string context)
|
||||
{
|
||||
if (!staticData.ShipDefinitions.ContainsKey(shipId))
|
||||
{
|
||||
throw new InvalidOperationException($"Scenario {context} references unknown ship '{shipId}'.");
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateItemId(string itemId, string context)
|
||||
{
|
||||
if (!staticData.ItemDefinitions.ContainsKey(itemId))
|
||||
{
|
||||
throw new InvalidOperationException($"Scenario {context} references unknown item '{itemId}'.");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user