Camera seat LIVE + Mech::PlayerLinkMessageHandler reconstructed (@0049f624)
The spectator/broadcast seat works end-to-end: a hostType=1 +
vehicle=camera pilot page boots a CameraShip whose 62-camera arena1
network loads from the BTL4.RES type-27 resource (the engine's
CreateStreamedCameraInstances existed all along -- the file probe falls
back to it), the BTCameraDirector locks onto the first live mech, and
the ship TRACKS it (sees=1, goal advancing) and CUTS between authored
camera positions (screenshot-verified: wide arena shot -> close
tracking shot).
The missing piece was the Mech override of PlayerLinkMessageHandler
(@0049f624), which the reconstruction never filled. The engine base
resolves mech->player; BT's override adds:
1. the REVERSE link player->playerVehicle = this on EVERY node
(replicants included) -- how the camera director and scoreboard
find a REMOTE player's mech; without it a spectator parks forever
('NO goal entity')
2. clears NonScoringPlayerFlag (0x4000 = bit 14): a pilot with a
vehicle is a SCORING player -- this admits REPLICATED players to
the ranking pass, so cross-node rank/score displays work
3. master only: seeds the heat bank's ambientTemperature (bank
@0x1d4) from the mission [mission] temperature= (BTMission+0xf4)
-- correcting the heat family's 'frozen 300' deviation note (it
was never frozen; THIS is the writer)
Bridge BTSetBankAmbientTemperature lives in heatfamily_reslice.cpp
(mech.cpp cannot include subsystem headers -- local-stub collision).
BT_CAM_LOG diagnostics: camera-network count, director pick + Players
group census, ship follow state, link dispatch/receive.
Verified live: 2-seat (mech + camera) relay session -- replicated
player shows +veh, director goal locked w/ 30s timer, ship tracking a
moving mech through camera cuts; standard 2-node mech smoke PASS
(un-regressed). Lesson re-learned: a 'clean' build filtered on 'error
C' missed a linker file-lock failure -- one whole test cycle ran
against a stale exe (the /FORCE gotcha's cousin; grep -i error, not
error C).
Remaining (task open): ranking-window overlay draw (L4VIDRND stubs),
operator-app camera-seat row, shot polish.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
74d9d3b6ff
commit
4459262b9c
@@ -0,0 +1,310 @@
|
||||
[mission]
|
||||
adventure=BattleTech
|
||||
map=arena1
|
||||
scenario=freeforall
|
||||
time=day
|
||||
weather=clear
|
||||
temperature=27
|
||||
length=600
|
||||
[ordinals]
|
||||
bitmap=Ordinal::BitMap::1
|
||||
bitmap=Ordinal::BitMap::2
|
||||
bitmap=Ordinal::BitMap::3
|
||||
bitmap=Ordinal::BitMap::4
|
||||
[Ordinal::BitMap::1]
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=000038000003C000001FF00000000F00
|
||||
bitmap=0000F8000003C000003FF80000000F00
|
||||
bitmap=0001F8000003C00000707C0000000F00
|
||||
bitmap=0001F8000003C00000603C0000000F00
|
||||
bitmap=00007801FC0FF00000003C3DF807FF00
|
||||
bitmap=00007803FE0FF00000003C3FFC0FFF00
|
||||
bitmap=00007803C703C00000003C3E3C1F0F00
|
||||
bitmap=000078078303C0000000783C1E1E0F00
|
||||
bitmap=000078078003C0000000783C1E1E0F00
|
||||
bitmap=00007807C003C0000000F03C1E1E0F00
|
||||
bitmap=00007807F003C0000001E03C1E1E0F00
|
||||
bitmap=00007803FC03C0000003C03C1E1E0F00
|
||||
bitmap=00007801FE03C0000007803C1E1E0F00
|
||||
bitmap=000078007F03C000000F003C1E1E0F00
|
||||
bitmap=000078001F03C000001E003C1E1E0F00
|
||||
bitmap=000078000F03C000003C003C1E1E0F00
|
||||
bitmap=000078060F03C0000078003C1E1E0F00
|
||||
bitmap=000078071E03E0000078003C1E1F1F00
|
||||
bitmap=00007803FE01F000007FFC3C1E0FFF00
|
||||
bitmap=00007801FC00F000007FFC3C1E07EF00
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
x=128
|
||||
y=32
|
||||
width=8
|
||||
[Ordinal::BitMap::2]
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=001FFF0000003C0000003C03C0780000
|
||||
bitmap=001FFF0000003C0000007C03C0780000
|
||||
bitmap=00000E0000003C000000FC03C0780000
|
||||
bitmap=00003C0000003C000001BC03C0780000
|
||||
bitmap=0000700F3E1FFC000003BC0FF07BF000
|
||||
bitmap=0001E00F7E3FFC0000073C0FF07FF800
|
||||
bitmap=0003800FFE7C3C0000063C03C07C7800
|
||||
bitmap=0007F80FFE783C00000C3C03C0783C00
|
||||
bitmap=0007FE0F80783C0000183C03C0783C00
|
||||
bitmap=00001E0F00783C0000383C03C0783C00
|
||||
bitmap=00000F0F00783C0000703C03C0783C00
|
||||
bitmap=00000F0F00783C00007FFF03C0783C00
|
||||
bitmap=00000F0F00783C00007FFF03C0783C00
|
||||
bitmap=00000F0F00783C0000003C03C0783C00
|
||||
bitmap=00000F0F00783C0000003C03C0783C00
|
||||
bitmap=00000F0F00783C0000003C03C0783C00
|
||||
bitmap=00180F0F00783C0000003C03C0783C00
|
||||
bitmap=001C1F0F007C7C0000003C03E0783C00
|
||||
bitmap=000FFE0F003FFC0000003C01F0783C00
|
||||
bitmap=0007FC0F001FBC0000003C00F0783C00
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
x=128
|
||||
y=32
|
||||
width=8
|
||||
[Ordinal::BitMap::3]
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=001FFF03C07800000000FC03C0780000
|
||||
bitmap=001FFF03C07800000003FC03C0780000
|
||||
bitmap=001E0003C07800000007C003C0780000
|
||||
bitmap=001E0003C0780000000F0003C0780000
|
||||
bitmap=001E000FF07BF000000F000FF07BF000
|
||||
bitmap=001E000FF07FF800001E000FF07FF800
|
||||
bitmap=001E0003C07C7800001E0003C07C7800
|
||||
bitmap=001FFC03C0783C00001EFC03C0783C00
|
||||
bitmap=001FFE03C0783C00001FFE03C0783C00
|
||||
bitmap=00001F03C0783C00001F1F03C0783C00
|
||||
bitmap=00000F03C0783C00001E0F03C0783C00
|
||||
bitmap=00000F03C0783C00001E0F03C0783C00
|
||||
bitmap=00000F03C0783C00001E0F03C0783C00
|
||||
bitmap=00000F03C0783C00001E0F03C0783C00
|
||||
bitmap=00000F03C0783C00001E0F03C0783C00
|
||||
bitmap=00000F03C0783C00001E0F03C0783C00
|
||||
bitmap=00180F03C0783C00001E0F03C0783C00
|
||||
bitmap=001C1F03E0783C00001F1F03E0783C00
|
||||
bitmap=000FFE01F0783C00000FFE01F0783C00
|
||||
bitmap=0007FC00F0783C000007FC00F0783C00
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
x=128
|
||||
y=32
|
||||
width=8
|
||||
[Ordinal::BitMap::4]
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=001FFF03C07800000007FC03C0780000
|
||||
bitmap=001FFF03C0780000000FFE03C0780000
|
||||
bitmap=00000F03C0780000001F1F03C0780000
|
||||
bitmap=00000F03C0780000001E0F03C0780000
|
||||
bitmap=00000F0FF07BF000001E0F0FF07BF000
|
||||
bitmap=00001F0FF07FF800001E0F0FF07FF800
|
||||
bitmap=00001E03C07C7800001E0F03C07C7800
|
||||
bitmap=00003E03C0783C00001E0F03C0783C00
|
||||
bitmap=00003C03C0783C00000F1E03C0783C00
|
||||
bitmap=00003C03C0783C000007FC03C0783C00
|
||||
bitmap=00007803C0783C000007FC03C0783C00
|
||||
bitmap=00007803C0783C00000F1E03C0783C00
|
||||
bitmap=00007803C0783C00001E0F03C0783C00
|
||||
bitmap=0000F003C0783C00001E0F03C0783C00
|
||||
bitmap=0000F003C0783C00001E0F03C0783C00
|
||||
bitmap=0000F003C0783C00001E0F03C0783C00
|
||||
bitmap=0000F003C0783C00001E0F03C0783C00
|
||||
bitmap=0000F003E0783C00000F1E03E0783C00
|
||||
bitmap=0000F001F0783C00000FFE01F0783C00
|
||||
bitmap=0000F000F0783C000007FC00F0783C00
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
x=128
|
||||
y=32
|
||||
width=8
|
||||
[pilots]
|
||||
pilot=10.99.0.1:1502
|
||||
pilot=10.99.0.2:1502
|
||||
[10.99.0.1:1502]
|
||||
hostType=0
|
||||
advancedDamage=1
|
||||
loadzones=1
|
||||
name=PILOT
|
||||
bitmapindex=1
|
||||
experience=expert
|
||||
badge=VGL
|
||||
patch=Yellow
|
||||
role=Role::Default
|
||||
dropzone=one
|
||||
vehicle=bhk1
|
||||
vehicleValue=1000
|
||||
color=White
|
||||
[10.99.0.2:1502]
|
||||
hostType=1
|
||||
advancedDamage=1
|
||||
loadzones=1
|
||||
name=CAMERA
|
||||
bitmapindex=2
|
||||
experience=expert
|
||||
badge=VGL
|
||||
patch=Yellow
|
||||
role=Role::Default
|
||||
dropzone=one
|
||||
vehicle=camera
|
||||
vehicleValue=1000
|
||||
color=White
|
||||
[largebitmap]
|
||||
bitmap=BitMap::Large::PILOT
|
||||
bitmap=BitMap::Large::CAMERA
|
||||
[BitMap::Large::PILOT]
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
x=128
|
||||
y=32
|
||||
width=8
|
||||
[BitMap::Large::CAMERA]
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
bitmap=00000000000000000000000000000000
|
||||
x=128
|
||||
y=32
|
||||
width=8
|
||||
[smallbitmap]
|
||||
bitmap=BitMap::Small::PILOT
|
||||
bitmap=BitMap::Small::CAMERA
|
||||
[BitMap::Small::PILOT]
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
x=64
|
||||
y=16
|
||||
width=4
|
||||
[BitMap::Small::CAMERA]
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
bitmap=0000000000000000
|
||||
x=64
|
||||
y=16
|
||||
width=4
|
||||
[Role::Default]
|
||||
model=dfltrole
|
||||
[Role::NoReturn]
|
||||
model=noretun
|
||||
@@ -35,11 +35,21 @@ authentic path scoped.
|
||||
map** (`FUN_0042be3c` probe → `FUN_0042c078(res, mapname, 0x1b)`; binary records
|
||||
`{count; per-cam {size; type 1|2; pos+quat+...}}`, parsers @0042ad54/@0042b9f8) — and our
|
||||
BTL4.RES has ALL 8 maps' networks (arena1 = 62 cameras; cavern/dbase/grass ~57KB each).
|
||||
[T1] Remaining to make the camera SEAT live: reconstruct the type-27 res loader in the
|
||||
WinTesla CAMMGR (it only has the file flavor), un-stub the ranking-window draw
|
||||
(L4VIDRND.cpp:3016), boot-test `vehicle=camera`. The spectator/broadcast system (director
|
||||
auto-follows the score leader, TV-style camera cuts) is otherwise engine-complete. Status:
|
||||
data in hand, loader reconstruction OPEN.
|
||||
[T1] **CAMERA SEAT LIVE (2026-07-18, same day) [T2]**: the type-27 loader ALREADY existed in
|
||||
the engine (`CreateStreamedCameraInstances`, CAMMGR.cpp:530 — the file probe falls back to it;
|
||||
62 arena1 cameras load, `[cam]` diag under BT_CAM_LOG). The REAL missing piece was
|
||||
**`Mech::PlayerLinkMessageHandler` (@0049f624)** — the BT override the reconstruction never
|
||||
filled: base resolves mech→player; BT adds the REVERSE link `player->playerVehicle = this` on
|
||||
EVERY node (replicants included — how the director/scoreboard find a remote player's mech),
|
||||
clears `NonScoringPlayerFlag` (0x4000 = bit 14: a pilot with a vehicle SCORES/ranks — this
|
||||
also makes cross-node RANKINGS work), and on the master seeds the heat bank's
|
||||
`ambientTemperature` from the mission `temperature=` (mech+0x7dc bank +0x1d4 ← BTMission+0xf4
|
||||
— the heat family's "frozen 300" note stands CORRECTED). Verified live: mech+camera 2-seat
|
||||
relay session — replicated player links (`bmp=1+veh`), director locks the goal (30s timer),
|
||||
camera ship tracks the moving mech (`sees=1`) and CUTS between authored cameras
|
||||
(screenshots). Egg: pilot page `hostType=1` + `vehicle=camera`. Remaining: the
|
||||
ranking-window overlay draw (L4VIDRND.cpp:3016 stubs), a camera-seat row helper in the
|
||||
operator app (hostType not in the roster UI), shot-composition polish. Status: core LIVE.
|
||||
|
||||
## Pod-hardware readiness gaps (Phase 8 assessment, 2026-07-17) [[pod-hardware]]
|
||||
Everything below EXISTS in the tree but has NEVER run against real pod hardware. Mechanism
|
||||
|
||||
@@ -580,6 +580,16 @@ void
|
||||
camera_stream.AdvancePointer(model->instanceSize);
|
||||
}
|
||||
res->Unlock();
|
||||
// BT port diag (BT_CAM_LOG): the camera-seat bring-up needs to know the
|
||||
// network actually loaded (type-27 res, all 8 maps ship in BTL4.RES)
|
||||
if (getenv("BT_CAM_LOG"))
|
||||
{
|
||||
int n = 0;
|
||||
SChainIteratorOf<CameraInstance*> it(cameraList);
|
||||
while (it.ReadAndNext() != NULL) ++n;
|
||||
DEBUG_STREAM << "[cam] streamed camera network '" << map_name
|
||||
<< "': " << n << " camera(s) loaded\n" << std::flush;
|
||||
}
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -314,11 +314,30 @@ void
|
||||
//
|
||||
if (!goalEntity)
|
||||
{
|
||||
// BT port diag (BT_CAM_LOG, 1 Hz): parked with no goal
|
||||
if (getenv("BT_CAM_LOG"))
|
||||
{
|
||||
static float s_ng = 0.0f; s_ng += time_slice;
|
||||
if (s_ng >= 1.0f) { s_ng = 0.0f;
|
||||
DEBUG_STREAM << "[cam] ship: NO goal entity (parked)\n"
|
||||
<< std::flush; }
|
||||
}
|
||||
return;
|
||||
}
|
||||
Check(goalEntity);
|
||||
Point3D target;
|
||||
target.Multiply(focusOffset, goalEntity->localToWorld);
|
||||
// BT port diag (BT_CAM_LOG, 1 Hz): live follow state
|
||||
if (getenv("BT_CAM_LOG"))
|
||||
{
|
||||
static float s_fg = 0.0f; s_fg += time_slice;
|
||||
if (s_fg >= 1.0f) { s_fg = 0.0f;
|
||||
DEBUG_STREAM << "[cam] ship: goal at (" << target.x << ","
|
||||
<< target.z << ") cam=" << (void*)currentCamera
|
||||
<< " sees=" << (currentCamera
|
||||
? (int)currentCamera->CanCameraSee(target) : -1)
|
||||
<< "\n" << std::flush; }
|
||||
}
|
||||
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
@@ -247,6 +247,39 @@ void
|
||||
}
|
||||
}
|
||||
|
||||
// BT port diag (BT_CAM_LOG, 1 Hz): why is/isn't the director tracking
|
||||
if (getenv("BT_CAM_LOG"))
|
||||
{
|
||||
static float s_acc = 0.0f; s_acc += time_slice;
|
||||
if (s_acc >= 1.0f)
|
||||
{
|
||||
s_acc = 0.0f;
|
||||
DEBUG_STREAM << "[cam] director pick: player=" << (void*)player
|
||||
<< " vehicle=" << (void*)vehicle
|
||||
<< " goal=" << (void*)GetGoalEntity()
|
||||
<< " timer=" << timeLeftOnPlayer;
|
||||
// who IS in the Players group here?
|
||||
EntityGroup *pg =
|
||||
application->GetEntityManager()->FindGroup("Players");
|
||||
if (pg)
|
||||
{
|
||||
DEBUG_STREAM << " group:[";
|
||||
Player *p;
|
||||
ChainIteratorOf<Node*> it(pg->groupMembers);
|
||||
while ((p = (Player *)it.ReadAndNext()) != NULL)
|
||||
{
|
||||
DEBUG_STREAM << " bmp=" << p->playerBitmapIndex
|
||||
<< (p->GetPlayerVehicle() ? "+veh" : "-veh");
|
||||
}
|
||||
DEBUG_STREAM << " ]";
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_STREAM << " group:MISSING";
|
||||
}
|
||||
DEBUG_STREAM << "\n" << std::flush;
|
||||
}
|
||||
}
|
||||
if (player == 0 || vehicle == 0)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -1074,6 +1074,10 @@ void
|
||||
|
||||
playerVehicle->Dispatch(&player_link_message);
|
||||
playerVehicle->DispatchToReplicants(&player_link_message);
|
||||
if (getenv("BT_CAM_LOG"))
|
||||
DEBUG_STREAM << "[cam] InitializePlayerLink dispatched (player "
|
||||
<< GetEntityID() << " -> vehicle "
|
||||
<< playerVehicle->GetEntityID() << ")\n" << std::flush;
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
|
||||
@@ -765,6 +765,23 @@ AggregateHeatSink::AttributeIndexSet&
|
||||
return attributeIndex;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// BTSetBankAmbientTemperature -- bridge for Mech::PlayerLinkMessageHandler
|
||||
// (@0049f624 writes bank+0x1d4 = mission temperature): mech.cpp cannot see
|
||||
// AggregateHeatSink (local-stub collision), so the write lands here where the
|
||||
// type is complete. This is the AUTHENTIC ambientTemperature writer -- the
|
||||
// old "frozen 300" note stands corrected (the ctor default only holds until
|
||||
// the mission's PlayerLink pass runs on the master).
|
||||
//
|
||||
void
|
||||
BTSetBankAmbientTemperature(Subsystem *bank, Scalar temperature)
|
||||
{
|
||||
if (bank != NULL)
|
||||
{
|
||||
((AggregateHeatSink *)bank)->ambientTemperature = temperature;
|
||||
}
|
||||
}
|
||||
|
||||
//#############################################################################
|
||||
// Shared Data Support
|
||||
//
|
||||
|
||||
@@ -80,6 +80,12 @@
|
||||
// for the same reason.
|
||||
#include "dmgtable.hpp"
|
||||
extern Scalar BTGetTorsoTwist(Subsystem *torso); // torso.cpp (Torso complete there)
|
||||
// heat-bank ambient bridge (heatfamily_reslice.cpp, AggregateHeatSink complete
|
||||
// there) -- mech.cpp cannot include the subsystem headers (local-stub collision)
|
||||
extern void BTSetBankAmbientTemperature(Subsystem *bank, Scalar temperature);
|
||||
#if !defined(BTMSSN_HPP)
|
||||
# include <btmssn.hpp> // BTMission::GetMissionTemperature (PlayerLink)
|
||||
#endif
|
||||
#if !defined(APP_HPP)
|
||||
# include <app.hpp>
|
||||
#endif
|
||||
@@ -454,6 +460,7 @@ const Receiver::HandlerEntry
|
||||
Mech::MessageHandlerEntries[] =
|
||||
{
|
||||
MESSAGE_ENTRY(Mech, TakeDamage),
|
||||
MESSAGE_ENTRY(Mech, PlayerLink),
|
||||
};
|
||||
|
||||
Receiver::MessageHandlerSet
|
||||
@@ -609,6 +616,52 @@ Scalar
|
||||
return tmpl ? tmpl->maxY : 0.0f; // ResolveHit guards <= 0
|
||||
}
|
||||
|
||||
//
|
||||
// Mech override of Entity::PlayerLinkMessageHandler (binary @0049f624). The
|
||||
// engine base resolves the FORWARD link (mech->playerLink @0x190 from the
|
||||
// message's playerID); BT then:
|
||||
// 1. sets the REVERSE link player->playerVehicle = this -- on EVERY node,
|
||||
// replicants included. This is how the 1995 camera director
|
||||
// (BeABTDirector's GetPlayerByIndex -> GetPlayerVehicle) and the
|
||||
// scoreboard find a REMOTE player's mech; without it a spectator seat
|
||||
// parks forever ("no goal entity", camera-seat bring-up 2026-07-18).
|
||||
// 2. clears the player's NonScoringPlayerFlag (0x4000 == bit 14): a pilot
|
||||
// with a vehicle is a SCORING player -- this is what admits them to the
|
||||
// ranking pass (Player::IsScoringPlayer gates RankPlayers).
|
||||
// 3. master only: seeds the heat bank's ambientTemperature (@0x1d4 on the
|
||||
// 0xBBE AggregateHeatSink at mech+0x7dc) from the mission's [mission]
|
||||
// temperature (BTMission+0xf4) -- resolving the heat family's
|
||||
// "frozen 300" deviation note: it was never frozen, THIS writes it.
|
||||
//
|
||||
void
|
||||
Mech::PlayerLinkMessageHandler(PlayerLinkMessage *message)
|
||||
{
|
||||
Check(message);
|
||||
Entity::PlayerLinkMessageHandler(message); // FUN_0041fd18: mech+0x190
|
||||
|
||||
Player *owner = GetPlayerLink();
|
||||
if (getenv("BT_CAM_LOG"))
|
||||
DEBUG_STREAM << "[cam] Mech::PlayerLink inst="
|
||||
<< (int)(GetInstance() == ReplicantInstance)
|
||||
<< " owner=" << (void*)owner << "\n" << std::flush;
|
||||
if (owner != NULL)
|
||||
{
|
||||
owner->SetPlayerVehicle(this); // player+0x1fc = this
|
||||
owner->simulationFlags &= ~Player::NonScoringPlayerFlag; // &= ~0x4000
|
||||
|
||||
if (GetInstance() != ReplicantInstance && sensorSubsystem != NULL)
|
||||
{
|
||||
Mission *mission = owner->GetMission();
|
||||
if (mission != NULL)
|
||||
{
|
||||
BTSetBankAmbientTemperature(sensorSubsystem,
|
||||
((BTMission *)mission)->GetMissionTemperature());
|
||||
}
|
||||
}
|
||||
}
|
||||
Check_Fpu();
|
||||
}
|
||||
|
||||
//
|
||||
// Mech override of Entity::TakeDamageMessageHandler (binary @0x4a037a, the two
|
||||
// call sites into the glue @0x49ed0c). An unaimed hit arrives with
|
||||
|
||||
@@ -1165,6 +1165,14 @@ protected:
|
||||
// Mech override of Entity::TakeDamageMessageHandler: resolve an unaimed
|
||||
// (invalidDamageZone) hit's zone via the cylinder table, then base-route.
|
||||
void TakeDamageMessageHandler(TakeDamageMessage *message);
|
||||
// Mech override of Entity::PlayerLinkMessageHandler (@0049f624): the
|
||||
// base resolves mech->player; BT adds the REVERSE link
|
||||
// player->playerVehicle = this on EVERY node (replicants included --
|
||||
// this is how the camera director / scoreboard find a remote player's
|
||||
// mech), clears the player's NonScoringPlayerFlag (a pilot with a
|
||||
// vehicle SCORES/ranks), and on the master seeds the heat bank's
|
||||
// ambientTemperature from the mission's [mission] temperature.
|
||||
void PlayerLinkMessageHandler(PlayerLinkMessage *message);
|
||||
|
||||
// --- damage-routing support (mechdmg / mech4) -----------------------
|
||||
// Typed access to the inherited Entity::damageZones[] (engine stores DamageZone*;
|
||||
|
||||
Reference in New Issue
Block a user