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
@@ -1137,6 +1137,34 @@ BoxedSolid*
|
||||
return solid;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// The "static world" tail of FindBoxedSolidHitBy on its own: ray-test ONLY the
|
||||
// zone's static solid tree (world structures -- garages, walls, props), NOT the
|
||||
// tangible movers/doors. Same tree the mech's walk collides against, so a shot
|
||||
// designated through this lands on exactly the geometry that blocks the mech.
|
||||
// FindBoundingBoxHitBy clips line->length to the hit distance (HitByBounded ->
|
||||
// line->length = enter), so the caller reads the entry point via line->FindEnd.
|
||||
//
|
||||
BoxedSolid*
|
||||
Mover::FindStaticSolidHitBy(
|
||||
Line *line
|
||||
)
|
||||
{
|
||||
Check(this);
|
||||
Check(line);
|
||||
|
||||
InterestManager *interest_mgr = application->GetInterestManager();
|
||||
Check(interest_mgr);
|
||||
InterestZone *zone = interest_mgr->GetInterestZone(interestZoneID);
|
||||
Check(zone);
|
||||
BoxedSolidTree* tree = zone->GetCollisionRoot();
|
||||
Check(tree);
|
||||
BoxedSolid *result = (BoxedSolid*)tree->FindBoundingBoxHitBy(line);
|
||||
Check_Fpu();
|
||||
return result;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
BoxedSolidCollisionList*
|
||||
|
||||
@@ -300,6 +300,16 @@ public:
|
||||
Line *line,
|
||||
Entity *except_by
|
||||
);
|
||||
// STATIC-WORLD-ONLY ray query: the "test against the static world" tail of
|
||||
// FindBoxedSolidHitBy factored out -- ray-tests ONLY the zone's static solid
|
||||
// tree (the world structures: garages, walls, props), skipping the tangible
|
||||
// movers/doors. Used by the weapon boresight pick so a shot lands on the SAME
|
||||
// static geometry that already blocks the mech's walk (mechs are picked
|
||||
// separately, with their damage zones/lock). Clips line->length to the entry.
|
||||
BoxedSolid*
|
||||
FindStaticSolidHitBy(
|
||||
Line *line
|
||||
);
|
||||
BoxedSolidCollisionList*
|
||||
CollideCenterOfMotion(
|
||||
Line *line,
|
||||
|
||||
Reference in New Issue
Block a user