diff --git a/src/d_main.cpp b/src/d_main.cpp index cefd446b9..55db3cc71 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -170,7 +170,7 @@ CUSTOM_CVAR (Int, fraglimit, 0, CVAR_SERVERINFO) if (playeringame[i] && self <= D_GetFragCount(&players[i])) { Printf ("%s\n", GStrings("TXT_FRAGLIMIT")); - G_ExitLevel (0, false); + level.ExitLevel (0, false); break; } } diff --git a/src/d_net.cpp b/src/d_net.cpp index abd703d13..33a6a3f3c 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2222,7 +2222,7 @@ void Net_DoCommand (int type, uint8_t **stream, int player) // Using LEVEL_NOINTERMISSION tends to throw the game out of sync. // That was a long time ago. Maybe it works now? level.flags |= LEVEL_CHANGEMAPCHEAT; - G_ChangeLevel(s, pos, 0); + level.ChangeLevel(s, pos, 0); break; case DEM_SUICIDE: @@ -2659,7 +2659,7 @@ void Net_DoCommand (int type, uint8_t **stream, int player) case DEM_FINISHGAME: // Simulate an end-of-game action - G_ChangeLevel(NULL, 0, 0); + level.ChangeLevel(NULL, 0, 0); break; case DEM_NETEVENT: diff --git a/src/dobjgc.cpp b/src/dobjgc.cpp index 94d6a946c..2b8aefd58 100644 --- a/src/dobjgc.cpp +++ b/src/dobjgc.cpp @@ -296,7 +296,7 @@ static void MarkRoot() } // Mark sectors. - for auto Level : AllLevels()) + for (auto Level : AllLevels()) { Level->Mark(); } diff --git a/src/fragglescript/t_cmd.cpp b/src/fragglescript/t_cmd.cpp index f3673c277..593b72e03 100644 --- a/src/fragglescript/t_cmd.cpp +++ b/src/fragglescript/t_cmd.cpp @@ -77,7 +77,7 @@ static void FS_Gimme(const char * what) // //========================================================================== -void FS_MapCmd(FScanner &sc) +void FS_MapCmd(FLevelLocals *Level, FScanner &sc) { char nextmap[9]; int NextSkill = -1; @@ -108,7 +108,7 @@ void FS_MapCmd(FScanner &sc) flags &= ~(CHANGELEVEL_RESETINVENTORY|CHANGELEVEL_RESETHEALTH); } } - G_ChangeLevel(nextmap, 0, flags, NextSkill); + Level->ChangeLevel(nextmap, 0, flags, NextSkill); } //========================================================================== @@ -168,7 +168,7 @@ void FS_EmulateCmd(FLevelLocals *Level, char * string) } else if (sc.Compare("map")) { - FS_MapCmd(sc); + FS_MapCmd(Level, sc); } else if (sc.Compare("gr_fogdensity")) { diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index e6f2a583e..1dccf3f35 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -608,7 +608,7 @@ void FParser::SF_Clock(void) void FParser::SF_ExitLevel(void) { - G_ExitLevel(0, false); + Level->ExitLevel(0, false); } //========================================================================== @@ -2825,7 +2825,7 @@ void FParser::SF_AmbientSound(void) void FParser::SF_ExitSecret(void) { - G_SecretExitLevel(0); + Level->SecretExitLevel(0); } diff --git a/src/g_level.cpp b/src/g_level.cpp index 24fa264a5..94a985066 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -569,16 +569,19 @@ static bool unloading; EXTERN_CVAR(Bool, sv_singleplayerrespawn) -void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill) +void FLevelLocals::ChangeLevel(const char *levelname, int position, int flags, int nextSkill) { - level_info_t *nextinfo = NULL; + if (this != currentUILevel) return; // only the primary level may exit. + + FString nextlevel; + level_info_t *nextinfo = nullptr; if (unloading) { Printf (TEXTCOLOR_RED "Unloading scripts cannot exit the level again.\n"); return; } - if (gameaction == ga_completed && !(level.i_compatflags2 & COMPATF2_MULTIEXIT)) // do not exit multiple times. + if (gameaction == ga_completed && !(i_compatflags2 & COMPATF2_MULTIEXIT)) // do not exit multiple times. { return; } @@ -587,9 +590,9 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill { // end the game levelname = NULL; - if (!level.NextMap.Compare("enDSeQ",6)) + if (!NextMap.Compare("enDSeQ",6)) { - nextlevel = level.NextMap; // If there is already an end sequence please leave it alone! + nextlevel = NextMap; // If there is already an end sequence please leave it alone! } else { @@ -625,15 +628,14 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill if (flags & CHANGELEVEL_NOINTERMISSION) { - level.flags |= LEVEL_NOINTERMISSION; + flags |= LEVEL_NOINTERMISSION; } - cluster_info_t *thiscluster = FindClusterInfo (level.cluster); + cluster_info_t *thiscluster = FindClusterInfo (cluster); cluster_info_t *nextcluster = nextinfo? FindClusterInfo (nextinfo->cluster) : NULL; startpos = position; - gameaction = ga_completed; - level.SetMusicVolume(1.0); + SetMusicVolume(1.0); if (nextinfo != NULL) { @@ -655,18 +657,18 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill // [RH] Give scripts a chance to do something unloading = true; - level.Behaviors.StartTypedScripts (SCRIPT_Unloading, NULL, false, 0, true); + Behaviors.StartTypedScripts (SCRIPT_Unloading, NULL, false, 0, true); // [ZZ] safe world unload E_WorldUnloaded(); // [ZZ] unsafe world unload (changemap != map) E_WorldUnloadedUnsafe(); unloading = false; - STAT_ChangeLevel(nextlevel, &level); + STAT_ChangeLevel(nextlevel, this); if (thiscluster && (thiscluster->flags & CLUSTER_HUB)) { - if ((level.flags & LEVEL_NOINTERMISSION) || ((nextcluster == thiscluster) && !(thiscluster->flags & CLUSTER_ALLOWINTERMISSION))) + if ((flags & LEVEL_NOINTERMISSION) || ((nextcluster == thiscluster) && !(thiscluster->flags & CLUSTER_ALLOWINTERMISSION))) NoWipe = 35; D_DrawIcon = "TELEICON"; } @@ -682,7 +684,7 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill // If this is co-op, respawn any dead players now so they can // keep their inventory on the next map. - if ((multiplayer || level.flags2 & LEVEL2_ALLOWRESPAWN || sv_singleplayerrespawn || !!G_SkillProperty(SKILLP_PlayerRespawn)) + if ((multiplayer || flags2 & LEVEL2_ALLOWRESPAWN || sv_singleplayerrespawn || !!G_SkillProperty(SKILLP_PlayerRespawn)) && !deathmatch && player->playerstate == PST_DEAD) { // Copied from the end of P_DeathThink [[ @@ -693,10 +695,13 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill player->mo->special1 = 0; } // ]] - level.DoReborn(i, false); + DoReborn(i, false); } } } + // Set global transition state. + gameaction = ga_completed; + ::nextlevel = nextlevel; } //========================================================================== @@ -704,20 +709,15 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill // //========================================================================== -const char *G_GetExitMap() +const char *FLevelLocals::GetSecretExitMap() { - return level.NextMap; -} + const char *nextmap = NextMap; -const char *G_GetSecretExitMap() -{ - const char *nextmap = level.NextMap; - - if (level.NextSecretMap.Len() > 0) + if (NextSecretMap.Len() > 0) { - if (P_CheckMapData(level.NextSecretMap)) + if (P_CheckMapData(NextSecretMap)) { - nextmap = level.NextSecretMap; + nextmap = NextSecretMap; } } return nextmap; @@ -728,16 +728,17 @@ const char *G_GetSecretExitMap() // //========================================================================== -void G_ExitLevel (int position, bool keepFacing) + +void FLevelLocals::ExitLevel (int position, bool keepFacing) { - level.flags3 |= LEVEL3_EXITNORMALUSED; - G_ChangeLevel(G_GetExitMap(), position, keepFacing ? CHANGELEVEL_KEEPFACING : 0); + flags3 |= LEVEL3_EXITNORMALUSED; + ChangeLevel(NextMap, position, keepFacing ? CHANGELEVEL_KEEPFACING : 0); } -void G_SecretExitLevel (int position) +void FLevelLocals::SecretExitLevel (int position) { - level.flags3 |= LEVEL3_EXITSECRETUSED; - G_ChangeLevel(G_GetSecretExitMap(), position, 0); + flags3 |= LEVEL3_EXITSECRETUSED; + ChangeLevel(GetSecretExitMap(), position, 0); } //========================================================================== diff --git a/src/g_level.h b/src/g_level.h index bdba32b7b..8b83ed043 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -454,11 +454,6 @@ void G_DeferedInitNew (const char *mapname, int skill = -1); struct FGameStartup; void G_DeferedInitNew (FGameStartup *gs); -void G_ExitLevel (int position, bool keepFacing); -void G_SecretExitLevel (int position); -const char *G_GetExitMap(); -const char *G_GetSecretExitMap(); - enum { CHANGELEVEL_KEEPFACING = 1, @@ -470,8 +465,6 @@ enum CHANGELEVEL_PRERAISEWEAPON = 64, }; -void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill=-1); - void G_DoLoadLevel (const FString &MapName, int position, bool autosave, bool newGame); cluster_info_t *FindClusterInfo (int cluster); diff --git a/src/g_levellocals.h b/src/g_levellocals.h index 17c834788..a8d1486dc 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -92,6 +92,7 @@ class DSeqNode; struct FStrifeDialogueNode; class DAutomapBase; struct wbstartstruct_t; +class DSectorMarker; typedef TMap FDialogueIDMap; // maps dialogue IDs to dialogue array index (for ACS) typedef TMap FDialogueMap; // maps actor class names to dialogue array index @@ -225,6 +226,10 @@ public: bool DoCompleted(FString nextlevel, wbstartstruct_t &wminfo); void StartTravel(); int FinishTravel(); + void ChangeLevel(const char *levelname, int position, int flags, int nextSkill = -1); + const char *GetSecretExitMap(); + void ExitLevel(int position, bool keepFacing); + void SecretExitLevel(int position); void DoLoadLevel(const FString &nextmapname, int position, bool autosave, bool newGame); diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 18846570a..a51343c7f 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -9896,7 +9896,7 @@ scriptwait: case PCD_CHANGELEVEL: { - G_ChangeLevel(Level->Behaviors.LookupString(STACK(4)), STACK(3), STACK(2), STACK(1)); + Level->ChangeLevel(Level->Behaviors.LookupString(STACK(4)), STACK(3), STACK(2), STACK(1)); sp -= 4; } break; diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 162e9a76c..f97628510 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -3175,7 +3175,7 @@ void A_BossDeath(AActor *self) if ((deathmatch || alwaysapplydmflags) && (dmflags & DF_NO_EXIT)) return; - G_ExitLevel (0, false); + Level->ExitLevel (0, false); } //---------------------------------------------------------------------------- diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index dfaeebea8..448892cf3 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -543,7 +543,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags, FName MeansOf fraglimit <= D_GetFragCount (source->player)) { Printf ("%s\n", GStrings("TXT_FRAGLIMIT")); - G_ExitLevel (0, false); + Level->ExitLevel (0, false); } } } diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 04d7d9337..fbb2dc873 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -1060,9 +1060,9 @@ FUNC(LS_Generic_Lift) FUNC(LS_Exit_Normal) // Exit_Normal (position) { - if (Level->CheckIfExitIsGood (it, FindLevelInfo(G_GetExitMap()))) + if (Level->CheckIfExitIsGood (it, FindLevelInfo(Level->NextMap))) { - G_ExitLevel (arg0, false); + Level->ExitLevel (arg0, false); return true; } return false; @@ -1071,9 +1071,9 @@ FUNC(LS_Exit_Normal) FUNC(LS_Exit_Secret) // Exit_Secret (position) { - if (Level->CheckIfExitIsGood (it, FindLevelInfo(G_GetSecretExitMap()))) + if (Level->CheckIfExitIsGood (it, FindLevelInfo(Level->GetSecretExitMap()))) { - G_SecretExitLevel (arg0); + Level->SecretExitLevel (arg0); return true; } return false; @@ -1088,7 +1088,7 @@ FUNC(LS_Teleport_NewMap) if (info && Level->CheckIfExitIsGood (it, info)) { - G_ChangeLevel(info->MapName, arg1, arg2 ? CHANGELEVEL_KEEPFACING : 0); + Level->ChangeLevel(info->MapName, arg1, arg2 ? CHANGELEVEL_KEEPFACING : 0); return true; } } @@ -1183,7 +1183,7 @@ FUNC(LS_Teleport_EndGame) { if (!backSide && Level->CheckIfExitIsGood (it, NULL)) { - G_ChangeLevel(NULL, 0, 0); + Level->ChangeLevel(NULL, 0, 0); return true; } return false; diff --git a/src/p_spec.cpp b/src/p_spec.cpp index effc55eed..7271e9401 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -463,7 +463,7 @@ void P_PlayerInSpecialSector (player_t *player, sector_t * sector) if (!(player->cheats & (CF_GODMODE|CF_GODMODE2))) P_DamageMobj(player->mo, NULL, NULL, sector->damageamount, sector->damagetype); if ((sector->Flags & SECF_ENDLEVEL) && player->health <= 10 && (!deathmatch || !(dmflags & DF_NO_EXIT))) { - G_ExitLevel(0, false); + Level->ExitLevel(0, false); } if (sector->Flags & SECF_DMGTERRAINFX) { @@ -678,7 +678,7 @@ void P_UpdateSpecials (FLevelLocals *Level) if (Level->maptime >= (int)(timelimit * TICRATE * 60)) { Printf ("%s\n", GStrings("TXT_TIMELIMIT")); - G_ExitLevel(0, false); + Level->ExitLevel(0, false); } } }