112 lines
3.8 KiB
C#
112 lines
3.8 KiB
C#
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}'.");
|
|
}
|
|
}
|
|
}
|