Files
BT411/scratchpad/night6/file_73pick.py
T

47 lines
3.5 KiB
Python

"""#73: the pick-model resolution."""
import base64
import json
import subprocess
import urllib.request
REPO = r"C:\git\bt411"
BASE = "https://gitea.mysticmachines.com/api/v1/repos/VWE/BT411"
out = subprocess.run(["git", "credential", "fill"],
input="protocol=https\nhost=gitea.mysticmachines.com\n\n",
capture_output=True, text=True, cwd=REPO)
cred = dict(l.split("=", 1) for l in out.stdout.strip().splitlines() if "=" in l)
AUTH = "Basic " + base64.b64encode(
(cred["username"] + ":" + cred["password"]).encode()).decode()
def call(method, path, payload=None):
data = json.dumps(payload).encode() if payload is not None else None
r = urllib.request.Request(BASE + path, data=data, method=method)
r.add_header("Authorization", AUTH)
r.add_header("Content-Type", "application/json")
return json.load(urllib.request.urlopen(r))
BODY = """**RESOLVED at the model level 2026-07-29** (`bcbc7cf` + `e110b10`): the residual question -- what geometry did the pod's pick test -- has a definitive answer, and it is neither the port's box nor a cylinder.
**There was never a software pick.** The target block at `mech+0x37c/0x388/0x38c` is an embedded engine `Reticle` struct (`mech+0x36c`, RETICLE.h lays the fields out exactly), and nothing in the binary writes its pick fields -- game code constructs it (the Mech ctor `@0x4a1674`, recovered this dig), gates it (the look-state machine `@0x4afd10`: per-view crosshair positions, pickPointing on only where a view allows it), reads it (HUD, fire path, missiles), and ships it to the video board for drawing (`@0x460a7c`). The pick itself was a **DPL SCENE INTERSECTION run by the division card**: the WinTesla renderer still carries the result slots (`dplHitInstance/dplHitDCS/dplHitGeoGroup/dplHitGeometry`), and the 1995-era renderable constructors each configured `dpl_isect_mode_obj` + an intersection mask per scene object. Auric's "the pod's division card cast from the view" was literal. So was VGL Lynx's LOD warning -- the ray tested the DRAWN geometry, on the active LOD.
**What this means:**
- **Aimed fire in 1995 had per-part precision.** Scene ray -> struck triangle -> the DCS is the SEGMENT -> the segment's `dzone` is the credited zone. Aim at the arm mesh, hit the arm's zone.
- The **cylinder lottery** (the earlier finding on this issue) was only ever the **UNAIMED** path -- splash, cook-off, -1 dispatches.
- The port's whole-mech box pick funnels AIMED fire through the unaimed lottery -- which is exactly what was documented on night 6. Both halves of the report are now explained: the spray is the unaimed model, and aimed fire wrongly using it is the port gap.
**Fix design** (recorded in `context/combat-damage.md`): a per-SEGMENT ray test on the shooter side -- `inverse(segmentWorld) * ray` against each segment BGF's local extent box, nearest struck segment wins, its `dzone` dispatched as the aimed zone, beam converging to the segment hit point. The renderable tree already keeps a per-segment `dcs_array` with the live transforms, and `Mech__DamageZone::segmentIndex` maps segments to zones. Falls back to the current box+lottery when no segment resolves (tree not yet built, spectators, etc.).
Implementation is the next work item on this issue."""
marker = BODY.strip().splitlines()[0][:60]
for c in call("GET", "/issues/73/comments"):
if marker in c.get("body", ""):
print(" #73 already has this comment - skipped")
raise SystemExit
call("POST", "/issues/73/comments", {"body": BODY})
print(" commented on #73")