Place records every child's slot; GenerateEntities marks belt candidates. After the swarm pass, a lane pass on its own stream gives a candidate that kept its body, has a band at least the lane's half-width on both sides, carries no swarm and whose parent has no other belt shape, an annulus on a copy of its rail: rocks over [slot inner, D - E] and [D + E, slot outer], E = LaneBodyRadii body radii. ZoneGenerationSettings gains LaneProbability (0 in code, 0.5 authored) and LaneBodyRadii (5). LanedBeltTests pins it; EveryBeltIsKindedAtGeneration moves there and asserts lanes; BeltShapes.Lanes lands with it; both TrojanSwarmTests fixtures draw no lane. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
32 lines
1.7 KiB
C#
32 lines
1.7 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using GameCult.Caching;
|
|
|
|
// The belt shapes a test reads back from a built zone. A swarm's or a lane's rail is a copy of its host's rail (same Parent,
|
|
// Distance and Phase), never a slot Place laid out, so the tests that walk placed orbits leave copied rails out through this one
|
|
// helper.
|
|
public static class BeltShapes
|
|
{
|
|
public static bool CopiedRail(Zone zone, CultRecordKey orbit)
|
|
{
|
|
if (!zone.Planets.Values.Any(b => b is AsteroidBeltData && b.Orbit.Key.Equals(orbit))) return false;
|
|
var rail = zone.Orbits[orbit].Data;
|
|
return zone.Planets.Values.Where(b => !(b is AsteroidBeltData)).Select(b => zone.Orbits[b.Orbit.Key].Data)
|
|
.Any(o => o.Parent.Key.Equals(rail.Parent.Key) && o.Distance == rail.Distance && o.Phase == rail.Phase);
|
|
}
|
|
|
|
// Every laned belt with its rail and its host: a belt on a copied rail that does not ride the rail (a swarm does), whose host
|
|
// is the body orbit the rail copies.
|
|
public static IEnumerable<(Orbit Host, Orbit Rail, AsteroidBelt Belt)> Lanes(Zone zone)
|
|
{
|
|
foreach (var (key, belt) in zone.AsteroidBelts.Where(b => !b.Value.Data.RidesRail))
|
|
{
|
|
var railKey = zone.Planets[key].Orbit.Key;
|
|
if (!CopiedRail(zone, railKey)) continue;
|
|
var rail = zone.Orbits[railKey];
|
|
var host = zone.Planets.Values.Where(b => !(b is AsteroidBeltData)).Select(b => zone.Orbits[b.Orbit.Key])
|
|
.Single(o => o.Data.Parent.Key.Equals(rail.Data.Parent.Key) && o.Data.Distance == rail.Data.Distance && o.Data.Phase == rail.Data.Phase);
|
|
yield return (host, rail, belt);
|
|
}
|
|
}
|
|
}
|