re(flight): START skips the briefing, and the player-entity lock is stage-specific

The scripted route now reaches FLIGHT unattended: boot -> main menu -> poke the
cleared-stage mask -> EXTRAS -> MISSION SELECT -> stage -> briefing -> READY ROOM
-> TAKE OFF -> flight, verified by a full HUD (TIME 00:52.54, speed 350, shields,
REMAINING OB 018) on stage 01.

Two things that cost a run each:

START skips the briefing; A does not. A pages through the brief, and ten A taps
still left the run sitting on a briefing screen -- twice, on two different
stages. One START press lands on the READY ROOM. fly_stage.sh now presses START.

entities2.py's `self` locked on `"Player" in name`, and that suffix is
STAGE-SPECIFIC: stage 02 fields UN_f002_TCAF_DeltaSaber_W_Player, but stage 01
fields UN_f001_TCAF_DeltaSaber_T with no suffix, so the filter found nothing
while the game was visibly flying and reporting 64 typed live entities. Falls
back to the craft class and prefers the instance that is actually moving (a
mission holds more than one). Recorded rather than worked around, because the
same assumption is embedded in several probes.
This commit is contained in:
2026-08-13 21:45:54 +00:00
parent 0b2f004ad0
commit 3d3d6726fa
3 changed files with 16 additions and 2 deletions

View File

@@ -145,7 +145,18 @@ def main():
return
if cmd == "self":
# The "_Player" suffix is STAGE-SPECIFIC. Stage 02 fields
# UN_f002_TCAF_DeltaSaber_W_Player, but stage 01 fields
# UN_f001_TCAF_DeltaSaber_T with no suffix at all, and this filter then
# found nothing while the game was visibly flying. Fall back to the
# player's craft class and prefer the instance that is actually moving —
# a mission holds more than one.
me = [e for e in ents if "Player" in e[1]]
if not me:
me = [e for e in ents if "DeltaSaber" in e[1] or "ArrowHead" in e[1]]
me.sort(key=lambda e: -e[3]) # fastest first: the flown one
if me:
print(f"# no *_Player entity; falling back to craft class -> {me[0][1]}")
if not me:
sys.exit("player entity not found")
off, nm, pos, sp = me[0]