More decoupling

This commit is contained in:
Lactozilla 2023-06-27 22:09:21 -03:00
parent 6ecec66297
commit cb002c0fa6
14 changed files with 183 additions and 170 deletions

View file

@ -5304,7 +5304,7 @@ boolean TryRunTics(tic_t realtics)
{ {
COM_BufTicker(); COM_BufTicker();
if (mapchangepending) 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(); NetUpdate();

View file

@ -1721,7 +1721,7 @@ void D_SRB2Main(void)
I_Error("You need to unlock this level before you can warp to it!\n"); I_Error("You need to unlock this level before you can warp to it!\n");
else else
{ {
D_MapChange(pstartmap, gametype, false, ultimatemode, true, 0, false, false); D_MapChange(pstartmap, gametype, ultimatemode, true, 0, false, false);
} }
} }
} }

View file

@ -64,6 +64,7 @@
static void Got_NameAndColor(UINT8 **cp, INT32 playernum); static void Got_NameAndColor(UINT8 **cp, INT32 playernum);
static void Got_WeaponPref(UINT8 **cp, INT32 playernum); static void Got_WeaponPref(UINT8 **cp, INT32 playernum);
static void Got_Mapcmd(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_ExitLevelcmd(UINT8 **cp, INT32 playernum);
static void Got_Switchworld(UINT8 **cp, INT32 playernum); static void Got_Switchworld(UINT8 **cp, INT32 playernum);
static void Got_RequestAddfilecmd(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_NAMEANDCOLOR, Got_NameAndColor);
RegisterNetXCmd(XD_WEAPONPREF, Got_WeaponPref); RegisterNetXCmd(XD_WEAPONPREF, Got_WeaponPref);
RegisterNetXCmd(XD_MAP, Got_Mapcmd); RegisterNetXCmd(XD_MAP, Got_Mapcmd);
RegisterNetXCmd(XD_NEWWORLD, Got_Newworld);
RegisterNetXCmd(XD_EXITLEVEL, Got_ExitLevelcmd); RegisterNetXCmd(XD_EXITLEVEL, Got_ExitLevelcmd);
RegisterNetXCmd(XD_SWITCHWORLD, Got_Switchworld); RegisterNetXCmd(XD_SWITCHWORLD, Got_Switchworld);
RegisterNetXCmd(XD_ADDFILE, Got_Addfilecmd); RegisterNetXCmd(XD_ADDFILE, Got_Addfilecmd);
@ -1748,7 +1750,6 @@ boolean mapchangepending = false;
* *
* \param mapnum Map number to change to. * \param mapnum Map number to change to.
* \param gametype Gametype to switch to. * \param gametype Gametype to switch to.
* \param addworld Loads a separate world.
* \param pultmode Is this 'Ultimate Mode'? * \param pultmode Is this 'Ultimate Mode'?
* \param resetplayers 1 to reset player scores and lives and such, 0 not to. * \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 * \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 * \sa D_GameTypeChanged, Command_Map_f
* \author Graue <graue@oceanbase.org> * \author Graue <graue@oceanbase.org>
*/ */
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[2+MAX_WADPATH+1+4];
static char *buf_p = buf; static char *buf_p = buf;
@ -1809,8 +1810,6 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean addworld, boolean pult
flags |= 1<<2; flags |= 1<<2;
if (FLS) if (FLS)
flags |= 1<<3; flags |= 1<<3;
if (addworld)
flags |= 1<<4;
WRITEUINT8(buf_p, flags); WRITEUINT8(buf_p, flags);
// new gametype value // new gametype value
@ -1827,7 +1826,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean addworld, boolean pult
// spawn the server if needed // spawn the server if needed
// reset players if there is a new one // reset players if there is a new one
if (!IsPlayerAdmin(consoleplayer) && !addworld) if (!IsPlayerAdmin(consoleplayer))
{ {
if (SV_SpawnServer()) if (SV_SpawnServer())
buf[0] &= ~(1<<1); 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 * static char *
ConcatCommandArgv (int start, int end) ConcatCommandArgv (int start, int end)
{ {
@ -2069,7 +2084,10 @@ static void Command_Map_f(void)
} }
tutorialmode = false; // warping takes us out of tutorial mode 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); Z_Free(realmapname);
} }
@ -2083,8 +2101,6 @@ static void Command_Map_f(void)
*/ */
static void Got_Mapcmd(UINT8 **cp, INT32 playernum) static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
{ {
player_t *player;
boolean addworld;
char mapname[MAX_WADPATH+1]; char mapname[MAX_WADPATH+1];
UINT8 flags; UINT8 flags;
INT32 resetplayer = 1, lastgametype; INT32 resetplayer = 1, lastgametype;
@ -2093,9 +2109,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
flags = READUINT8(*cp); flags = READUINT8(*cp);
addworld = ((flags & (1<<4)) != 0); if (playernum != serverplayer && !IsPlayerAdmin(playernum))
if (!addworld && playernum != serverplayer && !IsPlayerAdmin(playernum))
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal map change received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal map change received from %s\n"), player_names[playernum]);
if (server) if (server)
@ -2103,8 +2117,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
return; return;
} }
player = &players[playernum];
if (chmappending) if (chmappending)
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", DEBFILE(va("Warping to %s [resetplayer=%d lastgametype=%d gametype=%d cpnd=%d]\n",
mapname, resetplayer, lastgametype, gametype, chmappending)); 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) if (demoplayback && !timingdemo)
@ -2159,7 +2170,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
mapnumber = M_MapNumber(mapname[3], mapname[4]); mapnumber = M_MapNumber(mapname[3], mapname[4]);
LUA_HookInt(mapnumber, HOOK(MapChange)); LUA_HookInt(mapnumber, HOOK(MapChange));
G_InitNew(player, mapname, addworld, ultimatemode, resetplayer, skipprecutscene, FLS); G_InitNew(mapname, ultimatemode, resetplayer, skipprecutscene, FLS);
if (demoplayback && !timingdemo) if (demoplayback && !timingdemo)
precache = true; precache = true;
if (timingdemo) if (timingdemo)
@ -2172,6 +2183,24 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
demo_start = true; 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) void SendWorldSwitch(INT32 worldnum, void *location, boolean nodetach)
{ {
UINT8 buf[sizeof(INT32) + sizeof(UINT8) + (sizeof(fixed_t) * 3) + sizeof(angle_t)]; UINT8 buf[sizeof(INT32) + sizeof(UINT8) + (sizeof(fixed_t) * 3) + sizeof(angle_t)];

View file

@ -130,24 +130,25 @@ typedef enum
XD_SAY, // 5 XD_SAY, // 5
XD_MAP, // 6 XD_MAP, // 6
XD_EXITLEVEL, // 7 XD_EXITLEVEL, // 7
XD_ADDFILE, // 8 XD_NEWWORLD, // 8
XD_ADDFOLDER, // 9 XD_SWITCHWORLD, // 9
XD_PAUSE, // 10 XD_ADDFILE, // 10
XD_ADDPLAYER, // 11 XD_ADDFOLDER, // 11
XD_TEAMCHANGE, // 12 XD_PAUSE, // 12
XD_CLEARSCORES, // 13 XD_ADDPLAYER, // 13
XD_SWITCHWORLD, // 14 XD_TEAMCHANGE, // 14
XD_VERIFIED, // 15 XD_CLEARSCORES, // 15
XD_RANDOMSEED, // 16 XD_VERIFIED, // 16
XD_RUNSOC, // 17 XD_RANDOMSEED, // 17
XD_REQADDFILE, // 18 XD_RUNSOC, // 18
XD_REQADDFOLDER,// 19 XD_REQADDFILE, // 19
XD_SETMOTD, // 20 XD_REQADDFOLDER,// 20
XD_SUICIDE, // 21 XD_SETMOTD, // 21
XD_DEMOTED, // 22 XD_SUICIDE, // 22
XD_LUACMD, // 23 XD_DEMOTED, // 23
XD_LUAVAR, // 24 XD_LUACMD, // 24
XD_LUAFILE, // 25 XD_LUAVAR, // 25
XD_LUAFILE, // 26
MAXNETXCMD MAXNETXCMD
} netxcmd_t; } netxcmd_t;
@ -202,7 +203,8 @@ void D_SendPlayerConfig(void);
void Command_ExitGame_f(void); void Command_ExitGame_f(void);
void Command_Retry_f(void); void Command_Retry_f(void);
void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore 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); boolean IsPlayerAdmin(INT32 playernum);
void SetAdminPlayer(INT32 playernum); void SetAdminPlayer(INT32 playernum);
void ClearAdminPlayers(void); void ClearAdminPlayers(void);

View file

@ -2429,13 +2429,13 @@ void F_StartTitleScreen(void)
if (!mapheaderinfo[gamemap-1]) if (!mapheaderinfo[gamemap-1])
P_AllocMapHeader(gamemap-1); P_AllocMapHeader(gamemap-1);
P_UnloadWorldList(); World_UnloadAll();
curmapheader = nextmapheader = mapheaderinfo[gamemap-1]; curmapheader = nextmapheader = mapheaderinfo[gamemap-1];
worldmapheader = curmapheader; worldmapheader = curmapheader;
maptol = curmapheader->typeoflevel; maptol = curmapheader->typeoflevel;
G_DoLoadLevel(&players[displayplayer], false, true); G_DoLoadLevel(true);
if (!titlemap) if (!titlemap)
return; return;
@ -3904,7 +3904,7 @@ void F_EndCutScene(void)
if (runningprecutscene) if (runningprecutscene)
{ {
if (server) if (server)
D_MapChange(gamemap, gametype, false, ultimatemode, precutresetplayer, 0, true, precutFLS); D_MapChange(gamemap, gametype, ultimatemode, precutresetplayer, 0, true, precutFLS);
} }
else else
{ {

View file

@ -1985,7 +1985,7 @@ void G_DoPlayDemo(char *defdemoname)
memset(playeringame,0,sizeof(playeringame)); memset(playeringame,0,sizeof(playeringame));
playeringame[0] = true; playeringame[0] = true;
P_SetRandSeed(randseed); 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 // Set color
players[0].skincolor = skins[players[0].skin].prefcolor; players[0].skincolor = skins[players[0].skin].prefcolor;

View file

@ -1794,7 +1794,7 @@ static void G_ResetCamera(INT32 playernum)
// //
// G_DoLoadLevel // G_DoLoadLevel
// //
void G_DoLoadLevel(player_t *player, boolean addworld, boolean resetplayer) void G_DoLoadLevel(boolean resetplayer)
{ {
INT32 i; INT32 i;
@ -1826,29 +1826,18 @@ void G_DoLoadLevel(player_t *player, boolean addworld, boolean resetplayer)
titlemapinaction = TITLEMAP_OFF; titlemapinaction = TITLEMAP_OFF;
G_SetGamestate(GS_LEVEL); 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;
if (resetplayer || (playeringame[i] && players[i].playerstate == PST_DEAD))
players[i].playerstate = PST_REBORN;
}
P_UnloadWorldList();
} }
// Setup the level. World_UnloadAll();
boolean success;
if (addworld)
success = P_LoadWorld(false);
else
success = P_LoadLevel(false, false); // this never returns false? (yes it can)
// fail so reset game stuff // Setup the level.
if (!success) if (!P_LoadLevel(false, false)) // this never returns false? (yes it can)
{ {
Command_ExitGame_f(); Command_ExitGame_f();
return; return;
@ -1865,33 +1854,23 @@ void G_DoLoadLevel(player_t *player, boolean addworld, boolean resetplayer)
Z_CheckHeap(-2); Z_CheckHeap(-2);
#endif #endif
if (!addworld) // clear cmd building stuff
memset(gamekeydown, 0, sizeof (gamekeydown));
for (i = 0;i < JOYAXISSET; i++)
{ {
// clear cmd building stuff joyxmove[i] = joyymove[i] = 0;
memset(gamekeydown, 0, sizeof (gamekeydown)); joy2xmove[i] = joy2ymove[i] = 0;
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);
} }
G_SetMouseDeltas(0, 0, 1);
G_SetMouseDeltas(0, 0, 2);
if (!addworld && player == &players[consoleplayer]) if (splitscreen)
{ G_ResetCamera(1);
G_ResetCamera(consoleplayer);
// clear hud messages remains (usually from game startup) G_ResetCamera(consoleplayer);
CON_ClearHUD();
}
// change world back to yours, for consistency // clear hud messages remains (usually from game startup)
if (addworld) CON_ClearHUD();
P_SetWorld(localworld);
} }
// //
@ -2753,9 +2732,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->playerstate = PST_LIVE; p->playerstate = PST_LIVE;
p->panim = PA_IDLE; // standing animation 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 //if ((netgame || multiplayer) && !p->spectator) -- moved into P_SpawnPlayer to account for forced changes there
//p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent //p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent
@ -3292,7 +3268,7 @@ void G_DoReborn(INT32 playernum)
{ {
LUA_HookInt(gamemap, HOOK(MapChange)); LUA_HookInt(gamemap, HOOK(MapChange));
titlecardforreload = true; titlecardforreload = true;
G_DoLoadLevel(&players[consoleplayer], false, true); G_DoLoadLevel(true);
titlecardforreload = false; titlecardforreload = false;
if (metalrecording) if (metalrecording)
G_BeginMetal(); G_BeginMetal();
@ -3360,8 +3336,11 @@ void G_AddPlayer(INT32 playernum)
} }
} }
if (worldlist) // Assume the player is on the first world p->world = NULL;
p->world = worldlist[0];
// Let's just place the player in the first world
if (worldlist)
P_SwitchPlayerWorld(p, worldlist[0]);
p->playerstate = PST_REBORN; p->playerstate = PST_REBORN;
@ -4227,10 +4206,10 @@ static void G_DoWorldDone(void)
{ {
if (gametyperules & GTR_CAMPAIGN) if (gametyperules & GTR_CAMPAIGN)
// don't reset player between maps // 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 else
// resetplayer in match/chaos/tag/CTF/race for more equality // 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; gameaction = ga_nothing;
@ -4293,7 +4272,7 @@ static void G_DoContinued(void)
// Reset # of lives // Reset # of lives
pl->lives = (ultimatemode) ? 1 : startinglivesbalance[numgameovers]; 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; gameaction = ga_nothing;
} }
@ -4999,7 +4978,7 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, b
CV_StealthSetValue(&cv_playercolor, color); CV_StealthSetValue(&cv_playercolor, color);
if (mapname) 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) 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 // This is the map command interpretation something like Command_Map_f
// //
// called at: map cmd execution, doloadgame, doplaydemo // called at: map cmd execution, doloadgame, doplaydemo
void G_InitNew(player_t *player, void G_InitNew(const char *mapname, UINT8 pultmode, boolean resetplayer, boolean skipprecutscene, boolean FLS)
const char *mapname, boolean addworld,
UINT8 pultmode, boolean resetplayer, boolean skipprecutscene, boolean FLS)
{ {
INT32 i; INT32 i;
@ -5062,11 +5039,8 @@ void G_InitNew(player_t *player,
numgameovers = tokenlist = token = sstimer = redscore = bluescore = lastmap = 0; numgameovers = tokenlist = token = sstimer = redscore = bluescore = lastmap = 0;
countdown = countdown2 = exitfadestarted = 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 // Reset unlockable triggers
unlocktriggers = 0; unlocktriggers = 0;
@ -5093,15 +5067,8 @@ void G_InitNew(player_t *player,
if(!mapheaderinfo[gamemap-1]) if(!mapheaderinfo[gamemap-1])
P_AllocMapHeader(gamemap-1); P_AllocMapHeader(gamemap-1);
nextmapheader = mapheaderinfo[gamemap-1]; curmapheader = worldmapheader = nextmapheader = mapheaderinfo[gamemap-1];
maptol = nextmapheader->typeoflevel;
if (!addworld)
{
curmapheader = nextmapheader;
maptol = nextmapheader->typeoflevel;
}
worldmapheader = nextmapheader;
// Don't carry over custom music change to another map. // Don't carry over custom music change to another map.
mapmusflags |= MUSIC_RELOADRESET; mapmusflags |= MUSIC_RELOADRESET;
@ -5110,13 +5077,12 @@ void G_InitNew(player_t *player,
automapactive = false; automapactive = false;
imcontinuing = 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); F_StartCustomCutscene(nextmapheader->precutscenenum-1, true, resetplayer, FLS);
else else
G_DoLoadLevel(player, addworld, resetplayer); G_DoLoadLevel(resetplayer);
// current world is hopefully the newly loaded world at this point if (netgame)
if (netgame && !addworld)
{ {
char *title = G_BuildMapTitle(gamemap); 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) char *G_BuildMapTitle(INT32 mapnum)
{ {

View file

@ -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_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo);
void G_DoReborn(INT32 playernum); void G_DoReborn(INT32 playernum);
void G_PlayerReborn(INT32 player, boolean betweenmaps); void G_PlayerReborn(INT32 player, boolean betweenmaps);
void G_InitNew(player_t *player, void G_InitNew(const char *mapname, UINT8 pultmode, boolean resetplayer, boolean skipprecutscene, boolean FLS);
const char *mapname, boolean addworld,
UINT8 pultmode, boolean resetplayer, boolean skipprecutscene, boolean FLS);
char *G_BuildMapTitle(INT32 mapnum); char *G_BuildMapTitle(INT32 mapnum);
struct searchdim struct searchdim
@ -176,9 +174,11 @@ void G_SpawnPlayer(INT32 playernum);
// Can be called by the startup code or M_Responder. // Can be called by the startup code or M_Responder.
// A normal game starts at map 1, but a warp test can start elsewhere // A normal game starts at map 1, but a warp test can start elsewhere
void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar,boolean SSSG, boolean FLS);
boolean SSSG, boolean FLS); void G_DoLoadLevel(boolean resetplayer);
void G_DoLoadLevel(player_t *player, boolean addworld, boolean resetplayer);
boolean G_LoadWorld(const char *mapname);
void G_StartTitleCard(void); void G_StartTitleCard(void);
void G_PreLevelTitleCard(void); void G_PreLevelTitleCard(void);
boolean G_IsTitleCardAvailable(void); boolean G_IsTitleCardAvailable(void);

View file

@ -11594,7 +11594,7 @@ static void M_StartServer(INT32 choice)
if (!StartSplitScreenGame) 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"); COM_BufAddText("dummyconsvar 1\n");
} }
else // split screen else // split screen
@ -11606,7 +11606,7 @@ static void M_StartServer(INT32 choice)
splitscreen = true; splitscreen = true;
SplitScreen_OnChange(); 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); M_ClearMenus(true);

View file

@ -4365,7 +4365,7 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
if (READUINT32(save_p) != ARCHIVEBLOCK_MISC) if (READUINT32(save_p) != ARCHIVEBLOCK_MISC)
I_Error("Bad $$$.sav at archive block Misc"); I_Error("Bad $$$.sav at archive block Misc");
P_UnloadWorldList(); World_UnloadAll();
if (reloading) if (reloading)
gametic = READUINT32(save_p); gametic = READUINT32(save_p);
@ -4920,12 +4920,12 @@ static void P_NetUnArchiveWorlds(void)
// Unarchive each world // Unarchive each world
for (INT32 i = 0; i < worldcount; i++) 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) // Don't load the first world (because it already is loaded at this point)
if (i != 0) if (i != 0)
{ {
if (!P_LoadWorld(true)) if (!P_LoadWorld(mapnum, true))
I_Error("P_NetUnArchiveWorlds: failed loading world"); I_Error("P_NetUnArchiveWorlds: failed loading world");
} }

View file

@ -7562,7 +7562,7 @@ static void P_InitGametype(boolean addworld)
static world_t *P_InitWorldFromMap(INT16 mapnumber, mapheader_t *mapheader, boolean addworld, boolean fromnetsave) static world_t *P_InitWorldFromMap(INT16 mapnumber, mapheader_t *mapheader, boolean addworld, boolean fromnetsave)
{ {
world_t *curworld = world; world_t *curworld = world;
world_t *w = P_InitNewWorld(); world_t *w = World_PushNew(mapnumber);
w->loading = true; w->loading = true;
@ -7614,7 +7614,7 @@ static world_t *P_InitWorldFromMap(INT16 mapnumber, mapheader_t *mapheader, bool
P_InitSlopes(); P_InitSlopes();
if (!P_LoadMapFromFile(maplumpnum)) if (!P_LoadMapFromFile(maplumpnum))
return false; return NULL;
// init anything that P_SpawnSlopes/P_SpawnMapThings needs to know // init anything that P_SpawnSlopes/P_SpawnMapThings needs to know
P_InitSpecials(); P_InitSpecials();
@ -7923,7 +7923,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
return true; return true;
} }
boolean P_LoadWorld(boolean fromnetsave) boolean P_LoadWorld(INT16 mapnum, boolean fromnetsave)
{ {
// Initialize sector node list. // Initialize sector node list.
P_Initsecnode(); P_Initsecnode();
@ -7943,12 +7943,14 @@ boolean P_LoadWorld(boolean fromnetsave)
wipestyleflags = 0; wipestyleflags = 0;
} }
world_t *w = P_InitWorldFromMap(gamemap, worldmapheader, true, fromnetsave); world_t *w = P_InitWorldFromMap(mapnum, worldmapheader, true, fromnetsave);
if (w == NULL) if (w == NULL)
I_Error("Map %s not found.\n", G_BuildMapName(gamemap)); return false;
P_FinishMapLoad(fromnetsave); P_FinishMapLoad(fromnetsave);
P_FindEmerald(world);
return true; return true;
} }

View file

@ -98,7 +98,7 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum);
#endif #endif
void P_RespawnThings(void); void P_RespawnThings(void);
boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate); 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_AddWadFile(const char *wadfilename);
boolean P_AddFolder(const char *folderpath); boolean P_AddFolder(const char *folderpath);

View file

@ -54,15 +54,15 @@ world_t **worldlist = NULL;
INT32 numworlds = 0; 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); world_t *w = Z_Calloc(sizeof(world_t), PU_STATIC, NULL);
w->gamemap = gamemap; w->gamemap = mapnum;
if (!mapheaderinfo[gamemap-1]) if (!mapheaderinfo[mapnum-1])
P_AllocMapHeader(gamemap-1); P_AllocMapHeader(mapnum-1);
w->header = mapheaderinfo[gamemap-1]; w->header = mapheaderinfo[mapnum-1];
w->thlist = Z_Calloc(sizeof(thinker_t) * NUM_THINKERLISTS, PU_STATIC, NULL); w->thlist = Z_Calloc(sizeof(thinker_t) * NUM_THINKERLISTS, PU_STATIC, NULL);
P_InitCachedActions(w); P_InitCachedActions(w);
return w; return w;
@ -71,10 +71,10 @@ world_t *P_InitWorld(void)
// //
// Initializes a new world, inserting it into the world list. // 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 = Z_Realloc(worldlist, (numworlds + 1) * sizeof(void *), PU_STATIC, NULL);
worldlist[numworlds] = P_InitWorld(); worldlist[numworlds] = World_Create(mapnum);
world_t *w = worldlist[numworlds]; world_t *w = worldlist[numworlds];
@ -173,7 +173,7 @@ void P_DetachPlayerWorld(player_t *player)
player->world = NULL; 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); R_RemoveMobjInterpolator(player->mo);
player->mo->world = NULL; player->mo->world = NULL;
@ -189,7 +189,7 @@ void P_SwitchPlayerWorld(player_t *player, world_t *newworld)
player->world = 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; player->mo->world = newworld;
R_AddMobjInterpolator(player->mo); R_AddMobjInterpolator(player->mo);
@ -220,7 +220,7 @@ void P_RoamIntoWorld(player_t *player, INT32 mapnum)
else if (w) else if (w)
P_SwitchWorld(player, w, NULL); P_SwitchWorld(player, w, NULL);
else else
D_MapChange(mapnum, gametype, true, false, false, 0, false, false); D_AddWorld(mapnum);
} }
boolean P_TransferCarriedPlayers(player_t *player, world_t *w) 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. // Unloads a world.
// //
void P_UnloadWorld(world_t *w) void World_Delete(world_t *w)
{ {
if (w == NULL) if (w == NULL)
return; return;
@ -478,7 +478,7 @@ void P_UnloadWorld(world_t *w)
// //
// Unloads all worlds. // Unloads all worlds.
// //
void P_UnloadWorldList(void) void World_UnloadAll(void)
{ {
INT32 i; INT32 i;
@ -501,7 +501,7 @@ void P_UnloadWorldList(void)
if (w == NULL) if (w == NULL)
continue; continue;
P_UnloadWorld(w); World_Delete(w);
} }
Z_Free(worldlist); Z_Free(worldlist);
@ -525,26 +525,6 @@ void P_UnloadWorldList(void)
world = localworld = viewworld = NULL; 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) boolean P_MobjIsConnected(mobj_t *mobj1, mobj_t *mobj2)
{ {
return mobj2 && !P_MobjWasRemoved(mobj2) && P_GetMobjWorld(mobj1) == P_GetMobjWorld(mobj2); return mobj2 && !P_MobjWasRemoved(mobj2) && P_GetMobjWorld(mobj1) == P_GetMobjWorld(mobj2);

View file

@ -163,12 +163,10 @@ typedef struct
angle_t angle; angle_t angle;
} location_t; } location_t;
world_t *P_InitWorld(void); world_t *World_Create(INT16 mapnum);
world_t *P_InitNewWorld(void); world_t *World_PushNew(INT16 mapnum);
void World_Delete(world_t *w);
void P_UnloadWorld(world_t *w); void World_UnloadAll(void);
void P_UnloadWorldList(void);
void P_UnloadWorldPlayer(player_t *player);
void P_SetGameWorld(world_t *w); void P_SetGameWorld(world_t *w);
void P_SetViewWorld(world_t *w); void P_SetViewWorld(world_t *w);