diff --git a/RP_L4/RPL4CONSOLE.cpp b/RP_L4/RPL4CONSOLE.cpp index 7421e59..8e57baf 100644 --- a/RP_L4/RPL4CONSOLE.cpp +++ b/RP_L4/RPL4CONSOLE.cpp @@ -81,6 +81,9 @@ namespace NetTransport::Connection connection; int state; // last reported application state (-1 unknown) + int lastScore; // last telemetry score heard mid-race + int lastScoreHostID; // the host ID the pod itself reported + Logical haveScore; // any telemetry score at all yet Logical eggAcknowledged; DWORD lastQueryTick; DWORD eggSentTick; // 0 = never sent @@ -300,7 +303,27 @@ namespace (int) message->GetFinalScore()); pod->scored = True; } - // VTV telemetry (IDs 2-6) skips through for now + // + // Running telemetry. The pods have been sending it all + // along (it fed the arcade console's status board); this + // console skipped it - until a player Alt+Q'ed mid-race + // and vanished from the score sheet, because a pod that + // leaves never sends its EndMission score. Keep the last + // score heard, and the host ID the pod itself reported + // with it, so the buzzer can stand it in for a pod that + // is not there to answer. Leaving early keeps the points + // earned; it just stops earning more. + // + else if ((int) base->messageID == + ConsolePlayerVTVScoreUpdateMessageID) + { + ConsolePlayerVTVScoreUpdateMessage *message = + (ConsolePlayerVTVScoreUpdateMessage *) base; + pod->lastScore = (int) message->GetPlayerScore(); + pod->lastScoreHostID = (int) message->GetPlayerHostID(); + pod->haveScore = True; + } + // the rest of the telemetry (IDs 2-4, 6) skips through } else if ((int) header->clientID == (int) NetworkClient::NetworkManagerClientID) { @@ -914,6 +937,27 @@ namespace else if (AllRemotesScored() || (LONG)(GetTickCount() - gRemoteStopTick) >= 5000) { + // + // Stand in for anyone who is not here to answer. A pod + // that left mid-race - Alt+Q, a crash, a dropped link - + // never sends EndMission, and used to vanish from the + // score sheet as though it had not raced at all. Its + // last telemetry score is the score it left with. + // + for (int i = 0; i < gRemotePodCount; ++i) + { + if (!gRemotePods[i].scored && gRemotePods[i].haveScore) + { + DEBUG_STREAM << "LocalConsole: " + << gRemotePods[i].address + << " never reported - keeping its last" + << " telemetry score\n" << std::flush; + CollectFinalScore( + gRemotePods[i].lastScoreHostID, + gRemotePods[i].lastScore); + gRemotePods[i].scored = True; + } + } DispatchLocalStop(); DisconnectRemotes(); } diff --git a/RP_L4/RPL4LOBBY.cpp b/RP_L4/RPL4LOBBY.cpp index 7e1f1ba..a5784f2 100644 --- a/RP_L4/RPL4LOBBY.cpp +++ b/RP_L4/RPL4LOBBY.cpp @@ -1604,10 +1604,19 @@ void // // The owner publishes right after its race teardown - ours may - // finish first, so give the sheet a moment to arrive + // finish first, so give the sheet a moment to arrive. + // + // Unless WE aborted. An Alt+Q leaves a race that is still running + // everywhere else, and its sheet will not exist for minutes - the + // eight second wait below was eight seconds of frozen window for a + // player who had just asked to leave. Exit_Code carries the abort + // (the race loop resets it after the menu); take one free look and + // otherwise skip - the sheet's nonce keeps it eligible to show + // after the race actually ends. // const char *sheet = NULL; - DWORD deadline = GetTickCount() + 8 * 1000; + DWORD deadline = (Exit_Code != 0) + ? GetTickCount() : GetTickCount() + 8 * 1000; for (;;) { SteamAPI_RunCallbacks();