improvement on gm windows, ai
This commit is contained in:
@@ -9,7 +9,7 @@ internal sealed class SystemGenerationService
|
||||
|
||||
internal List<SolarSystemDefinition> InjectSpecialSystems(IReadOnlyList<SolarSystemDefinition> authoredSystems) =>
|
||||
authoredSystems
|
||||
.Select(CloneSystemDefinition)
|
||||
.Select((system, index) => EnsureStrategicResourceCoverage(CloneSystemDefinition(system), index))
|
||||
.ToList();
|
||||
|
||||
internal List<SolarSystemDefinition> ExpandSystems(
|
||||
@@ -126,6 +126,7 @@ internal sealed class SystemGenerationService
|
||||
.Select(node => new ResourceNodeDefinition
|
||||
{
|
||||
SourceKind = node.SourceKind,
|
||||
AnchorReference = node.AnchorReference,
|
||||
Angle = node.Angle,
|
||||
RadiusOffset = node.RadiusOffset,
|
||||
InclinationDegrees = node.InclinationDegrees,
|
||||
@@ -137,7 +138,7 @@ internal sealed class SystemGenerationService
|
||||
})
|
||||
.ToList();
|
||||
|
||||
return new SolarSystemDefinition
|
||||
return EnsureStrategicResourceCoverage(new SolarSystemDefinition
|
||||
{
|
||||
Id = id,
|
||||
Label = label,
|
||||
@@ -161,7 +162,7 @@ internal sealed class SystemGenerationService
|
||||
},
|
||||
ResourceNodes = resourceNodes,
|
||||
Planets = planets,
|
||||
};
|
||||
}, generatedIndex + 1024);
|
||||
}
|
||||
|
||||
private static SolarSystemDefinition CloneSystemDefinition(SolarSystemDefinition definition)
|
||||
@@ -182,6 +183,7 @@ internal sealed class SystemGenerationService
|
||||
ResourceNodes = definition.ResourceNodes.Select(node => new ResourceNodeDefinition
|
||||
{
|
||||
SourceKind = node.SourceKind,
|
||||
AnchorReference = node.AnchorReference,
|
||||
Angle = node.Angle,
|
||||
RadiusOffset = node.RadiusOffset,
|
||||
InclinationDegrees = node.InclinationDegrees,
|
||||
@@ -223,6 +225,7 @@ internal sealed class SystemGenerationService
|
||||
nodes.AddRange(template.ResourceNodes.Select(node => new ResourceNodeDefinition
|
||||
{
|
||||
SourceKind = node.SourceKind,
|
||||
AnchorReference = node.AnchorReference,
|
||||
Angle = node.Angle,
|
||||
RadiusOffset = node.RadiusOffset,
|
||||
InclinationDegrees = node.InclinationDegrees,
|
||||
@@ -234,10 +237,30 @@ internal sealed class SystemGenerationService
|
||||
}));
|
||||
}
|
||||
|
||||
nodes.AddRange(BuildAsteroidBeltNodes(generatedIndex, planets));
|
||||
return nodes;
|
||||
}
|
||||
|
||||
private static SolarSystemDefinition EnsureStrategicResourceCoverage(SolarSystemDefinition system, int seed)
|
||||
{
|
||||
for (var index = 0; index < system.ResourceNodes.Count; index += 1)
|
||||
{
|
||||
system.ResourceNodes[index] = SanitizeResourceNode(system.ResourceNodes[index], system.Planets, seed, index);
|
||||
}
|
||||
|
||||
var requiredItems = new[] { "ore", "silicon", "ice", "hydrogen", "helium", "methane" };
|
||||
foreach (var itemId in requiredItems)
|
||||
{
|
||||
if (system.ResourceNodes.Any(node => string.Equals(node.ItemId, itemId, StringComparison.Ordinal)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
system.ResourceNodes.Add(BuildStrategicResourceNode(itemId, system.Planets, seed, system.ResourceNodes.Count));
|
||||
}
|
||||
|
||||
return system;
|
||||
}
|
||||
|
||||
private static List<Vector3> BuildGalaxyPositions(IReadOnlyCollection<Vector3> occupiedPositions, int count)
|
||||
{
|
||||
var allPositions = occupiedPositions.ToList();
|
||||
@@ -303,25 +326,124 @@ internal sealed class SystemGenerationService
|
||||
return $"gen-{ordinal}-{slug}";
|
||||
}
|
||||
|
||||
private static IEnumerable<ResourceNodeDefinition> BuildAsteroidBeltNodes(int generatedIndex, IReadOnlyList<PlanetDefinition> planets)
|
||||
private static ResourceNodeDefinition BuildStrategicResourceNode(
|
||||
string itemId,
|
||||
IReadOnlyList<PlanetDefinition> planets,
|
||||
int seed,
|
||||
int ordinal)
|
||||
{
|
||||
var nodeCount = 4 + (generatedIndex % 4);
|
||||
var oreAmount = 1000f;
|
||||
|
||||
for (var index = 0; index < nodeCount; index += 1)
|
||||
var anchorPlanetIndex = ResolveStrategicResourceAnchorPlanetIndex(itemId, planets);
|
||||
return new ResourceNodeDefinition
|
||||
{
|
||||
yield return new ResourceNodeDefinition
|
||||
SourceKind = "local-space",
|
||||
AnchorReference = ResolveStrategicAnchorReference(itemId, planets, ordinal),
|
||||
Angle = (MathF.PI * 2f * ((ordinal % 7) / 7f)) + Jitter(seed, 400 + ordinal, 0.35f),
|
||||
RadiusOffset = 150000f + Jitter(seed, 460 + ordinal, 42000f),
|
||||
InclinationDegrees = Jitter(seed, 520 + ordinal, 10f),
|
||||
AnchorPlanetIndex = anchorPlanetIndex,
|
||||
OreAmount = itemId switch
|
||||
{
|
||||
SourceKind = "asteroid-belt",
|
||||
Angle = ((MathF.PI * 2f) / nodeCount) * index + Jitter(generatedIndex, 180 + index, 0.22f),
|
||||
RadiusOffset = 120000f + Jitter(generatedIndex, 200 + index, 36000f),
|
||||
InclinationDegrees = Jitter(generatedIndex, 280 + index, 12f),
|
||||
AnchorPlanetIndex = ResolveAsteroidAnchorPlanetIndex(planets),
|
||||
OreAmount = oreAmount,
|
||||
ItemId = "ore",
|
||||
ShardCount = 6 + (index % 4),
|
||||
};
|
||||
"ore" => 12000f,
|
||||
"silicon" => 10000f,
|
||||
"ice" => 9000f,
|
||||
_ => 8000f,
|
||||
},
|
||||
ItemId = itemId,
|
||||
ShardCount = itemId switch
|
||||
{
|
||||
"ore" or "silicon" or "ice" => 8,
|
||||
_ => 6,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private static ResourceNodeDefinition SanitizeResourceNode(
|
||||
ResourceNodeDefinition node,
|
||||
IReadOnlyList<PlanetDefinition> planets,
|
||||
int seed,
|
||||
int ordinal)
|
||||
{
|
||||
node.SourceKind = "local-space";
|
||||
node.AnchorReference ??= ResolveLegacyAnchorReference(node, planets, seed, ordinal);
|
||||
return node;
|
||||
}
|
||||
|
||||
private static string ResolveLegacyAnchorReference(
|
||||
ResourceNodeDefinition node,
|
||||
IReadOnlyList<PlanetDefinition> planets,
|
||||
int seed,
|
||||
int ordinal)
|
||||
{
|
||||
if (node.AnchorMoonIndex is int moonIndex && node.AnchorPlanetIndex is int planetIndex && planetIndex >= 0)
|
||||
{
|
||||
return $"planet-{planetIndex + 1}-moon-{moonIndex + 1}";
|
||||
}
|
||||
|
||||
if (node.AnchorPlanetIndex is int anchoredPlanetIndex && anchoredPlanetIndex >= 0)
|
||||
{
|
||||
return $"planet-{anchoredPlanetIndex + 1}";
|
||||
}
|
||||
|
||||
return ResolveStrategicAnchorReference(node.ItemId, planets, ordinal + seed);
|
||||
}
|
||||
|
||||
private static string ResolveStrategicAnchorReference(string itemId, IReadOnlyList<PlanetDefinition> planets, int ordinal)
|
||||
{
|
||||
if (itemId is "hydrogen" or "helium" or "methane")
|
||||
{
|
||||
var gasGiantIndex = planets
|
||||
.Select((planet, index) => (planet, index))
|
||||
.FirstOrDefault(entry => entry.planet.PlanetType is "gas-giant" or "ice-giant")
|
||||
.index;
|
||||
return gasGiantIndex > 0 || (planets.Count > 0 && planets[0].PlanetType is "gas-giant" or "ice-giant")
|
||||
? $"planet-{gasGiantIndex + 1}"
|
||||
: "star-1";
|
||||
}
|
||||
|
||||
if (itemId == "ice")
|
||||
{
|
||||
var moonAnchor = planets
|
||||
.Select((planet, index) => (planet, index))
|
||||
.FirstOrDefault(entry => entry.planet.Moons.Count > 0 && entry.planet.PlanetType is "ice" or "ice-giant" or "oceanic");
|
||||
if (moonAnchor.planet is not null && moonAnchor.planet.Moons.Count > 0)
|
||||
{
|
||||
return $"planet-{moonAnchor.index + 1}-moon-1";
|
||||
}
|
||||
}
|
||||
|
||||
var anchorPlanetIndex = ResolveStrategicResourceAnchorPlanetIndex(itemId, planets);
|
||||
var lagrange = (ordinal % 3) switch
|
||||
{
|
||||
0 => "l1",
|
||||
1 => "l4",
|
||||
_ => "l5",
|
||||
};
|
||||
return $"planet-{anchorPlanetIndex + 1}-{lagrange}";
|
||||
}
|
||||
|
||||
private static int ResolveStrategicResourceAnchorPlanetIndex(string itemId, IReadOnlyList<PlanetDefinition> planets)
|
||||
{
|
||||
if (planets.Count == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool MatchesPlanetType(PlanetDefinition planet) => itemId switch
|
||||
{
|
||||
"hydrogen" or "helium" or "methane" => planet.PlanetType is "gas-giant" or "ice-giant",
|
||||
"ice" => planet.PlanetType is "ice" or "ice-giant" or "oceanic",
|
||||
_ => planet.PlanetType is not "gas-giant" and not "ice-giant",
|
||||
};
|
||||
|
||||
for (var index = 0; index < planets.Count; index += 1)
|
||||
{
|
||||
if (MatchesPlanetType(planets[index]))
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
return ResolveAsteroidAnchorPlanetIndex(planets);
|
||||
}
|
||||
|
||||
private static int ResolveAsteroidAnchorPlanetIndex(IReadOnlyList<PlanetDefinition> planets)
|
||||
|
||||
Reference in New Issue
Block a user