diff --git a/src/d_clisrv.c b/src/d_clisrv.c index a79f1e711..11e067f24 100755 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -5304,7 +5304,7 @@ boolean TryRunTics(tic_t realtics) { COM_BufTicker(); if (mapchangepending) - D_MapChange(-1, 0, false, ultimatemode, false, 2, false, fromlevelselect); // finish the map change + D_MapChange(-1, 0, ultimatemode, false, 2, false, fromlevelselect); // finish the map change } NetUpdate(); diff --git a/src/d_main.c b/src/d_main.c index 9d7ae4379..0825fc974 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1721,7 +1721,7 @@ void D_SRB2Main(void) I_Error("You need to unlock this level before you can warp to it!\n"); else { - D_MapChange(pstartmap, gametype, false, ultimatemode, true, 0, false, false); + D_MapChange(pstartmap, gametype, ultimatemode, true, 0, false, false); } } } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index c7599d6bb..1905afa0f 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -64,6 +64,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum); static void Got_WeaponPref(UINT8 **cp, INT32 playernum); static void Got_Mapcmd(UINT8 **cp, INT32 playernum); +static void Got_Newworld(UINT8 **cp, INT32 playernum); static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum); static void Got_Switchworld(UINT8 **cp, INT32 playernum); static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum); @@ -454,6 +455,7 @@ void D_RegisterServerCommands(void) RegisterNetXCmd(XD_NAMEANDCOLOR, Got_NameAndColor); RegisterNetXCmd(XD_WEAPONPREF, Got_WeaponPref); RegisterNetXCmd(XD_MAP, Got_Mapcmd); + RegisterNetXCmd(XD_NEWWORLD, Got_Newworld); RegisterNetXCmd(XD_EXITLEVEL, Got_ExitLevelcmd); RegisterNetXCmd(XD_SWITCHWORLD, Got_Switchworld); RegisterNetXCmd(XD_ADDFILE, Got_Addfilecmd); @@ -1748,7 +1750,6 @@ boolean mapchangepending = false; * * \param mapnum Map number to change to. * \param gametype Gametype to switch to. - * \param addworld Loads a separate world. * \param pultmode Is this 'Ultimate Mode'? * \param resetplayers 1 to reset player scores and lives and such, 0 not to. * \param delay Determines how the function will be executed: 0 to do @@ -1758,7 +1759,7 @@ boolean mapchangepending = false; * \sa D_GameTypeChanged, Command_Map_f * \author Graue */ -void D_MapChange(INT32 mapnum, INT32 newgametype, boolean addworld, boolean pultmode, boolean resetplayers, INT32 delay, boolean skipprecutscene, boolean FLS) +void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean resetplayers, INT32 delay, boolean skipprecutscene, boolean FLS) { static char buf[2+MAX_WADPATH+1+4]; static char *buf_p = buf; @@ -1809,8 +1810,6 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean addworld, boolean pult flags |= 1<<2; if (FLS) flags |= 1<<3; - if (addworld) - flags |= 1<<4; WRITEUINT8(buf_p, flags); // new gametype value @@ -1827,7 +1826,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean addworld, boolean pult // spawn the server if needed // reset players if there is a new one - if (!IsPlayerAdmin(consoleplayer) && !addworld) + if (!IsPlayerAdmin(consoleplayer)) { if (SV_SpawnServer()) buf[0] &= ~(1<<1); @@ -1842,6 +1841,22 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean addworld, boolean pult } } +// Sends a command to add a new world. +// It's as simple as that. +void D_AddWorld(INT32 mapnum) +{ + char buf[MAX_WADPATH+1]; + char *buf_p = buf; + + CONS_Debug(DBG_GAMELOGIC, "Map change: mapnum=%d\n", mapnum); + + I_Assert(W_CheckNumForName(mapname) != LUMPERROR); + + WRITESTRINGN(buf_p, G_BuildMapName(mapnum), MAX_WADPATH); + + SendNetXCmd(XD_NEWWORLD, buf, buf_p - buf); +} + static char * ConcatCommandArgv (int start, int end) { @@ -2069,7 +2084,10 @@ static void Command_Map_f(void) } tutorialmode = false; // warping takes us out of tutorial mode - D_MapChange(newmapnum, newgametype, addworld, false, newresetplayers, 0, false, fromlevelselect); + if (addworld) + D_AddWorld(newmapnum); + else + D_MapChange(newmapnum, newgametype, false, newresetplayers, 0, false, fromlevelselect); Z_Free(realmapname); } @@ -2083,8 +2101,6 @@ static void Command_Map_f(void) */ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) { - player_t *player; - boolean addworld; char mapname[MAX_WADPATH+1]; UINT8 flags; INT32 resetplayer = 1, lastgametype; @@ -2093,9 +2109,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) flags = READUINT8(*cp); - addworld = ((flags & (1<<4)) != 0); - - if (!addworld && playernum != serverplayer && !IsPlayerAdmin(playernum)) + if (playernum != serverplayer && !IsPlayerAdmin(playernum)) { CONS_Alert(CONS_WARNING, M_GetText("Illegal map change received from %s\n"), player_names[playernum]); if (server) @@ -2103,8 +2117,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) return; } - player = &players[playernum]; - if (chmappending) chmappending--; @@ -2136,8 +2148,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) { DEBFILE(va("Warping to %s [resetplayer=%d lastgametype=%d gametype=%d cpnd=%d]\n", mapname, resetplayer, lastgametype, gametype, chmappending)); - if (!addworld) - CONS_Printf(M_GetText("Speeding off to level...\n")); + CONS_Printf(M_GetText("Speeding off to level...\n")); } if (demoplayback && !timingdemo) @@ -2159,7 +2170,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) mapnumber = M_MapNumber(mapname[3], mapname[4]); LUA_HookInt(mapnumber, HOOK(MapChange)); - G_InitNew(player, mapname, addworld, ultimatemode, resetplayer, skipprecutscene, FLS); + G_InitNew(mapname, ultimatemode, resetplayer, skipprecutscene, FLS); if (demoplayback && !timingdemo) precache = true; if (timingdemo) @@ -2172,6 +2183,24 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) demo_start = true; } +/** Receives a new world command and creates a new one. + * + * \param cp Data buffer. + * \param playernum Player number responsible for the message. + * \sa D_MapChange + */ +static void Got_Newworld(UINT8 **cp, INT32 playernum) +{ + (void)playernum; + + char mapname[MAX_WADPATH+1]; + READSTRINGN(*cp, mapname, MAX_WADPATH); + + DEBFILE(va("Adding world with map %s\n", mapname)); + + G_LoadWorld(mapname); +} + void SendWorldSwitch(INT32 worldnum, void *location, boolean nodetach) { UINT8 buf[sizeof(INT32) + sizeof(UINT8) + (sizeof(fixed_t) * 3) + sizeof(angle_t)]; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index b0e04ec7f..ae7ae5c21 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -130,24 +130,25 @@ typedef enum XD_SAY, // 5 XD_MAP, // 6 XD_EXITLEVEL, // 7 - XD_ADDFILE, // 8 - XD_ADDFOLDER, // 9 - XD_PAUSE, // 10 - XD_ADDPLAYER, // 11 - XD_TEAMCHANGE, // 12 - XD_CLEARSCORES, // 13 - XD_SWITCHWORLD, // 14 - XD_VERIFIED, // 15 - XD_RANDOMSEED, // 16 - XD_RUNSOC, // 17 - XD_REQADDFILE, // 18 - XD_REQADDFOLDER,// 19 - XD_SETMOTD, // 20 - XD_SUICIDE, // 21 - XD_DEMOTED, // 22 - XD_LUACMD, // 23 - XD_LUAVAR, // 24 - XD_LUAFILE, // 25 + XD_NEWWORLD, // 8 + XD_SWITCHWORLD, // 9 + XD_ADDFILE, // 10 + XD_ADDFOLDER, // 11 + XD_PAUSE, // 12 + XD_ADDPLAYER, // 13 + XD_TEAMCHANGE, // 14 + XD_CLEARSCORES, // 15 + XD_VERIFIED, // 16 + XD_RANDOMSEED, // 17 + XD_RUNSOC, // 18 + XD_REQADDFILE, // 19 + XD_REQADDFOLDER,// 20 + XD_SETMOTD, // 21 + XD_SUICIDE, // 22 + XD_DEMOTED, // 23 + XD_LUACMD, // 24 + XD_LUAVAR, // 25 + XD_LUAFILE, // 26 MAXNETXCMD } netxcmd_t; @@ -202,7 +203,8 @@ void D_SendPlayerConfig(void); void Command_ExitGame_f(void); void Command_Retry_f(void); void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore -void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean addworld, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect); +void D_MapChange(INT32 pmapnum, INT32 pgametype, boolean pultmode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pfromlevelselect); +void D_AddWorld(INT32 pmapnum); boolean IsPlayerAdmin(INT32 playernum); void SetAdminPlayer(INT32 playernum); void ClearAdminPlayers(void); diff --git a/src/f_finale.c b/src/f_finale.c index ccc1dfb84..4a7da0cb5 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2429,13 +2429,13 @@ void F_StartTitleScreen(void) if (!mapheaderinfo[gamemap-1]) P_AllocMapHeader(gamemap-1); - P_UnloadWorldList(); + World_UnloadAll(); curmapheader = nextmapheader = mapheaderinfo[gamemap-1]; worldmapheader = curmapheader; maptol = curmapheader->typeoflevel; - G_DoLoadLevel(&players[displayplayer], false, true); + G_DoLoadLevel(true); if (!titlemap) return; @@ -3904,7 +3904,7 @@ void F_EndCutScene(void) if (runningprecutscene) { if (server) - D_MapChange(gamemap, gametype, false, ultimatemode, precutresetplayer, 0, true, precutFLS); + D_MapChange(gamemap, gametype, ultimatemode, precutresetplayer, 0, true, precutFLS); } else { diff --git a/src/g_demo.c b/src/g_demo.c index 470485a3a..e51ef3e9d 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1985,7 +1985,7 @@ void G_DoPlayDemo(char *defdemoname) memset(playeringame,0,sizeof(playeringame)); playeringame[0] = true; P_SetRandSeed(randseed); - G_InitNew(&players[0], G_BuildMapName(gamemap), false, false, true, true, false); + G_InitNew(G_BuildMapName(gamemap), false, true, true, false); // Set color players[0].skincolor = skins[players[0].skin].prefcolor; diff --git a/src/g_game.c b/src/g_game.c index e42ec8755..270561eee 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1794,7 +1794,7 @@ static void G_ResetCamera(INT32 playernum) // // G_DoLoadLevel // -void G_DoLoadLevel(player_t *player, boolean addworld, boolean resetplayer) +void G_DoLoadLevel(boolean resetplayer) { INT32 i; @@ -1826,29 +1826,18 @@ void G_DoLoadLevel(player_t *player, boolean addworld, boolean resetplayer) titlemapinaction = TITLEMAP_OFF; G_SetGamestate(GS_LEVEL); - if (player == &players[consoleplayer]) - I_UpdateMouseGrab(); + I_UpdateMouseGrab(); - if (!addworld) + for (i = 0; i < MAXPLAYERS; i++) { - for (i = 0; i < MAXPLAYERS; i++) - { - if (resetplayer || (playeringame[i] && players[i].playerstate == PST_DEAD)) - players[i].playerstate = PST_REBORN; - } - - P_UnloadWorldList(); + if (resetplayer || (playeringame[i] && players[i].playerstate == PST_DEAD)) + players[i].playerstate = PST_REBORN; } - // Setup the level. - boolean success; - if (addworld) - success = P_LoadWorld(false); - else - success = P_LoadLevel(false, false); // this never returns false? (yes it can) + World_UnloadAll(); - // fail so reset game stuff - if (!success) + // Setup the level. + if (!P_LoadLevel(false, false)) // this never returns false? (yes it can) { Command_ExitGame_f(); return; @@ -1865,33 +1854,23 @@ void G_DoLoadLevel(player_t *player, boolean addworld, boolean resetplayer) Z_CheckHeap(-2); #endif - if (!addworld) + // clear cmd building stuff + memset(gamekeydown, 0, sizeof (gamekeydown)); + for (i = 0;i < JOYAXISSET; i++) { - // clear cmd building stuff - memset(gamekeydown, 0, sizeof (gamekeydown)); - for (i = 0;i < JOYAXISSET; i++) - { - joyxmove[i] = joyymove[i] = 0; - joy2xmove[i] = joy2ymove[i] = 0; - } - G_SetMouseDeltas(0, 0, 1); - G_SetMouseDeltas(0, 0, 2); - - if (splitscreen) - G_ResetCamera(1); + joyxmove[i] = joyymove[i] = 0; + joy2xmove[i] = joy2ymove[i] = 0; } + G_SetMouseDeltas(0, 0, 1); + G_SetMouseDeltas(0, 0, 2); - if (!addworld && player == &players[consoleplayer]) - { - G_ResetCamera(consoleplayer); + if (splitscreen) + G_ResetCamera(1); - // clear hud messages remains (usually from game startup) - CON_ClearHUD(); - } + G_ResetCamera(consoleplayer); - // change world back to yours, for consistency - if (addworld) - P_SetWorld(localworld); + // clear hud messages remains (usually from game startup) + CON_ClearHUD(); } // @@ -2753,9 +2732,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->playerstate = PST_LIVE; p->panim = PA_IDLE; // standing animation - if (p->world) - ((world_t *)p->world)->players++; - //if ((netgame || multiplayer) && !p->spectator) -- moved into P_SpawnPlayer to account for forced changes there //p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent @@ -3292,7 +3268,7 @@ void G_DoReborn(INT32 playernum) { LUA_HookInt(gamemap, HOOK(MapChange)); titlecardforreload = true; - G_DoLoadLevel(&players[consoleplayer], false, true); + G_DoLoadLevel(true); titlecardforreload = false; if (metalrecording) G_BeginMetal(); @@ -3360,8 +3336,11 @@ void G_AddPlayer(INT32 playernum) } } - if (worldlist) // Assume the player is on the first world - p->world = worldlist[0]; + p->world = NULL; + + // Let's just place the player in the first world + if (worldlist) + P_SwitchPlayerWorld(p, worldlist[0]); p->playerstate = PST_REBORN; @@ -4227,10 +4206,10 @@ static void G_DoWorldDone(void) { if (gametyperules & GTR_CAMPAIGN) // don't reset player between maps - D_MapChange(nextmap+1, gametype, false, ultimatemode, false, 0, false, false); + D_MapChange(nextmap+1, gametype, ultimatemode, false, 0, false, false); else // resetplayer in match/chaos/tag/CTF/race for more equality - D_MapChange(nextmap+1, gametype, false, ultimatemode, true, 0, false, false); + D_MapChange(nextmap+1, gametype, ultimatemode, true, 0, false, false); } gameaction = ga_nothing; @@ -4293,7 +4272,7 @@ static void G_DoContinued(void) // Reset # of lives pl->lives = (ultimatemode) ? 1 : startinglivesbalance[numgameovers]; - D_MapChange(gamemap, gametype, false, ultimatemode, false, 0, false, false); + D_MapChange(gamemap, gametype, ultimatemode, false, 0, false, false); gameaction = ga_nothing; } @@ -4999,7 +4978,7 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, b CV_StealthSetValue(&cv_playercolor, color); if (mapname) - D_MapChange(M_MapNumber(mapname[3], mapname[4]), gametype, false, pultmode, true, 1, false, FLS); + D_MapChange(M_MapNumber(mapname[3], mapname[4]), gametype, pultmode, true, 1, false, FLS); } static void G_ResetPlayer(player_t *player, boolean pultmode, boolean FLS) @@ -5036,9 +5015,7 @@ static void G_ResetPlayer(player_t *player, boolean pultmode, boolean FLS) // This is the map command interpretation something like Command_Map_f // // called at: map cmd execution, doloadgame, doplaydemo -void G_InitNew(player_t *player, - const char *mapname, boolean addworld, - UINT8 pultmode, boolean resetplayer, boolean skipprecutscene, boolean FLS) +void G_InitNew(const char *mapname, UINT8 pultmode, boolean resetplayer, boolean skipprecutscene, boolean FLS) { INT32 i; @@ -5062,11 +5039,8 @@ void G_InitNew(player_t *player, numgameovers = tokenlist = token = sstimer = redscore = bluescore = lastmap = 0; countdown = countdown2 = exitfadestarted = 0; - if (!addworld) - { - for (i = 0; i < MAXPLAYERS; i++) - G_ResetPlayer(&players[i], pultmode, FLS); - } + for (i = 0; i < MAXPLAYERS; i++) + G_ResetPlayer(&players[i], pultmode, FLS); // Reset unlockable triggers unlocktriggers = 0; @@ -5093,15 +5067,8 @@ void G_InitNew(player_t *player, if(!mapheaderinfo[gamemap-1]) P_AllocMapHeader(gamemap-1); - nextmapheader = mapheaderinfo[gamemap-1]; - - if (!addworld) - { - curmapheader = nextmapheader; - maptol = nextmapheader->typeoflevel; - } - - worldmapheader = nextmapheader; + curmapheader = worldmapheader = nextmapheader = mapheaderinfo[gamemap-1]; + maptol = nextmapheader->typeoflevel; // Don't carry over custom music change to another map. mapmusflags |= MUSIC_RELOADRESET; @@ -5110,13 +5077,12 @@ void G_InitNew(player_t *player, automapactive = false; imcontinuing = false; - if (!addworld && ((gametyperules & GTR_CUTSCENES) && !skipprecutscene && nextmapheader->precutscenenum && !modeattacking && !(marathonmode & MA_NOCUTSCENES))) // Start a custom cutscene. + if ((gametyperules & GTR_CUTSCENES) && !skipprecutscene && nextmapheader->precutscenenum && !modeattacking && !(marathonmode & MA_NOCUTSCENES)) // Start a custom cutscene. F_StartCustomCutscene(nextmapheader->precutscenenum-1, true, resetplayer, FLS); else - G_DoLoadLevel(player, addworld, resetplayer); + G_DoLoadLevel(resetplayer); - // current world is hopefully the newly loaded world at this point - if (netgame && !addworld) + if (netgame) { char *title = G_BuildMapTitle(gamemap); @@ -5130,6 +5096,42 @@ void G_InitNew(player_t *player, } } +boolean G_LoadWorld(const char *mapname) +{ + // Check if the map is actually valid. + if (W_CheckNumForName(mapname) == LUMPERROR) + { + CONS_Alert(CONS_ERROR, "G_LoadWorld: Internal game map '%s' not found\n", mapname); + return false; + } + + INT16 mapnum = (INT16)M_MapNumber(mapname[3], mapname[4]); // get xx out of MAPxx + + LUA_HookInt(mapnum, HOOK(MapChange)); + + // gamemap changed; we assume that its map header is always valid, + // so make it so + if(!mapheaderinfo[mapnum-1]) + P_AllocMapHeader(mapnum-1); + + nextmapheader = mapheaderinfo[mapnum-1]; + worldmapheader = nextmapheader; + + if (!P_LoadWorld(mapnum, false)) + { + CONS_Alert(CONS_ERROR, "G_LoadWorld: Could not load map '%s'\n", mapname); + return false; + } + +#ifdef PARANOIA + Z_CheckHeap(-2); +#endif + + // change world back to yours, for consistency + P_SetWorld(localworld); + + return true; +} char *G_BuildMapTitle(INT32 mapnum) { diff --git a/src/g_game.h b/src/g_game.h index 3a4b3b413..5550c8698 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -136,9 +136,7 @@ extern INT32 localaiming, localaiming2; // should be an angle_t but signed void G_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo); void G_DoReborn(INT32 playernum); void G_PlayerReborn(INT32 player, boolean betweenmaps); -void G_InitNew(player_t *player, - const char *mapname, boolean addworld, - UINT8 pultmode, boolean resetplayer, boolean skipprecutscene, boolean FLS); +void G_InitNew(const char *mapname, UINT8 pultmode, boolean resetplayer, boolean skipprecutscene, boolean FLS); char *G_BuildMapTitle(INT32 mapnum); struct searchdim @@ -176,9 +174,11 @@ void G_SpawnPlayer(INT32 playernum); // Can be called by the startup code or M_Responder. // A normal game starts at map 1, but a warp test can start elsewhere -void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, - boolean SSSG, boolean FLS); -void G_DoLoadLevel(player_t *player, boolean addworld, boolean resetplayer); +void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar,boolean SSSG, boolean FLS); +void G_DoLoadLevel(boolean resetplayer); + +boolean G_LoadWorld(const char *mapname); + void G_StartTitleCard(void); void G_PreLevelTitleCard(void); boolean G_IsTitleCardAvailable(void); diff --git a/src/m_menu.c b/src/m_menu.c index cae75902b..8d29a646c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -11594,7 +11594,7 @@ static void M_StartServer(INT32 choice) if (!StartSplitScreenGame) { - D_MapChange(cv_nextmap.value, cv_newgametype.value, false, false, 1, 1, false, false); + D_MapChange(cv_nextmap.value, cv_newgametype.value, false, 1, 1, false, false); COM_BufAddText("dummyconsvar 1\n"); } else // split screen @@ -11606,7 +11606,7 @@ static void M_StartServer(INT32 choice) splitscreen = true; SplitScreen_OnChange(); } - D_MapChange(cv_nextmap.value, cv_newgametype.value, false, false, 1, 1, false, false); + D_MapChange(cv_nextmap.value, cv_newgametype.value, false, 1, 1, false, false); } M_ClearMenus(true); diff --git a/src/p_saveg.c b/src/p_saveg.c index daa388f3d..568ff1b2a 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -4365,7 +4365,7 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading) if (READUINT32(save_p) != ARCHIVEBLOCK_MISC) I_Error("Bad $$$.sav at archive block Misc"); - P_UnloadWorldList(); + World_UnloadAll(); if (reloading) gametic = READUINT32(save_p); @@ -4920,12 +4920,12 @@ static void P_NetUnArchiveWorlds(void) // Unarchive each world for (INT32 i = 0; i < worldcount; i++) { - gamemap = READINT16(save_p); + INT16 mapnum = READINT16(save_p); // Don't load the first world (because it already is loaded at this point) if (i != 0) { - if (!P_LoadWorld(true)) + if (!P_LoadWorld(mapnum, true)) I_Error("P_NetUnArchiveWorlds: failed loading world"); } diff --git a/src/p_setup.c b/src/p_setup.c index baf5c093d..d8b348443 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -7562,7 +7562,7 @@ static void P_InitGametype(boolean addworld) static world_t *P_InitWorldFromMap(INT16 mapnumber, mapheader_t *mapheader, boolean addworld, boolean fromnetsave) { world_t *curworld = world; - world_t *w = P_InitNewWorld(); + world_t *w = World_PushNew(mapnumber); w->loading = true; @@ -7614,7 +7614,7 @@ static world_t *P_InitWorldFromMap(INT16 mapnumber, mapheader_t *mapheader, bool P_InitSlopes(); if (!P_LoadMapFromFile(maplumpnum)) - return false; + return NULL; // init anything that P_SpawnSlopes/P_SpawnMapThings needs to know P_InitSpecials(); @@ -7923,7 +7923,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) return true; } -boolean P_LoadWorld(boolean fromnetsave) +boolean P_LoadWorld(INT16 mapnum, boolean fromnetsave) { // Initialize sector node list. P_Initsecnode(); @@ -7943,12 +7943,14 @@ boolean P_LoadWorld(boolean fromnetsave) wipestyleflags = 0; } - world_t *w = P_InitWorldFromMap(gamemap, worldmapheader, true, fromnetsave); + world_t *w = P_InitWorldFromMap(mapnum, worldmapheader, true, fromnetsave); if (w == NULL) - I_Error("Map %s not found.\n", G_BuildMapName(gamemap)); + return false; P_FinishMapLoad(fromnetsave); + P_FindEmerald(world); + return true; } diff --git a/src/p_setup.h b/src/p_setup.h index b293d4e65..6a385f875 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -98,7 +98,7 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum); #endif void P_RespawnThings(void); boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate); -boolean P_LoadWorld(boolean fromnetsave); +boolean P_LoadWorld(INT16 mapnum, boolean fromnetsave); boolean P_AddWadFile(const char *wadfilename); boolean P_AddFolder(const char *folderpath); diff --git a/src/p_world.c b/src/p_world.c index 503100e27..a9e66d05b 100644 --- a/src/p_world.c +++ b/src/p_world.c @@ -54,15 +54,15 @@ world_t **worldlist = NULL; INT32 numworlds = 0; // -// Initializes a world. +// Creates a world. // -world_t *P_InitWorld(void) +world_t *World_Create(INT16 mapnum) { world_t *w = Z_Calloc(sizeof(world_t), PU_STATIC, NULL); - w->gamemap = gamemap; - if (!mapheaderinfo[gamemap-1]) - P_AllocMapHeader(gamemap-1); - w->header = mapheaderinfo[gamemap-1]; + w->gamemap = mapnum; + if (!mapheaderinfo[mapnum-1]) + P_AllocMapHeader(mapnum-1); + w->header = mapheaderinfo[mapnum-1]; w->thlist = Z_Calloc(sizeof(thinker_t) * NUM_THINKERLISTS, PU_STATIC, NULL); P_InitCachedActions(w); return w; @@ -71,10 +71,10 @@ world_t *P_InitWorld(void) // // Initializes a new world, inserting it into the world list. // -world_t *P_InitNewWorld(void) +world_t *World_PushNew(INT16 mapnum) { worldlist = Z_Realloc(worldlist, (numworlds + 1) * sizeof(void *), PU_STATIC, NULL); - worldlist[numworlds] = P_InitWorld(); + worldlist[numworlds] = World_Create(mapnum); world_t *w = worldlist[numworlds]; @@ -173,7 +173,7 @@ void P_DetachPlayerWorld(player_t *player) player->world = NULL; - if (player->mo && !P_MobjWasRemoved(player->mo)) + if (player->mo && !P_MobjWasRemoved(player->mo) && player->mo->world != NULL) { R_RemoveMobjInterpolator(player->mo); player->mo->world = NULL; @@ -189,7 +189,7 @@ void P_SwitchPlayerWorld(player_t *player, world_t *newworld) player->world = newworld; - if (player->mo && !P_MobjWasRemoved(player->mo)) + if (player->mo && !P_MobjWasRemoved(player->mo) && player->mo->world == NULL) { player->mo->world = newworld; R_AddMobjInterpolator(player->mo); @@ -220,7 +220,7 @@ void P_RoamIntoWorld(player_t *player, INT32 mapnum) else if (w) P_SwitchWorld(player, w, NULL); else - D_MapChange(mapnum, gametype, true, false, false, 0, false, false); + D_AddWorld(mapnum); } boolean P_TransferCarriedPlayers(player_t *player, world_t *w) @@ -452,7 +452,7 @@ static void P_UnloadSectorAttachments(sector_t *s, size_t ns) // // Unloads a world. // -void P_UnloadWorld(world_t *w) +void World_Delete(world_t *w) { if (w == NULL) return; @@ -478,7 +478,7 @@ void P_UnloadWorld(world_t *w) // // Unloads all worlds. // -void P_UnloadWorldList(void) +void World_UnloadAll(void) { INT32 i; @@ -501,7 +501,7 @@ void P_UnloadWorldList(void) if (w == NULL) continue; - P_UnloadWorld(w); + World_Delete(w); } Z_Free(worldlist); @@ -525,26 +525,6 @@ void P_UnloadWorldList(void) world = localworld = viewworld = NULL; } -// -// Unloads a player. -// -void P_UnloadWorldPlayer(player_t *player) -{ - P_DetachPlayerWorld(player); - - if (player->followmobj) - { - P_RemoveMobj(player->followmobj); - P_SetTarget(&player->followmobj, NULL); - } - - if (player->mo) - { - P_RemoveMobj(player->mo); - P_SetTarget(&player->mo, NULL); - } -} - boolean P_MobjIsConnected(mobj_t *mobj1, mobj_t *mobj2) { return mobj2 && !P_MobjWasRemoved(mobj2) && P_GetMobjWorld(mobj1) == P_GetMobjWorld(mobj2); diff --git a/src/p_world.h b/src/p_world.h index 94da9736e..6ce4f86f1 100644 --- a/src/p_world.h +++ b/src/p_world.h @@ -163,12 +163,10 @@ typedef struct angle_t angle; } location_t; -world_t *P_InitWorld(void); -world_t *P_InitNewWorld(void); - -void P_UnloadWorld(world_t *w); -void P_UnloadWorldList(void); -void P_UnloadWorldPlayer(player_t *player); +world_t *World_Create(INT16 mapnum); +world_t *World_PushNew(INT16 mapnum); +void World_Delete(world_t *w); +void World_UnloadAll(void); void P_SetGameWorld(world_t *w); void P_SetViewWorld(world_t *w);