MP task #48 (partial): -net aim+drive already work; localize the real gap
Re-measured interactive -net combat on a 2-node run. The KB's "aim ray dead / drive dead in -net" was STALE: A's aim ray is live (noRay=0, the active eye publishes the aim camera) and A drives (BT_AUTODRIVE/BT_GOTO move it). The real blocker to a human cross-pod kill via the beam path is NOT the netcode: - Boresight inherits the mech BODY pitch. The aim ray = the active eye's view dir; on sloped terrain the body pitches to conform and the boresight points ~8 deg down ([EYE] up=(-.03,.99,-.14) == [pick] ldir.y=-0.145 every frame), so at range the ray hits terrain ~50-100m short of the enemy (mechPicks=0). - Drive/goto stalls ~700m short before closing to pick/weapon range. - PickRayHit vs a replicant is thus unconfirmed, but the replicant localToWorld IS correct (lstart magnitude == true A->B distance; the DeadReckon + localToWorld=localOrigin block already tracks the replicated position). Change: add a gated BT_GOTO="enemy" test mode (beeline toward the nearest live replicant) -- MP spawn coords vary per run so a fixed "x z" can't reliably face the peer. KB (multiplayer.md) updated with the corrected findings + the real remaining work (torso-pitch/level-boresight aim ray + drive-to-range). Solo un-regressed; btl4.exe builds; KB validator clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
54b6663b4d
commit
bac45851ad
@@ -1499,10 +1499,33 @@ void
|
||||
if (s_goto < 0)
|
||||
{
|
||||
const char *gv = getenv("BT_GOTO");
|
||||
if (gv && sscanf(gv, "%f %f", &s_gx, &s_gz) == 2) s_goto = 1;
|
||||
if (gv && !stricmp(gv, "enemy")) s_goto = 2; // chase nearest replicant
|
||||
else if (gv && sscanf(gv, "%f %f", &s_gx, &s_gz) == 2) s_goto = 1;
|
||||
else s_goto = 0;
|
||||
}
|
||||
if (s_goto == 1)
|
||||
if (s_goto == 2)
|
||||
{
|
||||
// DYNAMIC target (test harness): beeline toward the CLOSEST live
|
||||
// peer replicant wherever it currently is -- MP spawn positions
|
||||
// vary per run, so a fixed "x z" can't reliably face the enemy.
|
||||
extern int BTGetTargetCandidates(Entity *shooter, Entity **out, int maxOut);
|
||||
Entity *ec[32];
|
||||
const int enc = BTGetTargetCandidates((Entity *)this, ec, 32);
|
||||
float best = 1e30f; int found = 0;
|
||||
for (int ei = 0; ei < enc; ++ei)
|
||||
{
|
||||
Mech *em = (Mech *)ec[ei];
|
||||
if (em == 0 || em->GetInstance() != ReplicantInstance
|
||||
|| em->IsMechDestroyed()) continue;
|
||||
Point3D ep = em->localOrigin.linearPosition;
|
||||
float edx = (float)ep.x - (float)localOrigin.linearPosition.x;
|
||||
float edz = (float)ep.z - (float)localOrigin.linearPosition.z;
|
||||
float ed2 = edx*edx + edz*edz;
|
||||
if (ed2 < best) { best = ed2; s_gx = (float)ep.x; s_gz = (float)ep.z; found = 1; }
|
||||
}
|
||||
if (found) s_goto = 2; else { gBTGotoActive = 0; }
|
||||
}
|
||||
if (s_goto == 1 || (s_goto == 2 && (s_gx != 0.0f || s_gz != 0.0f)))
|
||||
{
|
||||
float ddx = s_gx - (float)localOrigin.linearPosition.x;
|
||||
float ddz = s_gz - (float)localOrigin.linearPosition.z;
|
||||
|
||||
Reference in New Issue
Block a user