Authentic target acquisition LIVE: reticle slew + pick-ray lock + aimed zone damage (task #36)
The engine Reticle model (MUNGA/RETICLE.h [T0]) reconstructed end to end: - Mech::targetReticle is a real Reticle member bound to the TargetReticle attribute (0x1d), per the RP VTV analog (VTV.h targetReticle). - Crosshair slew: mouse -> client rect -> reticle coords (the pod stick free-aim channel's dev-box stand-in); BT_AIM="x y" pins it headless. LMB fires lasers / RMB missiles (alongside SPACE/CTRL). - Pick ray: the ACTIVE eye publishes pos + LookAtRH basis (BTSetAimCamera, L4VIDRND view-write site) + the render loop publishes proj._22; BTGetAimRay builds the world ray, Mech::PickRayHit slab-tests it against the collision template's ExtentBox via the engine's BoundingBox::HitBy (local frame; clips the Line at entry) -> world hull point. - Designation: the mech under the crosshair designates (sticky; re-hover refreshes; cleared when the target leaves the roster at burial); the entity target slots 0x37c/0x388/0x38c feed the whole weapon path. - Aimed fire: while HOT the impact point is the PICKED hull point -> the STEP-6 cylinder lookup resolves the zone under the crosshair (verified: center-aim -> head-band zone 13 dominant). Off-crosshair the sticky designation converges on center mass. - HUD: the aim group draws at the slewed position ([0x9a] translate, contained by push/pop); the designator ring tracks the target's projected point (subB9 hot / subB8 designated, BTProjectToReticle); edge arrows when off-screen/behind. - AUTHENTIC gating: no fire arc exists in the binary (FireWeapon fires whenever HasActiveTarget, part_013.c:7758) -> BT_FIRE_ARC is now an explicit OPT-IN presentation clamp; the hardwired gEnemyMech lock and the projectile path's gEnemyMech fallback are removed. - Fixed en route: every renderable rebuild stomped mCamera back to the chase eye (start-inside silently lost the cockpit camera; the aim feed exposed it). BTL4VideoRenderer::mViewInside persists the chosen view. Verified headless: BT_AIM="0 0" -> HOT lock, pick hits the hull face at exact range, aimed zones resolve; BT_AIM="0.8 0.3" -> no lock, zero damage, zero missile launches; kill chain completes to wreck + smoke. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
6988821525
commit
d78bde066d
@@ -616,7 +616,11 @@ HierarchicalDrawComponent*
|
||||
debugOffset(3,0) = camPx; debugOffset(3,1) = camPy; debugOffset(3,2) = camPz; // W row (pos)
|
||||
|
||||
mEyeChase = new DPLEyeRenderable(entity, debugOffset, this_root, NULL);
|
||||
mCamera = mEyeChase; // default view: chase (V toggles cockpit)
|
||||
// Respect the pilot's CHOSEN view across renderable rebuilds: this build
|
||||
// used to stomp mCamera back to chase on every remake (damage swaps,
|
||||
// start-inside), silently flipping the active eye out from under the V
|
||||
// toggle (and the aim-ray camera feed with it).
|
||||
mCamera = (mViewInside && mEyeCockpit != 0) ? mEyeCockpit : mEyeChase;
|
||||
DEBUG_STREAM << "[BTrender] external debug chase camera installed at ("
|
||||
<< camPx << "," << camPy << "," << camPz << ") looking at ("
|
||||
<< tgtX << "," << tgtY << "," << tgtZ << ") -- V toggles the cockpit eyepoint"
|
||||
@@ -1064,8 +1068,17 @@ BTReticleRenderable::BTReticleRenderable(Entity *entity, Scalar *range_attr)
|
||||
dpl2d_SetLineWidth(m, 1.0f);
|
||||
dpl2d_FullScreenClip(m);
|
||||
dpl2d_SetColor(m, 0.75f, 0.0f, 0.0f);
|
||||
dpl2d_CallList(m, crossList); // [0xa1] target-box slot (empty until lock)
|
||||
dpl2d_CallList(m, crossList); // [0xa1] target-box slot (empty until lock;
|
||||
// Draw rebuilds it: designator ring at the
|
||||
// target's screen point / off-screen arrows)
|
||||
dpl2d_SetColor(m, 0.0f, 0.75f, 0.0f);
|
||||
// the AIM GROUP (task #36): [0x9a] is the aim TRANSLATE -- CallList state
|
||||
// persists to the caller (the dpl2d inline-include semantic), so the slew
|
||||
// translate it carries positions the dot + crosses that follow. The
|
||||
// PushState/PopState pair contains it so the fixed frame (tick ladders,
|
||||
// tapes) stays put. [T3 -- the binary Execute is un-exported; mechanism
|
||||
// per the engine ReticleRenderable's position-list pattern, T0.]
|
||||
dpl2d_PushState(m);
|
||||
dpl2d_CallList(m, aimDotList); // [0x9a] the aim translate
|
||||
dpl2d_OpenPolypoint(m); // centre dot
|
||||
dpl2d_AddPoint(m, 0.0f, 0.0f);
|
||||
@@ -1083,6 +1096,7 @@ BTReticleRenderable::BTReticleRenderable(Entity *entity, Scalar *range_attr)
|
||||
dpl2d_AddPoint(m, 0.0f, 0.10f); dpl2d_AddPoint(m, 0.0f, 0.16f);
|
||||
dpl2d_AddPoint(m, 0.0f, -0.10f); dpl2d_AddPoint(m, 0.0f, -0.16f);
|
||||
dpl2d_CloseLines(m);
|
||||
dpl2d_PopState(m); // contain the aim translate
|
||||
dpl2d_SetLineWidth(m, 1.0f);
|
||||
// the RIGHT range ladder (13 ticks up the right side, dir 3 = -y travel)
|
||||
BTReticleTickLadder(m, kRetTicksR, 1, kRetScaleY,
|
||||
@@ -1222,6 +1236,49 @@ void
|
||||
dpl2d_End(rangeCaretR);
|
||||
dpl2d_Compile(rangeCaretR);
|
||||
|
||||
// the AIM translate [0x9a] (task #36): the slewed crosshair position, in
|
||||
// reticle coordinates (fed by the mouse / stick free-aim in mech4).
|
||||
{
|
||||
extern float gBTAimX, gBTAimY;
|
||||
Scalar t6[6] = { 1, 0, 0, 1, gBTAimX, gBTAimY };
|
||||
dpl2d_Begin(aimDotList, 1);
|
||||
dpl2d_ConcatMatrix(aimDotList, t6);
|
||||
dpl2d_End(aimDotList);
|
||||
dpl2d_Compile(aimDotList);
|
||||
}
|
||||
|
||||
// the TARGET DESIGNATOR slot [0xa1] (task #36, Reticle::TargetDesignatorOn
|
||||
// [T0]): the designated target's projected screen point gets the lock ring
|
||||
// (subB9 ring+cross while the crosshair is ON it, subB8 plain ring while
|
||||
// designated); off-screen / behind, the edge turn ARROW points the way back.
|
||||
{
|
||||
extern int gBTHudLockState; // 0 none / 1 designated / 2 hot
|
||||
extern float gBTHudLockWorld[3];
|
||||
extern int BTProjectToReticle(const float world[3], float *rx, float *ry);
|
||||
|
||||
dpl2d_Begin(crossList, 1);
|
||||
if (gBTHudLockState != 0)
|
||||
{
|
||||
float tx = 0.0f, ty = 0.0f;
|
||||
const int onScreen = BTProjectToReticle(gBTHudLockWorld, &tx, &ty);
|
||||
const float xLimit = 1.55f; // past the ladders = off-screen
|
||||
if (onScreen && tx > -xLimit && tx < xLimit && ty > -1.0f && ty < 1.0f)
|
||||
{
|
||||
Scalar d6[6] = { 1, 0, 0, 1, tx, ty };
|
||||
dpl2d_PushState(crossList);
|
||||
dpl2d_ConcatMatrix(crossList, d6);
|
||||
dpl2d_CallList(crossList, (gBTHudLockState == 2) ? subB9 : subB8);
|
||||
dpl2d_PopState(crossList);
|
||||
}
|
||||
else
|
||||
{
|
||||
dpl2d_CallList(crossList, (tx < 0.0f) ? leftArrow : rightArrow);
|
||||
}
|
||||
}
|
||||
dpl2d_End(crossList);
|
||||
dpl2d_Compile(crossList);
|
||||
}
|
||||
|
||||
dpl2d_ExecuteList(masterList, device);
|
||||
|
||||
for (int i = 0; i < weaponCount; ++i)
|
||||
@@ -1623,6 +1680,7 @@ BTL4VideoRenderer::BTL4VideoRenderer(
|
||||
Check_Pointer(this);
|
||||
mEyeCockpit = 0;
|
||||
mEyeChase = 0;
|
||||
mViewInside = 0;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1633,6 +1691,7 @@ BTL4VideoRenderer::BTL4VideoRenderer(
|
||||
void
|
||||
BTL4VideoRenderer::SetViewInside(int inside)
|
||||
{
|
||||
mViewInside = inside; // persists across renderable rebuilds
|
||||
if (inside && mEyeCockpit != 0)
|
||||
mCamera = mEyeCockpit;
|
||||
else if (!inside && mEyeChase != 0)
|
||||
|
||||
Reference in New Issue
Block a user