MP: world structures (garages/walls) TARGETABLE -- boresight ray-tests the static collision tree (task #50)
The boresight's non-mech pick only sampled the VISUAL heightfield (BTGroundRayHit), which on arena1 is a single flat 'sky'-named ground mesh (and class-42 BuildTables likewise holds only 'sky') -- so shots passed THROUGH the garages/walls and only mechs moved the HUD range axis (user-reported regression: "buildings used to move the range axis; now only mechs do, and you can only fire at a peer"). Real fix: the boresight now ALSO ray-tests the ZONE'S STATIC COLLISION SOLID TREE -- the same geometry that already blocks the mech's walk. Authentic engine mechanism: Mover::FindBoxedSolidHitBy already tests the static world via zone->GetCollisionRoot()->FindBoundingBoxHitBy(line). Factored its "static world" tail into Mover::FindStaticSolidHitBy(Line*) (static solids only, no movers), wrapped by Mech::WorldStructurePick(start,dir,range,&hit) (builds the world-space Line, reads the entry point back via line->FindEnd since HitByBounded clips line->length=enter). Boresight pick order is now: closest MECH (PickRayHit, damage zones + lock) -> closest STRUCTURE (WorldStructurePick; occludes a mech BEHIND it; designates the gBTTerrainEntity sentinel + entry point, so the range caret reads the structure distance and NO lock ring draws, mech4.cpp:4529) -> flat ground (BTGroundRayHit) -> sky (fire-at-nothing). Also un-skips arena1's misnamed-'sky' flat ground so the ground tier works (btvisgnd geometry-aware skip + [mapent]/[rendent] census). Verified headless: a BT_WSWEEP horizontal ray-fan on arena1 tracks position (3/24 hits near the boundary -> 17-21/24 inside the interior garage cluster -> 3/24 past it = DISCRETE interior solids, not an enclosing box), no crash/assert/AV. Interactive aim (BTGetAimRay) can't run headless (no window -> noRay), so the sweep is the headless proof; interactive aim is user-verified. Note: FindBoundingBoxUnder (the ground/containedByNode BoundingBoxTree) is DOWNWARD-only (gravity/ground-snap: *height = FindDistanceBelowBounded), useless for a horizontal boresight; the static SOLID tree's FindBoundingBoxHitBy is the only ray-vs-world query. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
ee6e19e86e
commit
de8f6d02c1
@@ -539,6 +539,37 @@ Logical
|
||||
return True;
|
||||
}
|
||||
|
||||
//
|
||||
// World-STRUCTURE boresight pick. Ray-test the zone's STATIC collision solid
|
||||
// tree (the world geometry -- garages, walls, props -- that the mech's walk
|
||||
// already collides against) along the boresight, and hand back the entry point
|
||||
// of the closest structure the ray strikes. This is the authentic non-mech
|
||||
// world pick: Mover::FindStaticSolidHitBy is the "test against the static world"
|
||||
// tail of the engine's own FindBoxedSolidHitBy (MOVER.cpp), which is what the
|
||||
// mover-vs-world collision uses -- so a shot lands on EXACTLY the geometry that
|
||||
// blocks the walk (the user's "structures block the mech, but weapons don't").
|
||||
//
|
||||
// The ray is WORLD-space (the static tree is world-space, unlike a mech's local
|
||||
// collision template). FindBoundingBoxHitBy clips the Line's length to the
|
||||
// entry distance (BoundingBox::HitByBounded -> line->length = enter), so
|
||||
// line->FindEnd yields the world entry point on the struck solid.
|
||||
//
|
||||
Logical
|
||||
Mech::WorldStructurePick(const Point3D &start, const Vector3D &dir,
|
||||
Scalar max_range, Point3D *hit_world)
|
||||
{
|
||||
Scalar dlen = (Scalar)Sqrt(dir.x*dir.x + dir.y*dir.y + dir.z*dir.z);
|
||||
if (dlen < 1e-6f)
|
||||
return False;
|
||||
Line ray(start, UnitVector(dir.x/dlen, dir.y/dlen, dir.z/dlen), max_range);
|
||||
BoxedSolid *solid = FindStaticSolidHitBy(&ray); // static world only
|
||||
if (solid == 0)
|
||||
return False;
|
||||
if (hit_world != 0)
|
||||
ray.FindEnd(hit_world); // clipped length -> entry point
|
||||
return True;
|
||||
}
|
||||
|
||||
//
|
||||
// The roster torso (sinkSourceSubsystem @0x438, ClassID 0xBC5) -- parity with
|
||||
// the binary's *(mech+0x438).
|
||||
|
||||
Reference in New Issue
Block a user