Drawn pose: ship indicators and map centre read DrawAhead; Round takes one time; RailAt logs a missing parent

- ActionGameManager: the visible hostile/friendly indicators and MenuMap.Position read DrawAhead.Position at Clock.Lead.
- DrawAhead.Round drops its lead parameter: the target's lead is the drawn time less its zone's step time, derived inside,
  so a caller cannot pass two times that disagree. Projectile and BallisticFlightTests updated; the hit tests derive their
  lead from the drawn time; two assertions that only varied the now-absent lead are removed.
- Zone.RailAt logs "Requested orbit is not part of this zone!" for a missing parent again (DrawnPoseTests.AMissingParentOrbitIsLoggedAtADrawnTime).

Builds: not yet compiled at this commit (verified by the run that follows).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-16 00:50:29 +02:00
commit e5eb87050e
6 changed files with 70 additions and 62 deletions

View file

@ -91,18 +91,18 @@ public static class DrawAhead
t.w * q.w - t.x * q.x - t.y * q.y - t.z * q.z));
}
// A ballistic round at the drawn time (DrawAhead.Time, passed in by the caller, as lead is): on its frozen line while the outcome is unknown or a
// A ballistic round at the drawn time (DrawAhead.Time, passed in by the caller; the target's lead is that time less its zone's step time, derived here, never a second input): on its frozen line while the outcome is unknown or a
// miss, with the barrel's offset from that line decaying to nothing over blendTime sim seconds from the moment of firing.
// A round the sim published as a hit or burst steers from its line, from the commit tick, onto where it ends by the
// time damage lands: a burst's frozen point, else the impact cell on the target's drawn pose; and is held there after.
public static float3 Round(in PendingShot shot, ShotOutcome known, float3 barrel, float blendTime, double drawnTime, float lead)
public static float3 Round(in PendingShot shot, ShotOutcome known, float3 barrel, float blendTime, double drawnTime)
{
var time = (float) drawnTime;
var drawn = Lifted(shot, Line(shot, known?.Result, time), barrel, blendTime, time);
if (known == null || known.Result == ShotResult.Miss) return drawn;
var end = known.HasBurstPoint
? float3(known.BurstPoint.x, shot.FireOrigin.y, known.BurstPoint.y)
: Impact(known.Target, known.Cell, lead);
: Impact(known.Target, known.Cell, (float) (drawnTime - known.Target.Zone.ExactTime));
var commit = shot.ArrivalTime - known.ArrivalIn;
var steer = shot.ArrivalTime > commit ? saturate((time - commit) / (shot.ArrivalTime - commit)) : 1f;
return drawn + (end - drawn) * steer;

View file

@ -533,8 +533,13 @@ public class Zone
// The same rail law at any time, with no memo read or written: a parent is its own rail at that time.
private float2 RailAt(CultRecordKey orbitID, double time)
{
if (!orbitID.IsSet() || !Orbits.TryGetValue(orbitID, out var orbit))
if (!orbitID.IsSet())
return float2.zero;
if (!Orbits.TryGetValue(orbitID, out var orbit))
{
Log?.Invoke("Requested orbit is not part of this zone!");
return float2.zero;
}
var parentPosition = !orbit.Data.Parent.IsSet() ? orbit.Data.FixedPosition : RailAt(orbit.Data.Parent.Key, time);
return parentPosition + Offset(orbit, time);
}