Departed-pod resilience: collision guard + console loss ends the race
Round six raced all three machines (staging fix confirmed) and then exposed what happens when a pod leaves mid-mission - which arcade pods never did. The B crash dump named it exactly: VTV::TakeDamageMessageHandler resolved message->inflictingEntity to NULL (the entity belonged to the departed owner) and dereferenced it - Verify is compiled out in release. Collision damage from an entity that no longer exists is now ignored. And the race B and C were left in was a zombie: the owner (console) had aborted, so the mission clock would count up forever and the death/respawn flow hung with nobody to arbitrate. Lobby-member races now set gConsoleLossEndsMission: losing the console mid-mission posts StopMission locally, the pod tears down, and lands back in the lobby room. Arcade -net pods keep the re-listen-and-wait behavior. Loopback hosted race still green. For the drivers: the ampersand key is the arcade mission-abort - that was every crash-on-keypress so far; and a sleeping Bluetooth pad wakes on the Xbox button and hot-connects within 3 seconds (PadRIO re-probes). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,9 @@ void (*gPerFrameHook)() = NULL;
|
||||
// an in-process console owns the launch (hosted network races)
|
||||
Logical gConsoleMarshalsLaunch = False;
|
||||
|
||||
// losing the console mid-mission ends it (lobby-member races)
|
||||
Logical gConsoleLossEndsMission = False;
|
||||
|
||||
ApplicationManager* ApplicationManager::CurrentAppManager = NULL;
|
||||
|
||||
ApplicationManager::ApplicationManager(HINSTANCE hInstance, HWND hWnd, Scalar frame_rate) : Node(ApplicationManagerClassID), runningApplications(this)
|
||||
|
||||
@@ -14,6 +14,12 @@ extern void (*gPerFrameHook)();
|
||||
// single player leaves it False and auto-runs exactly as always.
|
||||
extern Logical gConsoleMarshalsLaunch;
|
||||
|
||||
// True for lobby-member races: losing the console mid-mission ends the
|
||||
// mission (the owner left - without a console the timer counts up
|
||||
// forever). Arcade -net pods leave it False and re-listen for their
|
||||
// console to return, exactly as always.
|
||||
extern Logical gConsoleLossEndsMission;
|
||||
|
||||
class ApplicationManager : public Node
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#include "l4host.h"
|
||||
#include "l4net.h"
|
||||
#include "l4nettransport.h"
|
||||
#include "..\munga\appmgr.h"
|
||||
#include "..\munga\appmsg.h"
|
||||
#include "..\munga\mission.h"
|
||||
#include "..\munga\notation.h"
|
||||
//#include <netnub.hpp>
|
||||
@@ -1000,6 +1002,20 @@ void L4NetworkManager::HostDisconnectedMessageHandler(HostDisconnectedMessage* H
|
||||
#else
|
||||
myConsoleHost = 0;
|
||||
#endif
|
||||
//
|
||||
// Lobby-member races: the departed console was the race
|
||||
// owner - without a console the mission clock counts up
|
||||
// forever, so end the mission and get back to the lobby
|
||||
// room. (Arcade pods keep the listen above and wait for
|
||||
// their console to return.)
|
||||
//
|
||||
if (gConsoleLossEndsMission &&
|
||||
application->GetApplicationState() == Application::RunningMission)
|
||||
{
|
||||
DEBUG_STREAM << "Console lost mid-race - ending the mission\n" << std::flush;
|
||||
Application::StopMissionMessage stop_message(0);
|
||||
application->Post(DefaultEventPriority, application, &stop_message);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
+10
@@ -179,6 +179,16 @@ void
|
||||
Check(host);
|
||||
Mover
|
||||
*mover = (Mover*)host->GetEntityPointer(message->inflictingEntity);
|
||||
if (mover == NULL)
|
||||
{
|
||||
//
|
||||
// The inflicting entity is gone - its pod left the race
|
||||
// mid-mission (consumer multiplayer; arcade pods never
|
||||
// left). Nothing to bounce against.
|
||||
//
|
||||
Check_Fpu();
|
||||
return;
|
||||
}
|
||||
Verify(mover->IsDerivedFrom(Mover::GetClassDerivations()));
|
||||
Vector3D
|
||||
v;
|
||||
|
||||
+5
-1
@@ -298,12 +298,16 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
//
|
||||
// Lobby member: enter the race as a network pod. The
|
||||
// owner's console connects over the wire, feeds the egg,
|
||||
// and marshals us - no local egg, no local console.
|
||||
// and marshals us - no local egg, no local console. If
|
||||
// the owner leaves mid-race the mission ends (a race
|
||||
// with no console never stops on its own).
|
||||
//
|
||||
L4Application::SetNetworkCommonFlatAddress(1501);
|
||||
gConsoleLossEndsMission = True;
|
||||
}
|
||||
else
|
||||
{
|
||||
gConsoleLossEndsMission = False;
|
||||
L4Application::SetEggNotationFileName(frontend_egg);
|
||||
|
||||
// Front-end games are marshaled by the in-process console:
|
||||
|
||||
Reference in New Issue
Block a user