gauges/map: populate the radar entity grid + draw mech contact blips

Root-caused why the radar showed 0 contacts: the gauge renderer's moving/static
entity grids (queried by GetMoving/StaticEntitiesWithinBounds) were NEVER
populated -- the 1995 game fed them from ExecuteImplementation's InterestingEntity
iterator, which the WinTesla port dropped.

Fix (engine): add GaugeRenderer::RebuildEntityGrid() -- Clear + repopulate
movingEntities from the world's DynamicMaster + DynamicReplicant entities (the
vehicles/mechs; AllEntity would flood the grid with ~300 props/effects/terrain).
Called from the map's Execute phase 0 (under the gauge's guarded Execute, so a
fault disables only the map).  Verified: contacts are now found, combat un-
regressed (TARGET DESTROYED), heap-clean under BT_HEAPCHECK.

Fix (map): DrawMoving now draws a cross blip for mech-class contacts (0xBB9) when
the authentic pip raster set is absent (the BT pip table is stubbed in this engine
build).  KEY PROJECTION FIX: worldToView is a camera (view->world) matrix and
Point3D::Multiply applies only rotation+scale (NOT translation), so projecting the
absolute entity position left the viewpoint un-subtracted and the blip landed
off-screen (verified: blip @(580,-1154)).  Project the RELATIVE position (delta =
entity - viewpoint, already computed for the range check) instead -> the blip
projects viewpoint-relative + heading-rotated correctly (@(164,221)).

radarRange default 500->1000 (1km zoom) so contacts within ~500m show on the
radar (SetTargetRange, the real player zoom, is still stubbed).  BT_MAP_LOG traces
the blip coords.

STATE: the grid population + viewpoint-relative blip projection are correct and
combat-safe.  A reliable on-screen contact demo still needs the display-scale vs
spawn-distance reconciliation (the BT_SPAWN_ENEMY dummy sits at a varying, large
distance -- 377-828m -- beyond the display radius across runs) + the authentic pip
symbol/name/video-object infrastructure (still stubbed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-06 22:07:19 -05:00
co-authored by Claude Opus 4.8
parent 1746c5bb1f
commit 0bceb9a638
4 changed files with 96 additions and 3 deletions
+52
View File
@@ -6,6 +6,7 @@
#include "mover.h"
#include "terrain.h"
#include "app.h"
#include "hostmgr.h" // HostManager + AllEntityIterator (RebuildEntityGrid)
// #define LOCAL_TEST
@@ -3587,6 +3588,57 @@ void
CLEAR_GAUGE_RENDERER();
}
//
//===========================================================================
// RebuildEntityGrid -- repopulate the moving/static entity grids from the world
// entity list (the port dropped ExecuteImplementation's InterestingEntity feed,
// so the radar/map gauge's within-bounds queries found no contacts).
//===========================================================================
//
void
GaugeRenderer::RebuildEntityGrid()
{
Check(this);
movingEntities.Clear();
staticEntities.Clear();
if (application == NULL)
{
return;
}
HostManager *host_manager = application->GetHostManager();
if (host_manager == NULL)
{
return;
}
// Radar contacts are the DYNAMIC vehicles (mechs), not the props/terrain/
// projectiles that AllEntityIterator would flood the grid with -- iterate the
// dynamic masters (the local + AI/dummy vehicles) plus the dynamic replicants
// (peer vehicles in multiplayer). Static beacons/props (a separate
// classification) are left for a follow-up.
{
HostManager::DynamicMasterEntityIterator master_iterator(host_manager);
master_iterator.First();
Entity *entity;
while ((entity = master_iterator.ReadAndNext()) != NULL)
{
movingEntities.Add(entity);
}
}
{
HostManager::DynamicReplicantEntityIterator replicant_iterator(host_manager);
replicant_iterator.First();
Entity *entity;
while ((entity = replicant_iterator.ReadAndNext()) != NULL)
{
movingEntities.Add(entity);
}
}
Check_Fpu();
}
void
GaugeRenderer::ExecuteForeground()
{
+7
View File
@@ -560,6 +560,13 @@ public:
maxX, maxY, maxZ
);
}
// Rebuild the moving/static entity grids that the radar/map gauge queries.
// The 1995 game fed these from ExecuteImplementation's InterestingEntity
// iterator, which the WinTesla port dropped, so the grids stayed empty and
// the radar found no contacts. Repopulate from the world entity list.
void
RebuildEntityGrid();
void
GetStaticBounds(
Scalar *min_x,