diff --git a/src/events.cpp b/src/events.cpp index 1baa9b1d3..0b8802c91 100755 --- a/src/events.cpp +++ b/src/events.cpp @@ -301,7 +301,7 @@ void E_InitStaticHandlers(bool map) void E_Shutdown(bool map) { // delete handlers. - for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next) + for (DStaticEventHandler* handler = E_LastEventHandler; handler; handler = handler->prev) { if (handler->IsStatic() == !map) handler->Destroy(); @@ -515,11 +515,16 @@ bool E_CheckReplacement( PClassActor *replacee, PClassActor **replacement ) return final; } -void E_NewGame() +void E_NewGame(bool map) { + // Shut down all per-map event handlers before static NewGame events. + if (!map) + E_Shutdown(true); + for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next) { - handler->NewGame(); + if (handler->IsStatic() == !map) + handler->NewGame(); } } diff --git a/src/events.h b/src/events.h index 456db6c10..cacc78ce7 100755 --- a/src/events.h +++ b/src/events.h @@ -73,7 +73,7 @@ void E_Console(int player, FString name, int arg1, int arg2, int arg3, bool manu bool E_CheckReplacement(PClassActor* replacee, PClassActor** replacement); // called on new game -void E_NewGame(); +void E_NewGame(bool map); // send networked event. unified function. bool E_SendNetworkEvent(FString name, int arg1, int arg2, int arg3, bool manual); diff --git a/src/g_game.cpp b/src/g_game.cpp index f5d9b5d98..2758b3c17 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1054,7 +1054,7 @@ void G_Ticker () switch (gameaction) { case ga_loadlevel: - G_DoLoadLevel (-1, false); + G_DoLoadLevel (-1, false, false); break; case ga_recordgame: G_CheckDemoStatus(); diff --git a/src/g_level.cpp b/src/g_level.cpp index 36843919b..69514f690 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -526,11 +526,8 @@ void G_InitNew (const char *mapname, bool bTitleLevel) { gamestate = GS_LEVEL; } - G_DoLoadLevel (0, false); - if(!savegamerestore) - { - E_NewGame(); - } + + G_DoLoadLevel (0, false, !savegamerestore); } // @@ -744,7 +741,7 @@ void G_DoCompleted (void) if (gamestate == GS_TITLELEVEL) { level.MapName = nextlevel; - G_DoLoadLevel (startpos, false); + G_DoLoadLevel (startpos, false, false); startpos = 0; viewactive = true; return; @@ -919,7 +916,7 @@ void DAutosaver::Tick () extern gamestate_t wipegamestate; -void G_DoLoadLevel (int position, bool autosave) +void G_DoLoadLevel (int position, bool autosave, bool newGame) { static int lastposition = 0; gamestate_t oldgs = gamestate; @@ -1005,7 +1002,12 @@ void G_DoLoadLevel (int position, bool autosave) level.maptime = 0; - P_SetupLevel (level.MapName, position); + if (newGame) + { + E_NewGame(false); + } + + P_SetupLevel (level.MapName, position, newGame); AM_LevelInit(); @@ -1253,7 +1255,7 @@ void G_DoWorldDone (void) level.MapName = nextlevel; } G_StartTravel (); - G_DoLoadLevel (startpos, true); + G_DoLoadLevel (startpos, true, false); startpos = 0; gameaction = ga_nothing; viewactive = true; diff --git a/src/g_level.h b/src/g_level.h index 98bdb4229..a98a8d415 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -507,7 +507,7 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill void G_StartTravel (); int G_FinishTravel (); -void G_DoLoadLevel (int position, bool autosave); +void G_DoLoadLevel (int position, bool autosave, bool newGame); void G_InitLevelLocals (void); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 7ff907f8a..a9414a776 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -3642,7 +3642,7 @@ void P_FreeExtraLevelData() // //=========================================================================== -void P_SetupLevel (const char *lumpname, int position) +void P_SetupLevel (const char *lumpname, int position, bool newGame) { cycle_t times[20]; #if 0 @@ -3720,6 +3720,11 @@ void P_SetupLevel (const char *lumpname, int position) level.lumpnum = map->lumpnum; hasglnodes = false; + if (newGame) + { + E_NewGame(true); + } + // [RH] Support loading Build maps (because I felt like it. :-) buildmap = false; #if 0 @@ -4298,13 +4303,13 @@ void P_Init () } static void P_Shutdown () -{ - // [ZZ] delete global event handlers - DThinker::DestroyThinkersInList(STAT_STATIC); - E_Shutdown(false); +{ + DThinker::DestroyThinkersInList(STAT_STATIC); P_DeinitKeyMessages (); P_FreeLevelData (); P_FreeExtraLevelData (); + // [ZZ] delete global event handlers + E_Shutdown(false); ST_Clear(); FS_Close(); for (auto &p : players) diff --git a/src/p_setup.h b/src/p_setup.h index b9c680632..31612894b 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -138,7 +138,7 @@ bool P_CheckMapData(const char * mapname); // [RH] The only parameter used is mapname, so I removed playermask and skill. // On September 1, 1998, I added the position to indicate which set // of single-player start spots should be spawned in the level. -void P_SetupLevel (const char *mapname, int position); +void P_SetupLevel (const char *mapname, int position, bool newGame); void P_FreeLevelData(); void P_FreeExtraLevelData();