Files
BT411/scratchpad/night16/cascade_bench.sh
T

57 lines
2.4 KiB
Bash

#!/usr/bin/env bash
# #174: a destroyed zone must NEVER re-run its crit cascade. Binary truth:
# the burst-loop zone-state guard wraps the WHOLE application (@0x4a0446,
# part_012.c:14661) -- continued fire into a dead zone is a no-op. Night-16
# field logs showed zone 18 x7 / zone 9 x4 re-descends from the port's
# narrowed guard. Rig: 2-node kd-style fight (sustained autofire, multiple
# deaths). PASS: in BOTH logs, no zone index cascades twice within one life
# (between RESET markers); at least 2 cascades + 1 death total (rig sanity).
set -x
. /c/git/bt411/scratchpad/night6/bench_common.sh
cd /c/git/bt411/content || exit 1
taskkill //F //IM btl4.exe >/dev/null 2>&1; sleep 3
rm -f casc_a.log casc_b.log casc_r.log
bt_expert_egg MP.EGG CAS.EGG
sed -i "s/^map=.*/map=grass/; s/^time=.*/time=day/; s/^vehicle=.*/vehicle=madcat/; s/^length=.*/length=180/" CAS.EGG
( export BT_AUTOFIRE=1 BT_FIRE_AT_ICON=1 BT_DEATH_LOG=1 BT_DMG_LOG=1
bt_launch casc_b.log CAS.EGG 0x0C -net 1601 )
( export BT_AUTOFIRE=1 BT_FIRE_AT_ICON=1 BT_DEATH_LOG=1 BT_DMG_LOG=1
bt_launch casc_a.log CAS.EGG 0x03 -net 1501 )
sleep 5
python ../tools/btconsole.py CAS.EGG 127.0.0.1:1501 127.0.0.1:1601 > casc_r.log 2>&1 &
sleep 195
bt_kill_ours; sleep 2; taskkill //F //IM btl4.exe >/dev/null 2>&1
python - <<'PY'
import io, re
ok = True
tot_casc = tot_death = 0
for fn in ("casc_a.log", "casc_b.log"):
L = io.open(fn, encoding="latin-1", errors="replace").read().splitlines()
life = {} # zone -> cascade count this life
worst = {}
deaths = 0
for l in L:
m = re.search(r"\[cascade\] zone (\d+) DESTROYED", l)
if m:
z = int(m.group(1))
life[z] = life.get(z, 0) + 1
worst[z] = max(worst.get(z, 0), life[z])
tot_casc += 1
elif "RESET (death" in l or "Mech::Reset" in l:
life = {}
deaths += 1
tot_death += deaths
dup = {z: c for z, c in worst.items() if c > 1}
print(f"{fn}: cascades-per-life max={max(worst.values()) if worst else 0} "
f"zones={len(worst)} deaths={deaths} dups={dup}")
if dup:
ok = False
print(f"FAIL: {fn} re-descended zones {dup} within one life -- #174 ALIVE")
print(f"totals: cascades={tot_casc} deaths={tot_death}")
if tot_casc < 2: ok = False; print("FAIL: rig too quiet (need >=2 cascades)")
if tot_death < 1: ok = False; print("FAIL: rig too quiet (need >=1 death)")
print("RESULT:", "PASS" if ok else "FAIL")
PY