LockOn patrols orbit 3 by index; the probe file is dropped
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
5f1fa7d63b
commit
f0cb87277b
4 changed files with 15 additions and 47 deletions
|
|
@ -136,16 +136,15 @@ public sealed class ScenarioStage
|
|||
return entity;
|
||||
}
|
||||
|
||||
// The patrol order a piloted entity starts on: the one orbit that sits nearest `near` when the stage opens. A check
|
||||
// that rests on where a pilot goes states it here, so the pilot's circuit is not a draw. An entity that is not
|
||||
// piloted or not placed is a failure.
|
||||
public void Patrol(Entity entity, float2 near)
|
||||
// The patrol order a piloted entity starts on: the one orbit at this index of the arena's orbits, which a galaxy seed
|
||||
// fixes. A check that rests on where a pilot goes states it here, so the pilot's circuit is not a draw. An entity that
|
||||
// is not placed and piloted, or an index past the orbits, is a failure.
|
||||
public void Patrol(Entity entity, int orbit)
|
||||
{
|
||||
var placement = _placed.FirstOrDefault(p => ReferenceEquals(p.Entity, entity));
|
||||
if (placement == null || !placement.Piloted) { _failures.Add($"patrol: {entity?.Name ?? "no entity"} is not a placed, piloted ship"); return; }
|
||||
var orbit = Arena.Orbits.Keys.OrderBy(key => lengthsq(Arena.GetOrbitPosition(key) - near)).Cast<CultRecordKey?>().FirstOrDefault();
|
||||
if (orbit == null) { _failures.Add("patrol: the arena has no orbit to patrol"); return; }
|
||||
placement.Circuit = new[] { orbit.Value };
|
||||
if (orbit < 0 || orbit >= Arena.Orbits.Count) { _failures.Add($"patrol: the arena has no orbit {orbit} (it has {Arena.Orbits.Count})"); return; }
|
||||
placement.Circuit = new[] { Arena.Orbits.Keys.ElementAt(orbit) };
|
||||
}
|
||||
|
||||
// Items in the entity's first cargo bay, one per name. A name is an equippable or consumable design (open: the stage
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@ public sealed class LockOn : Scenario
|
|||
// The fit's lots are minted at this quality, and the hostile's patrol order is stated, so the lock follows from the
|
||||
// staged situation and not from item draws or the pilot's drawn circuit (ruling scenario-stages-hostile-task).
|
||||
const float StagedQuality = .6f;
|
||||
// The orbit it patrols: the fourth of the arena's, which carries the hostile across the player's lock envelope (lock
|
||||
// at about 35 s, closest 880 m; the other twelve, patrolled alone, do not lock it in 600 ticks).
|
||||
const int PatrolOrbit = 3;
|
||||
|
||||
public override Galaxy Generate(GalaxyStage stage) => stage.Prelude(DemoTerminus.Cast);
|
||||
|
||||
|
|
@ -46,6 +49,6 @@ public sealed class LockOn : Scenario
|
|||
|
||||
stage.Player(fighter, float2(0, 0), facing: float2(0, 1));
|
||||
var hostile = stage.Place(fighter, HostileAt, facing: normalize(-HostileAt), stance: ScenarioStance.Hostile, piloted: true);
|
||||
stage.Patrol(hostile, float2(0, 0)); // it patrols the orbit by the player, which brings it into lock range
|
||||
stage.Patrol(hostile, PatrolOrbit);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -309,11 +309,14 @@ public sealed partial class RunStartTests
|
|||
}
|
||||
CultRecordKey[] Circuit(Zone arena) => ((PatrolOrbitsTask) Assert.Single(arena.Agents).Task).Circuit;
|
||||
|
||||
// The orbit keys are fresh per galaxy, so a circuit is compared by the place of each orbit among its zone's.
|
||||
int[] Places(Zone arena) => Circuit(arena).Select(key => arena.Orbits.Keys.ToList().IndexOf(key)).ToArray();
|
||||
|
||||
var plain = Arena(0);
|
||||
var disturbed = Arena(3);
|
||||
Assert.True(plain.Orbits.Count > 4, "the zone has orbits to choose a circuit among");
|
||||
Assert.Equal(4, Circuit(plain).Length);
|
||||
Assert.Equal(Circuit(plain), Circuit(disturbed));
|
||||
Assert.Equal(4, Places(plain).Length);
|
||||
Assert.Equal(Places(plain), Places(disturbed));
|
||||
}
|
||||
|
||||
// A fit that states its quality mints every lot it builds at it, assembly and role fills alike; the same fit without one
|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
using static CultMath.math;
|
||||
|
||||
public sealed partial class RunStartTests
|
||||
{
|
||||
[Fact]
|
||||
public void ZProbeLockOn()
|
||||
{
|
||||
var log = new List<string>();
|
||||
for (var which = -1; which < 13; which++)
|
||||
{
|
||||
var (_, arena, staged, failures) = Launch(new LockOn(), Inputs(() => GalaxySeed));
|
||||
var player = staged.Player;
|
||||
var hostile = staged.Entities.Single();
|
||||
var keys = arena.Orbits.Keys.ToList();
|
||||
var agent = arena.Agents.Single();
|
||||
var task = (PatrolOrbitsTask) agent.Task;
|
||||
if (which < 0)
|
||||
foreach (var b in arena.PlanetInstances)
|
||||
log.Add($"PROBE body {arena.Planets[b.Key].Name} orbit idx {keys.IndexOf(b.Value.Orbit.Data == null ? default : keys.First(k => ReferenceEquals(arena.Orbits[k], b.Value.Orbit)))}");
|
||||
else task.Circuit = new[] { keys[which] };
|
||||
var minD = 1e9f;
|
||||
var lockedAt = -1;
|
||||
for (var tick = 0; tick < 600 && lockedAt < 0; tick++)
|
||||
{
|
||||
arena.Update(.1f);
|
||||
minD = min(minD, length(hostile.Position.xz - player.Position.xz));
|
||||
if (player.IncomingPaints.Any(p => p.Mode == PaintMode.Track)) lockedAt = tick;
|
||||
}
|
||||
log.Add($"PROBE only-orbit {which} start={arena.Orbits[keys[Math.Max(which, 0)]].Position} locked={lockedAt} minD={minD}");
|
||||
}
|
||||
Assert.Fail(string.Join(Environment.NewLine, log));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue