diff --git a/MUNGA/APPMGR.cpp b/MUNGA/APPMGR.cpp index 390aae2..6dbad56 100644 --- a/MUNGA/APPMGR.cpp +++ b/MUNGA/APPMGR.cpp @@ -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) diff --git a/MUNGA/APPMGR.h b/MUNGA/APPMGR.h index eac4952..ac52fdc 100644 --- a/MUNGA/APPMGR.h +++ b/MUNGA/APPMGR.h @@ -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: diff --git a/MUNGA_L4/L4NET.CPP b/MUNGA_L4/L4NET.CPP index 2d1c5ef..996cf4c 100644 --- a/MUNGA_L4/L4NET.CPP +++ b/MUNGA_L4/L4NET.CPP @@ -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 @@ -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: diff --git a/RP/VTV.cpp b/RP/VTV.cpp index 2d4eea9..d94e49f 100644 --- a/RP/VTV.cpp +++ b/RP/VTV.cpp @@ -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; diff --git a/RP_L4/RPL4.CPP b/RP_L4/RPL4.CPP index 1048cdd..a0ca74b 100644 --- a/RP_L4/RPL4.CPP +++ b/RP_L4/RPL4.CPP @@ -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: