Files
BT411/scratchpad/night15/proj_ttl_bench.sh
T

100 lines
4.4 KiB
Bash

#!/usr/bin/env bash
# #168: projectile lifetime bench (v5). Two phases:
#
# PHASE 1 (probe, solo ~40s): BT_PROJ_TEST pushes two damage-0 rounds straight
# up (no target, no terrain in the path) -- each MUST fizzle at exactly its
# authentic cap: unguided ttl=5.0s (@004bddec _DAT_004be054), guided burn=2 ->
# ttl=12.0s (@004bef78 burnTime + _DAT_004bf5ac=10). Proves the timeout fires
# at the authentic second.
#
# PHASE 2 (field, 2-node ~250s): A (avatar) autofires AC + launcher salvos at
# B (madcat) walking at full throttle. Proves: every launch stamps the
# authentic ttl (5.0 / burn+10), NO round fizzles early (the old len*1.3+60
# distance cap is gone), and unguided DETs land only on the target's LIVE
# position (stale-point phantom hits dead: DET at() must ~= aim()).
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 pttl_probe.log pttl_a.log pttl_b.log pttl_relay.log
# ---------------- PHASE 1: the timeout probe (solo) ----------------
bt_expert_egg MP.EGG PTTL.EGG
sed -i "s/^map=.*/map=grass/; s/^time=.*/time=day/; s/^vehicle=.*/vehicle=avatar/" PTTL.EGG
( export BT_PROJ_TEST=1 BT_PROJ_LOG=1
bt_launch pttl_probe.log PTTL.EGG 0x03 -egg PTTL.EGG )
sleep 75
bt_kill_ours; sleep 2; taskkill //F //IM btl4.exe >/dev/null 2>&1; sleep 3
# ---------------- PHASE 2: the field rig (2-node) ----------------
bt_expert_egg MP.EGG PTTL.EGG
sed -i "s/^map=.*/map=grass/; s/^time=.*/time=day/" PTTL.EGG
python - <<'EOF'
lines = open('PTTL.EGG').read().splitlines(True)
n = 0
for i, l in enumerate(lines):
if l.startswith('vehicle='):
n += 1
lines[i] = 'vehicle=avatar\n' if n == 1 else 'vehicle=madcat\n'
open('PTTL.EGG', 'w').writelines(lines)
print('vehicles set:', n)
EOF
( export BT_AUTODRIVE=1.0 BT_SPIN_SELF=45 BT_MP_LOG=1
bt_launch pttl_b.log PTTL.EGG 0x0C -net 1601 )
sleep 2
( export BT_SPIN_SELF=30 BT_KEY_NOFOCUS=1
export BT_AUTOFIRE=1 BT_AF_MISSILE=1 BT_AF_PERIOD=7
export BT_PROJ_LOG=1 BT_MP_LOG=1
bt_launch pttl_a.log PTTL.EGG 0x03 -net 1501 )
sleep 5
python ../tools/btconsole.py PTTL.EGG 127.0.0.1:1501 127.0.0.1:1601 > pttl_relay.log 2>&1 &
RELAY=$!
sleep 240
kill $RELAY 2>/dev/null
sleep 2
bt_kill_ours; sleep 2; taskkill //F //IM btl4.exe >/dev/null 2>&1
python - <<'PY'
import io, re, math
ok = True
# ---- phase 1: the probe ----
ptxt = io.open("pttl_probe.log", encoding="latin-1", errors="replace").read()
pfz = re.findall(r"\[projectile\] FIZZLE t=([0-9.]+) ttl=([0-9.]+) guided=(\d)", ptxt)
u = [(float(t), float(c)) for t, c, g in pfz if g == '0']
g = [(float(t), float(c)) for t, c, g in pfz if g == '1']
print("=== #168 PHASE 1: TIMEOUT PROBE ===")
print("probe fizzles unguided/guided:", u, "/", g)
p1 = (len(u) == 1 and len(g) == 1
and abs(u[0][1] - 5.0) < 0.001 and u[0][0] >= 5.0 and u[0][0] < 5.3
and abs(g[0][1] - 12.0) < 0.001 and g[0][0] >= 12.0 and g[0][0] < 12.3)
print("phase 1:", "PASS -- timeouts fired at the authentic caps" if p1 else "FAIL")
ok &= p1
# ---- phase 2: the field rig ----
txt = io.open("pttl_a.log", encoding="latin-1", errors="replace").read()
push = re.findall(r"\[projectile\] PUSH .*guided=(\d) ttl=([0-9.]+)", txt)
fz = re.findall(r"\[projectile\] FIZZLE t=([0-9.]+) ttl=([0-9.]+) guided=(\d)", txt)
p0 = [t for gg, t in push if gg == '0']; p1n = [t for gg, t in push if gg == '1']
badp0 = [t for t in p0 if abs(float(t) - 5.0) > 0.001]
badp1 = [t for t in p1n if float(t) < 10.0]
early = [(t, c, gg) for t, c, gg in fz if float(t) < float(c) - 0.05]
# phantom check: every unguided DET must burst ON the live aim (at ~= aim)
phantom = []
for m in re.finditer(r"DET at\(([-0-9.]+),([-0-9.]+),([-0-9.]+)\) dmg=13 .*aim\(([-0-9.]+),([-0-9.]+),([-0-9.]+)\)", txt):
ax, ay, az, bx, by, bz = map(float, m.groups())
if math.sqrt((ax-bx)**2 + (ay-by)**2 + (az-bz)**2) > 12.0:
phantom.append(m.group(0)[:90])
print("=== #168 PHASE 2: FIELD RIG ===")
print("PUSH unguided/guided :", len(p0), "/", len(p1n))
print("bad ttl stamps :", len(badp0) + len(badp1))
print("early fizzles :", len(early), early[:3])
print("phantom unguided DETs:", len(phantom), phantom[:2])
p2 = (len(p0) > 0 and len(p1n) > 0 and not badp0 and not badp1
and not early and not phantom)
print("phase 2:", "PASS -- stamps authentic, none early, no stale-point hits" if p2 else "FAIL")
ok &= p2
print("VERDICT:", "PASS" if ok else "FAIL")
PY