gauge wave P3: fix the DEATHS runaway + RANK=-1 (solo scoreboard correct)
RANK=-1: Player::DefaultFlags creates every player NonScoring (CalcRanking only ranks IsScoringPlayer()==true, else -1), and the bring-up never cleared it. Call SetScoringPlayerFlag() in DropZoneReplyMessageHandler's mech branch (a piloted mech IS an active scoring combatant; the camera-ship branch stays non-scoring). -> RANK=0. DEATHS runaway (climbed ~1/s, not the "1" first seen): @004c012c -- which our MESSAGE_ENTRY binds as the VehicleDead handler -- is actually the drop-zone RESPAWN-RETRY helper. The engine's RequestDropZone (PLAYER.cpp:400) posts a 2s-delayed VehicleDead(deathCount=-2) as a "did the drop zone reply?" timer; our handler ++deathCount + RE-POSTED it UNCONDITIONALLY -> an infinite loop, because the drop-zone handshake never "completes" in the bring-up (no console/drop-zone system). Traced it to a pure boot artifact (13 fires with zero combat; the only VehicleDead producers are the re-post + my kill-producer, and the kill fires AFTER the loop starts). FIX (correct respawn-retry semantics): if the player already has a vehicle the drop zone WAS acquired (the DropZoneReply created it), so the retry is moot -- return without counting a death or re-posting. -> DEATHS=0 in solo, loop gone. Verified DBASE+dev gauges: the Comm roster shows KILLS=1 / DEATHS=0; the KILL log reads killCount=1 deaths=0 score=164 rank=0; 0 crashes. (MP real-death DEATHS -- a destroyed vehicle via the separate @004c05c4 path -- remains deferred per the plan; solo never dies so the retry gate is correct there.) 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
99e2078b83
commit
a9210e038a
@@ -237,6 +237,28 @@ void
|
|||||||
Check(this);
|
Check(this);
|
||||||
Check(message);
|
Check(message);
|
||||||
|
|
||||||
|
//
|
||||||
|
// scoring wave (DEATHS fix): @004c012c is the drop-zone RESPAWN-RETRY helper --
|
||||||
|
// the engine's RequestDropZone (PLAYER.cpp:400) posts a 2s-delayed VehicleDead
|
||||||
|
// (deathCount=-2) as a "did the drop zone reply?" timer. If the player already
|
||||||
|
// has a vehicle, the drop zone WAS acquired (the DropZoneReply created it) -> the
|
||||||
|
// retry is moot: don't count a death and don't re-post. The prior unconditional
|
||||||
|
// ++deathCount + re-post was an INFINITE loop in solo (the drop-zone handshake
|
||||||
|
// never "completes" in the bring-up), climbing deathCount ~1/s. (A real MP death
|
||||||
|
// -- vehicle destroyed -> playerVehicle cleared/the @004c05c4 path -- is deferred.)
|
||||||
|
//
|
||||||
|
if (playerVehicle != 0)
|
||||||
|
{
|
||||||
|
deathPending = 0; // this+0x290
|
||||||
|
suppressConsole = 0; // this+0x258
|
||||||
|
Check_Fpu();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getenv("BT_SCORE_LOG"))
|
||||||
|
DEBUG_STREAM << "[score] VehicleDeadMessageHandler: deathCount " << deathCount
|
||||||
|
<< " -> " << (deathCount + 1) << "\n" << std::flush;
|
||||||
|
|
||||||
//
|
//
|
||||||
// One more death; tell the message (so replicants stay in sync) and
|
// One more death; tell the message (so replicants stay in sync) and
|
||||||
// debit a life against the scoring role.
|
// debit a life against the scoring role.
|
||||||
@@ -823,6 +845,11 @@ void
|
|||||||
Check(this);
|
Check(this);
|
||||||
Check(message);
|
Check(message);
|
||||||
|
|
||||||
|
if (getenv("BT_SCORE_LOG"))
|
||||||
|
DEBUG_STREAM << "[score] DropZoneReply: hasVehicle=" << (playerVehicle != 0)
|
||||||
|
<< " deathCount=" << deathCount << " msgDeath=" << message->deathCount
|
||||||
|
<< " state=" << (int)GetSimulationState() << "\n" << std::flush;
|
||||||
|
|
||||||
if (!playerVehicle) // param_1[0x7f] == 0
|
if (!playerVehicle) // param_1[0x7f] == 0
|
||||||
{
|
{
|
||||||
CreatePlayerVehicle(message->dropZoneLocation); // (**vtable+0x40)(origin)
|
CreatePlayerVehicle(message->dropZoneLocation); // (**vtable+0x40)(origin)
|
||||||
@@ -836,6 +863,11 @@ void
|
|||||||
if (playerVehicle->GetClassID() == Mech::MechClassID) // 0xbb9
|
if (playerVehicle->GetClassID() == Mech::MechClassID) // 0xbb9
|
||||||
{
|
{
|
||||||
SetPerformance(&BTPlayer::PlayerSimulation); // perf @00513058
|
SetPerformance(&BTPlayer::PlayerSimulation); // perf @00513058
|
||||||
|
// scoring wave (RANK fix): an active mech combatant is a SCORING player.
|
||||||
|
// Player::DefaultFlags creates every player NonScoring (rank -1 until
|
||||||
|
// activated); CalcRanking only ranks IsScoringPlayer()==true. The camera
|
||||||
|
// ship (below) stays non-scoring; a piloted mech becomes scoring here.
|
||||||
|
SetScoringPlayerFlag(); // clear NonScoringPlayerFlag
|
||||||
}
|
}
|
||||||
else // camera ship (0x45)
|
else // camera ship (0x45)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user