Files
BT411/scratchpad/night16/bys_forensics.py
T

89 lines
3.6 KiB
Python

#!/usr/bin/env python
# Forensics for the 11 [projectile] BYSTANDER receipts of the weapons_sweep
# run: classify every DET lock pointer by aim-point motion (a mech lock TRACKS
# the walking enemy; a scenery/wreck lock is stationary), then test each
# receipt: struck id vs the shooter's own id, det-to-aim distance, and the
# paired IMPACT delivery.
import io
import math
import re
RX_DET = re.compile(r"\[projectile\] DET at\(([^)]*)\) dmg=([\d.eE+\-]+) "
r"lead=(\d+) tgt=(\S+) aim\(([^)]*)\)")
RX_BYS = re.compile(r"\[projectile\] BYSTANDER id=(\d+) t=(\S+) at\(([^)]*)\) "
r"dmg=([\d.eE+\-]+) lockedTgt=(\S+)")
RX_RST = re.compile(r"\[respawn\] Mech::Reset (\d+):(\d+) ")
def p3(s):
a = [float(x) for x in s.split(",")]
return a
def dist(a, b):
return math.sqrt(sum((a[i] - b[i]) ** 2 for i in range(3)))
for fn in ("ws_a.log", "ws_b.log"):
lines = io.open("/c/git/bt411/content/" + fn.replace("/", ""),
encoding="latin-1", errors="replace").read().splitlines() \
if False else io.open("C:/git/bt411/content/" + fn,
encoding="latin-1", errors="replace").read().splitlines()
own = None
dets = {} # tgt ptr -> list of (lineno, aim)
bys = [] # (lineno, id, at, dmg, lockedTgt)
for i, l in enumerate(lines):
m = RX_DET.search(l)
if m and m.group(4) != "0x0" and float(m.group(2)) > 0.0:
dets.setdefault(m.group(4), []).append((i, p3(m.group(5))))
continue
m = RX_BYS.search(l)
if m:
bys.append((i, int(m.group(1)), p3(m.group(3)),
float(m.group(4)), m.group(5)))
continue
m = RX_RST.search(l)
if m and own is None:
own = int(m.group(2))
print("=== %s (own mech entity=%s) ===" % (fn, own))
# classify pointers: max pairwise aim distance within a 1500-line window
cls = {}
for ptr, lst in sorted(dets.items(), key=lambda kv: -len(kv[1])):
move = 0.0
for j in range(1, len(lst)):
if lst[j][0] - lst[j - 1][0] <= 1500:
d = dist(lst[j][1], lst[j - 1][1])
if d > move:
move = d
cls[ptr] = "MECH-TRACKING" if move > 60.0 else "STATIONARY"
print(" lock %s damage-DETs=%3d max local aim motion=%7.1fu -> %s"
% (ptr, len(lst), move, cls[ptr]))
ok = True
for (i, mid, at, dmg, ptr) in bys:
# find this receipt's own DET (next damage DET line)
aim = None
imp = False
for j in range(i, min(i + 4, len(lines))):
m = RX_DET.search(lines[j])
if m and aim is None:
aim = p3(m.group(5))
if "[projectile] IMPACT damage=" in lines[j]:
imp = True
d_aim = dist(at, aim) if aim else -1.0
verdict = []
if mid == own:
verdict.append("SELF-STRIKE (geometry bug)")
if cls.get(ptr) == "MECH-TRACKING":
verdict.append("LOCK WAS THE MECH (exclusion failed)")
if aim is not None and d_aim < 30.0:
verdict.append("det at the lock's own aim point")
if not imp:
verdict.append("no paired IMPACT delivery")
tag = "TRUE-POSITIVE" if not verdict else "FALSE-POSITIVE: " + "; ".join(verdict)
if verdict:
ok = False
print(" bys@%-6d struck=%d dmg=%g lock=%s(%s) det-to-aim=%.0fu imp=%d %s"
% (i + 1, mid, dmg, ptr, cls.get(ptr, "?"), d_aim, imp, tag))
print(" %s: %s" % (fn, "all receipts TRUE positives" if ok
else "FALSE POSITIVES PRESENT"))