Refactoring, fix subtle bugs

This commit is contained in:
Lactozilla 2023-06-27 01:28:21 -03:00
parent 233bddc68e
commit e486556f4b
38 changed files with 523 additions and 482 deletions

View file

@ -529,6 +529,10 @@ boolean B_CheckRespawn(player_t *player)
return false;
}
// Not even in the same world?
if (P_GetMobjWorld(sonic) != P_GetMobjWorld(tails))
return true;
// If you can't see Sonic, I guess we should?
if (!P_CheckSight(sonic, tails) && P_AproxDistance(P_AproxDistance(tails->x-sonic->x, tails->y-sonic->y), tails->z-sonic->z) > FixedMul(1024*FRACUNIT, tails->scale))
return true;

View file

@ -1394,9 +1394,9 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
memset(netbuffer->u.serverinfo.maptitle, 0, sizeof netbuffer->u.serverinfo.maptitle);
if (mapheaderinfo[gamemap-1] && *mapheaderinfo[gamemap-1]->lvlttl)
if (worldmapheader && *worldmapheader->lvlttl)
{
char *read = mapheaderinfo[gamemap-1]->lvlttl, *writ = netbuffer->u.serverinfo.maptitle;
char *read = worldmapheader->lvlttl, *writ = netbuffer->u.serverinfo.maptitle;
while (writ < (netbuffer->u.serverinfo.maptitle+32) && *read != '\0')
{
if (!(*read & 0x80))
@ -1407,18 +1407,18 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
read++;
}
*writ = '\0';
//strncpy(netbuffer->u.serverinfo.maptitle, (char *)mapheaderinfo[gamemap-1]->lvlttl, 33);
//strncpy(netbuffer->u.serverinfo.maptitle, (char *)worldmapheader->lvlttl, 33);
}
else
strncpy(netbuffer->u.serverinfo.maptitle, "UNKNOWN", 32);
if (mapheaderinfo[gamemap-1] && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
if (worldmapheader && !(worldmapheader->levelflags & LF_NOZONE))
netbuffer->u.serverinfo.iszone = 1;
else
netbuffer->u.serverinfo.iszone = 0;
if (mapheaderinfo[gamemap-1])
netbuffer->u.serverinfo.actnum = mapheaderinfo[gamemap-1]->actnum;
if (worldmapheader)
netbuffer->u.serverinfo.actnum = worldmapheader->actnum;
p = PutFileNeeded(0);
@ -1706,12 +1706,12 @@ static void CL_LoadReceivedSavegame(boolean reloading)
// load a base level
if (P_LoadNetGame(reloading))
{
const UINT8 actnum = mapheaderinfo[gamemap-1]->actnum;
const UINT8 actnum = worldmapheader->actnum;
CONS_Printf(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap));
if (strcmp(mapheaderinfo[gamemap-1]->lvlttl, ""))
if (strcmp(worldmapheader->lvlttl, ""))
{
CONS_Printf(": %s", mapheaderinfo[gamemap-1]->lvlttl);
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
CONS_Printf(": %s", worldmapheader->lvlttl);
if (!(worldmapheader->levelflags & LF_NOZONE))
CONS_Printf(M_GetText(" Zone"));
if (actnum > 0)
CONS_Printf(" %2d", actnum);

View file

@ -1163,7 +1163,7 @@ UINT8 CanChangeSkin(INT32 playernum)
return true;
// Force skin in effect.
if ((cv_forceskin.value != -1) || (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0'))
if ((cv_forceskin.value != -1) || (worldmapheader && worldmapheader->forcecharacter[0] != '\0'))
return false;
// Can change skin in intermission and whatnot.
@ -2200,10 +2200,8 @@ static void Got_Switchworld(UINT8 **cp, INT32 playernum)
if (nodetach) // Don't detach from the current world, if any
{
#if 1
if (player->world)
((world_t *)player->world)->players--;
#endif
P_GetPlayerWorld(player)->players--;
player->world = NULL;
}
@ -4385,7 +4383,8 @@ static void Gravity_OnChange(void)
if (!CV_IsSetToDefault(&cv_gravity))
G_SetUsedCheats(false);
gravity = cv_gravity.value;
if (world)
world->gravity = cv_gravity.value;
}
static void SoundTest_OnChange(void)
@ -4578,10 +4577,10 @@ static void Command_Showmap_f(void)
{
if (gamestate == GS_LEVEL)
{
if (mapheaderinfo[gamemap-1]->actnum)
CONS_Printf("%s (%d): %s %d\n", G_BuildMapName(gamemap), gamemap, mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->actnum);
if (worldmapheader->actnum)
CONS_Printf("%s (%d): %s %d\n", G_BuildMapName(gamemap), gamemap, worldmapheader->lvlttl, worldmapheader->actnum);
else
CONS_Printf("%s (%d): %s\n", G_BuildMapName(gamemap), gamemap, mapheaderinfo[gamemap-1]->lvlttl);
CONS_Printf("%s (%d): %s\n", G_BuildMapName(gamemap), gamemap, worldmapheader->lvlttl);
}
else
CONS_Printf(M_GetText("You must be in a level to use this.\n"));

View file

@ -388,6 +388,10 @@ typedef struct
extern mapheader_t* mapheaderinfo[NUMMAPS];
extern mapheader_t* curmapheader;
extern mapheader_t* nextmapheader;
extern mapheader_t* worldmapheader;
// Gametypes
#define NUMGAMETYPEFREESLOTS 128
enum GameType
@ -548,14 +552,12 @@ extern UINT8 useContinues;
extern UINT8 shareEmblems;
extern mobj_t *hunt1, *hunt2, *hunt3; // Emerald hunt locations
#define NUM_EMERALD_HUNT_LOCATIONS 3
// For racing
extern UINT32 countdown;
extern UINT32 countdown2;
extern fixed_t gravity;
//for CTF balancing
extern INT16 autobalance;
extern INT16 teamscramble;

View file

@ -2431,7 +2431,9 @@ void F_StartTitleScreen(void)
P_UnloadWorldList();
maptol = mapheaderinfo[gamemap-1]->typeoflevel;
curmapheader = nextmapheader = mapheaderinfo[gamemap-1];
worldmapheader = curmapheader;
maptol = curmapheader->typeoflevel;
G_DoLoadLevel(&players[displayplayer], false, true);
if (!titlemap)
@ -2477,6 +2479,8 @@ void F_StartTitleScreen(void)
gamemap = 1; // g_game.c
if (!mapheaderinfo[gamemap-1])
P_AllocMapHeader(gamemap-1);
curmapheader = nextmapheader = mapheaderinfo[gamemap-1];
worldmapheader = curmapheader;
CON_ClearHUD();
}

View file

@ -1868,6 +1868,8 @@ void G_DoPlayDemo(char *defdemoname)
}
demo_p += 4; // "PLAY"
gamemap = READINT16(demo_p);
curmapheader = nextmapheader = mapheaderinfo[gamemap-1];
worldmapheader = curmapheader;
demo_p += 16; // mapmd5
demoflags = READUINT8(demo_p);

View file

@ -164,11 +164,13 @@ mobj_t *blueflag;
mapthing_t *rflagpoint;
mapthing_t *bflagpoint;
struct quake quake;
// Map Header Information
mapheader_t* mapheaderinfo[NUMMAPS] = {NULL};
mapheader_t* curmapheader = NULL;
mapheader_t* nextmapheader = NULL;
mapheader_t* worldmapheader = NULL;
static boolean exitgame = false;
static boolean retrying = false;
static boolean retryingmodeattack = false;
@ -221,15 +223,8 @@ UINT8 introtoplay;
UINT8 creditscutscene;
UINT8 useBlackRock = 1;
// Emerald locations
mobj_t *hunt1;
mobj_t *hunt2;
mobj_t *hunt3;
UINT32 countdown, countdown2; // for racing
fixed_t gravity;
INT16 autobalance; //for CTF team balance
INT16 teamscramble; //for CTF team scramble
INT16 scrambleplayers[MAXPLAYERS]; //for CTF team scramble
@ -1855,7 +1850,7 @@ void G_DoLoadLevel(player_t *player, boolean addworld, boolean resetplayer)
return;
}
P_FindEmerald();
P_FindEmerald(world);
displayplayer = consoleplayer; // view the guy you are playing
if (!splitscreen && !botingame)
@ -1965,7 +1960,7 @@ boolean G_IsTitleCardAvailable(void)
else if (titlecardforreload)
titleflag = LF_NOTITLECARDRESPAWN;
if (mapheaderinfo[gamemap-1]->levelflags & titleflag)
if (worldmapheader->levelflags & titleflag)
return false;
// The current gametype doesn't have a title card.
@ -1973,7 +1968,7 @@ boolean G_IsTitleCardAvailable(void)
return false;
// The current level has no name.
if (!mapheaderinfo[gamemap-1]->lvlttl[0])
if (!worldmapheader->lvlttl[0])
return false;
// The title card is available.
@ -2654,7 +2649,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
if (betweenmaps || !G_IsSpecialStage(gamemap))
{
rings = (ultimatemode ? 0 : mapheaderinfo[gamemap-1]->startrings);
rings = (ultimatemode ? 0 : curmapheader->startrings);
spheres = 0;
}
else
@ -2769,23 +2764,23 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
{
if (mapmusflags & MUSIC_RELOADRESET)
{
strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
strncpy(mapmusname, worldmapheader->musname, 7);
mapmusname[6] = 0;
mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK);
mapmusposition = mapheaderinfo[gamemap-1]->muspos;
mapmusflags = (worldmapheader->mustrack & MUSIC_TRACKMASK);
mapmusposition = worldmapheader->muspos;
}
// This is in S_Start, but this was not here previously.
// if (RESETMUSIC)
// if (S_ShouldResetMusic(worldmapheader))
// S_StopMusic();
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
}
if (gametyperules & GTR_EMERALDHUNT)
P_FindEmerald(); // scan for emeralds to hunt for
P_FindEmerald(p->world); // scan for emeralds to hunt for
// If NiGHTS, find lowest mare to start with.
p->mare = P_FindLowestMare();
p->mare = P_FindLowestMare(p->world);
CONS_Debug(DBG_NIGHTS, M_GetText("Current mare is %d\n"), p->mare);
@ -3202,7 +3197,7 @@ void G_DoReborn(INT32 playernum)
players[i].starpostnum = 0;
}
}
if (!countdowntimeup && (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD) && !(marathonmode & MA_INIT))
if (!countdowntimeup && (curmapheader->levelflags & LF_NORELOAD) && !(marathonmode & MA_INIT))
{
P_RespawnThings();
@ -3983,11 +3978,11 @@ void G_SetNextMap(boolean usespec, boolean inspec)
// nextmap is 0-based, unlike gamemap
if (nextmapoverride != 0)
nextmap = (INT16)(nextmapoverride-1);
else if (marathonmode && mapheaderinfo[gamemap-1]->marathonnext)
nextmap = (INT16)(mapheaderinfo[gamemap-1]->marathonnext-1);
else if (marathonmode && curmapheader->marathonnext)
nextmap = (INT16)(curmapheader->marathonnext-1);
else
{
nextmap = (INT16)(mapheaderinfo[gamemap-1]->nextlevel-1);
nextmap = (INT16)(curmapheader->nextlevel-1);
if (marathonmode && nextmap == spmarathon_start-1)
nextmap = 1100-1; // No infinite loop for you
}
@ -4161,14 +4156,14 @@ void G_AfterIntermission(void)
HU_ClearCEcho();
if ((gametyperules & GTR_CUTSCENES) && mapheaderinfo[gamemap-1]->cutscenenum
if ((gametyperules & GTR_CUTSCENES) && curmapheader->cutscenenum
&& !modeattacking
&& skipstats <= 1
&& (gamecomplete || !(marathonmode & MA_NOCUTSCENES))
&& stagefailed == false)
{
// Start a custom cutscene.
F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false, false);
F_StartCustomCutscene(curmapheader->cutscenenum-1, false, false, false);
}
else
{
@ -5068,7 +5063,12 @@ void G_InitNew(player_t *player,
if(!mapheaderinfo[gamemap-1])
P_AllocMapHeader(gamemap-1);
maptol = mapheaderinfo[gamemap-1]->typeoflevel;
nextmapheader = mapheaderinfo[gamemap-1];
maptol = curmapheader->typeoflevel;
if (!addworld)
curmapheader = nextmapheader;
worldmapheader = nextmapheader;
// Don't carry over custom music change to another map.
mapmusflags |= MUSIC_RELOADRESET;
@ -5077,14 +5077,15 @@ void G_InitNew(player_t *player,
automapactive = false;
imcontinuing = false;
if ((gametyperules & GTR_CUTSCENES) && !skipprecutscene && mapheaderinfo[gamemap-1]->precutscenenum && !modeattacking && !(marathonmode & MA_NOCUTSCENES)) // Start a custom cutscene.
F_StartCustomCutscene(mapheaderinfo[gamemap-1]->precutscenenum-1, true, resetplayer, FLS);
if (!addworld && ((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);
if (addworld && player != &players[consoleplayer])
return;
// current world is hopefully the newly loaded world at this point
if (netgame)
{
char *title = G_BuildMapTitle(gamemap);

View file

@ -5371,6 +5371,14 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
if (viewnumber == 0) // Only do it if it's the first screen being rendered
HWD.pfnClearBuffer(true, false, &ClearColor); // Clear the Color Buffer, stops HOMs. Also seems to fix the skybox issue on Intel GPUs.
// Uh, double check? I don't know, I'm not paid for this.
if (viewworld->extrasubsectors == NULL)
HWR_CreatePlanePolygons((INT32)viewworld->numnodes - 1);
// Same
if (viewworld->sky_dome == NULL)
HWR_BuildSkyDome(viewworld);
PS_START_TIMING(ps_hw_skyboxtime);
if (skybox && drawsky) // If there's a skybox and we should be drawing the sky, draw the skybox
HWR_RenderSkyboxView(viewnumber, player); // This is drawn before everything else so it is placed behind

View file

@ -2577,15 +2577,15 @@ static int lib_pStartQuake(lua_State *L)
q_epicenter.z = 0;
lua_pop(L, 1);
quake.epicenter = &q_epicenter;
world->quake.epicenter = &q_epicenter;
}
else
quake.epicenter = NULL;
quake.radius = luaL_optinteger(L, 4, 512*FRACUNIT);
world->quake.epicenter = NULL;
world->quake.radius = luaL_optinteger(L, 4, 512*FRACUNIT);
// These things are actually used in 2.1.
quake.intensity = q_intensity;
quake.time = q_time;
world->quake.intensity = q_intensity;
world->quake.time = q_time;
return 0;
}

View file

@ -383,7 +383,7 @@ int LUA_PushGlobals(lua_State *L, const char *word)
lua_pushinteger(L, emeralds);
return 1;
} else if (fastcmp(word,"gravity")) {
lua_pushinteger(L, gravity);
lua_pushinteger(L, world->gravity);
return 1;
} else if (fastcmp(word,"VERSION")) {
lua_pushinteger(L, VERSION);
@ -441,7 +441,7 @@ int LUA_CheckGlobals(lua_State *L, const char *word)
else if (fastcmp(word, "token"))
token = (UINT32)luaL_checkinteger(L, 2);
else if (fastcmp(word, "gravity"))
gravity = (fixed_t)luaL_checkinteger(L, 2);
world->gravity = (fixed_t)luaL_checkinteger(L, 2);
else if (fastcmp(word, "stoppedclock"))
stoppedclock = luaL_checkboolean(L, 2);
else if (fastcmp(word, "displayplayer"))

View file

@ -4716,10 +4716,10 @@ static void M_DrawPauseMenu(void)
// Draw any and all emblems at the top.
M_DrawMapEmblems(gamemap, 272, 28, true);
if (mapheaderinfo[gamemap-1]->actnum != 0)
V_DrawString(40, 28, V_YELLOWMAP, va("%s %d", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->actnum));
if (curmapheader->actnum != 0)
V_DrawString(40, 28, V_YELLOWMAP, va("%s %d", curmapheader->lvlttl, curmapheader->actnum));
else
V_DrawString(40, 28, V_YELLOWMAP, mapheaderinfo[gamemap-1]->lvlttl);
V_DrawString(40, 28, V_YELLOWMAP, curmapheader->lvlttl);
// Set up the detail boxes.
{

View file

@ -830,11 +830,11 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png
else
snprintf(maptext, 8, "Unknown");
if (gamestate == GS_LEVEL && mapheaderinfo[gamemap-1]->lvlttl[0] != '\0')
if (gamestate == GS_LEVEL && worldmapheader->lvlttl[0] != '\0')
snprintf(lvlttltext, 48, "%s%s%s",
mapheaderinfo[gamemap-1]->lvlttl,
(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " Zone",
(mapheaderinfo[gamemap-1]->actnum > 0) ? va(" %d",mapheaderinfo[gamemap-1]->actnum) : "");
worldmapheader->lvlttl,
(worldmapheader->levelflags & LF_NOZONE) ? "" : " Zone",
(worldmapheader->actnum > 0) ? va(" %d", worldmapheader->actnum) : "");
else
snprintf(lvlttltext, 48, "Unknown");

View file

@ -756,7 +756,7 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed
if (player->quittime)
continue; // Ignore uncontrolled bodies
if (player->world != actor->world)
if (P_GetPlayerWorld(player) != actor->world)
continue; // Different world
if (dist > 0
@ -1664,10 +1664,10 @@ static void P_ParabolicMove(mobj_t *actor, fixed_t x, fixed_t y, fixed_t z, fixe
actor->momx = FixedMul(FixedDiv(x, dh), speed);
actor->momy = FixedMul(FixedDiv(y, dh), speed);
if (!gravity)
if (!world->gravity)
return;
dh = FixedDiv(FixedMul(dh, gravity), speed);
dh = FixedDiv(FixedMul(dh, world->gravity), speed);
actor->momz = (dh>>1) + FixedDiv(z, dh<<1);
}
@ -2731,7 +2731,7 @@ void A_LobShot(mobj_t *actor)
dist = P_AproxDistance(actor->target->x - shot->x, actor->target->y - shot->y);
horizontal = dist / airtime;
vertical = FixedMul((gravity*airtime)/2, shot->scale);
vertical = FixedMul((world->gravity*airtime)/2, shot->scale);
shot->momx = FixedMul(horizontal, FINECOSINE(an));
shot->momy = FixedMul(horizontal, FINESINE(an));
@ -2753,7 +2753,7 @@ void A_LobShot(mobj_t *actor)
CONS_Debug(DBG_GAMELOGIC, "orig: %d\n", (orig)>>FRACBITS);
horizontal = dist / airtime;
vertical = (gravity*airtime)/2;
vertical = (world->gravity*airtime)/2;
}
dist -= orig;
shot->momx = FixedMul(horizontal, FINECOSINE(an));
@ -3967,26 +3967,26 @@ static void P_DoBossVictory(mobj_t *mo)
EV_DoElevator(LE_CAPSULE2, NULL, elevateHighest);
}
if (mapheaderinfo[gamemap-1]->muspostbossname[0] &&
S_MusicExists(mapheaderinfo[gamemap-1]->muspostbossname, !midi_disabled, !digital_disabled))
if (worldmapheader->muspostbossname[0] &&
S_MusicExists(worldmapheader->muspostbossname, !midi_disabled, !digital_disabled))
{
// Touching the egg trap button calls P_DoPlayerExit, which calls P_RestoreMusic.
// So just park ourselves in the mapmus variables.
// But don't change the mapmus variables if they were modified from their level header values (e.g., TUNES).
boolean changed = strnicmp(mapheaderinfo[gamemap-1]->musname, S_MusicName(), 7);
if (!strnicmp(mapheaderinfo[gamemap-1]->musname, mapmusname, 7))
boolean changed = strnicmp(worldmapheader->musname, S_MusicName(), 7);
if (!strnicmp(worldmapheader->musname, mapmusname, 7))
{
strncpy(mapmusname, mapheaderinfo[gamemap-1]->muspostbossname, 7);
strncpy(mapmusname, worldmapheader->muspostbossname, 7);
mapmusname[6] = 0;
mapmusflags = (mapheaderinfo[gamemap-1]->muspostbosstrack & MUSIC_TRACKMASK) | MUSIC_RELOADRESET;
mapmusposition = mapheaderinfo[gamemap-1]->muspostbosspos;
mapmusflags = (worldmapheader->muspostbosstrack & MUSIC_TRACKMASK) | MUSIC_RELOADRESET;
mapmusposition = worldmapheader->muspostbosspos;
}
// don't change if we're in another tune
// but in case we're in jingle, use our parked mapmus variables so the correct track restores
if (!changed)
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, (1*MUSICRATE)+(MUSICRATE/2),
mapheaderinfo[gamemap-1]->muspostbossfadein);
worldmapheader->muspostbossfadein);
}
}
}
@ -4412,7 +4412,7 @@ void A_SuperSneakers(mobj_t *actor)
if (P_IsLocalPlayer(player) && !player->powers[pw_super])
{
if (S_SpeedMusic(0.0f) && (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC))
if (S_SpeedMusic(0.0f) && (worldmapheader->levelflags & LF_SPEEDMUSIC))
S_SpeedMusic(1.4f);
else
P_PlayJingle(player, JT_SHOES);
@ -11591,7 +11591,7 @@ void A_BrakLobShot(mobj_t *actor)
return; // Don't even bother if we've got nothing to aim at.
// Look up actor's current gravity situation
g = FixedMul(gravity, P_GetSectorGravityFactor(actor->subsector->sector));
g = FixedMul(world->gravity, P_GetSectorGravityFactor(actor->subsector->sector));
// Look up distance between actor and its target
x = P_AproxDistance(actor->target->x - actor->x, actor->target->y - actor->y);
@ -11706,7 +11706,7 @@ void A_NapalmScatter(mobj_t *actor)
airtime = 16<<FRACBITS;
// Look up actor's current gravity situation
g = FixedMul(gravity, P_GetSectorGravityFactor(actor->subsector->sector));
g = FixedMul(world->gravity, P_GetSectorGravityFactor(actor->subsector->sector));
// vy = (g*(airtime-1))/2
vy = FixedMul(g,(airtime-(1<<FRACBITS)))>>1;
@ -11761,12 +11761,12 @@ mobj_t *P_InternalFlickySpawn(mobj_t *actor, mobjtype_t flickytype, fixed_t momz
if (!flickytype)
{
if (!mapheaderinfo[gamemap-1] || !mapheaderinfo[gamemap-1]->numFlickies) // No mapheader, no shoes, no service.
if (!worldmapheader || !worldmapheader->numFlickies) // No mapheader, no shoes, no service.
return NULL;
else
{
INT32 prandom = P_RandomKey(mapheaderinfo[gamemap-1]->numFlickies);
flickytype = mapheaderinfo[gamemap-1]->flickies[prandom];
INT32 prandom = P_RandomKey(worldmapheader->numFlickies);
flickytype = worldmapheader->flickies[prandom];
}
}
@ -12416,7 +12416,7 @@ void A_Boss5Jump(mobj_t *actor)
return; // Don't even bother if we've got nothing to aim at.
// Look up actor's current gravity situation
g = FixedMul(gravity, P_GetSectorGravityFactor(actor->subsector->sector));
g = FixedMul(world->gravity, P_GetSectorGravityFactor(actor->subsector->sector));
// Look up distance between actor and its tracer
x = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y);
@ -12519,10 +12519,10 @@ void A_MineExplode(mobj_t *actor)
A_Scream(actor);
actor->flags = MF_NOGRAVITY|MF_NOCLIP;
quake.epicenter = NULL;
quake.radius = 512*FRACUNIT;
quake.intensity = 8*FRACUNIT;
quake.time = TICRATE/3;
world->quake.epicenter = NULL;
world->quake.radius = 512*FRACUNIT;
world->quake.intensity = 8*FRACUNIT;
world->quake.time = TICRATE/3;
P_RadiusAttack(actor, actor->tracer, 192*FRACUNIT, DMG_CANHURTSELF, true);
P_MobjCheckWater(actor);
@ -13505,14 +13505,14 @@ void A_Boss5BombExplode(mobj_t *actor)
P_DustRing(locvar1, 6, actor->x, actor->y, actor->z+actor->height/2, 3*actor->radius, FRACUNIT, FRACUNIT, actor->scale);
//P_StartQuake(9*actor->scale, TICRATE/6, {actor->x, actor->y, actor->z}, 20*actor->radius);
// the above does not exist, so we set the quake values directly instead
quake.intensity = 9*actor->scale;
quake.time = TICRATE/6;
world->quake.intensity = 9*actor->scale;
world->quake.time = TICRATE/6;
// the following quake values have no effect atm? ah well, may as well set them anyway
{
mappoint_t q_epicenter = {actor->x, actor->y, actor->z};
quake.epicenter = &q_epicenter;
world->quake.epicenter = &q_epicenter;
}
quake.radius = 20*actor->radius;
world->quake.radius = 20*actor->radius;
}
static mobj_t *dustdevil;
@ -13785,10 +13785,10 @@ void A_TNTExplode(mobj_t *actor)
epicenter.x = actor->x;
epicenter.y = actor->y;
epicenter.z = actor->z;
quake.intensity = 9*FRACUNIT;
quake.time = TICRATE/6;
quake.epicenter = &epicenter;
quake.radius = 512*FRACUNIT;
world->quake.intensity = 9*FRACUNIT;
world->quake.time = TICRATE/6;
world->quake.epicenter = &epicenter;
world->quake.radius = 512*FRACUNIT;
if (locvar1)
{

View file

@ -689,7 +689,7 @@ void T_BounceCheese(bouncecheese_t *bouncer)
}
else if (bouncer->sector->ceilingheight > bouncer->ceilingwasheight) // Up
{
bouncer->speed += gravity;
bouncer->speed += world->gravity;
}
if (abs(bouncer->speed) < 2*FRACUNIT
@ -838,7 +838,7 @@ void T_StartCrumble(crumble_t *crumble)
// Only fall like this if it isn't meant to float on water
if (!(crumble->flags & CF_FLOATBOB))
{
crumble->speed += gravity; // Gain more and more speed
crumble->speed += world->gravity; // Gain more and more speed
if ((!(crumble->flags & CF_REVERSE) && crumble->sector->ceilingheight >= -16384*FRACUNIT)
|| ((crumble->flags & CF_REVERSE) && crumble->sector->ceilingheight <= 16384*FRACUNIT))

View file

@ -725,18 +725,24 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
break;
// Emerald Hunt
case MT_EMERHUNT:
case MT_EMERHUNT: {
unsigned remaining_emeralds = 0;
if (player->bot && player->bot != BOT_MPAI)
return;
if (hunt1 == special)
hunt1 = NULL;
else if (hunt2 == special)
hunt2 = NULL;
else if (hunt3 == special)
hunt3 = NULL;
for (i = 0; i < NUM_EMERALD_HUNT_LOCATIONS; i++)
{
if (world->emerald_hunt_locations[i])
{
if (world->emerald_hunt_locations[i] == special)
P_SetTarget(&world->emerald_hunt_locations[i], NULL);
else
remaining_emeralds++;
}
}
if (!hunt1 && !hunt2 && !hunt3)
if (!remaining_emeralds)
{
for (i = 0; i < MAXPLAYERS; i++)
{
@ -748,7 +754,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
//S_StartSound(NULL, sfx_lvpass);
}
break;
}
// Collectible emeralds
case MT_EMERALD1:
case MT_EMERALD2:
@ -1678,9 +1684,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_SetObjectMomZ(toucher, FixedDiv(69*FRACUNIT,10*FRACUNIT), false);
if (P_IsLocalPlayer(player))
{
quake.intensity = 9*FRACUNIT;
quake.time = TICRATE/2;
quake.epicenter = NULL;
world->quake.intensity = 9*FRACUNIT;
world->quake.time = TICRATE/2;
world->quake.epicenter = NULL;
}
#if 0 // camera redirection - deemed unnecessary
@ -3149,7 +3155,7 @@ static void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
if (oldnightstime > 10*TICRATE
&& player->nightstime < 10*TICRATE)
{
if ((mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN)
if ((worldmapheader->levelflags & LF_MIXNIGHTSCOUNTDOWN)
#ifdef _WIN32
// win32 MIDI volume hack means we cannot fade down the music
&& S_MusicType() != MU_MID
@ -3605,7 +3611,7 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source)
if (oldnightstime > 10*TICRATE
&& player->nightstime < 10*TICRATE)
{
if (mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN)
if (worldmapheader->levelflags & LF_MIXNIGHTSCOUNTDOWN)
{
S_FadeMusic(0, 10*MUSICRATE);
S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS.

View file

@ -208,8 +208,8 @@ boolean P_SuperReady(player_t *player);
void P_DoJump(player_t *player, boolean soundandstate);
#define P_AnalogMove(player) (P_ControlStyle(player) == CS_LMAOGALOG)
boolean P_TransferToNextMare(player_t *player);
UINT8 P_FindLowestMare(void);
void P_FindEmerald(void);
UINT8 P_FindLowestMare(world_t *w);
void P_FindEmerald(world_t *w);
void P_TransferToAxis(player_t *player, INT32 axisnum);
boolean P_PlayerMoving(INT32 pnum);
void P_SpawnThokMobj(player_t *player);
@ -276,7 +276,7 @@ extern consvar_t cv_gravity, cv_movebob;
mobjtype_t P_GetMobjtype(UINT16 mthingtype);
void P_RespawnSpecials(void);
void P_RespawnSpecials(world_t *w);
mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type);
@ -288,8 +288,8 @@ boolean P_MobjWasRemoved(mobj_t *th);
void P_RemoveSavegameMobj(mobj_t *th);
boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state);
boolean P_SetMobjState(mobj_t *mobj, statenum_t state);
void P_RunShields(void);
void P_RunOverlays(void);
void P_RunShields(world_t *w);
void P_RunOverlays(world_t *w);
void P_HandleMinecartSegments(mobj_t *mobj);
void P_MobjThinker(mobj_t *mobj);
boolean P_RailThinker(mobj_t *mobj);
@ -301,17 +301,17 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t
fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
#define P_GetFloorZ(mobj, sector, x, y, line) P_MobjFloorZ(mobj, sector, NULL, x, y, line, false, false)
#define P_GetCeilingZ(mobj, sector, x, y, line) P_MobjCeilingZ(mobj, sector, NULL, x, y, line, true, false)
#define P_GetFOFTopZ(mobj, sector, fof, x, y, line) P_MobjCeilingZ(mobj, sectors + fof->secnum, sector, x, y, line, false, false)
#define P_GetFOFBottomZ(mobj, sector, fof, x, y, line) P_MobjFloorZ(mobj, sectors + fof->secnum, sector, x, y, line, true, false)
#define P_GetFOFTopZ(mobj, sector, fof, x, y, line) P_MobjCeilingZ(mobj, P_GetMobjWorld(mobj)->sectors + fof->secnum, sector, x, y, line, false, false)
#define P_GetFOFBottomZ(mobj, sector, fof, x, y, line) P_MobjFloorZ(mobj, P_GetMobjWorld(mobj)->sectors + fof->secnum, sector, x, y, line, true, false)
#define P_GetSpecialBottomZ(mobj, src, bound) P_MobjFloorZ(mobj, src, bound, mobj->x, mobj->y, NULL, src != bound, true)
#define P_GetSpecialTopZ(mobj, src, bound) P_MobjCeilingZ(mobj, src, bound, mobj->x, mobj->y, NULL, src == bound, true)
fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
#define P_CameraGetFloorZ(mobj, sector, x, y, line) P_CameraFloorZ(mobj, sector, NULL, x, y, line, false, false)
#define P_CameraGetCeilingZ(mobj, sector, x, y, line) P_CameraCeilingZ(mobj, sector, NULL, x, y, line, true, false)
#define P_CameraGetFOFTopZ(mobj, sector, fof, x, y, line) P_CameraCeilingZ(mobj, sectors + fof->secnum, sector, x, y, line, false, false)
#define P_CameraGetFOFBottomZ(mobj, sector, fof, x, y, line) P_CameraFloorZ(mobj, sectors + fof->secnum, sector, x, y, line, true, false)
fixed_t P_CameraFloorZ(camera_t *cam, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
fixed_t P_CameraCeilingZ(camera_t *cam, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
#define P_CameraGetFloorZ(cam, sector, x, y, line) P_CameraFloorZ(cam, sector, NULL, x, y, line, false, false)
#define P_CameraGetCeilingZ(cam, sector, x, y, line) P_CameraCeilingZ(cam, sector, NULL, x, y, line, true, false)
#define P_CameraGetFOFTopZ(cam, sector, fof, x, y, line) P_CameraCeilingZ(cam, P_GetCameraWorld(cam)->sectors + fof->secnum, sector, x, y, line, false, false)
#define P_CameraGetFOFBottomZ(cam, sector, fof, x, y, line) P_CameraFloorZ(cam, P_GetCameraWorld(cam)->sectors + fof->secnum, sector, x, y, line, true, false)
boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover);
boolean P_CheckDeathPitCollide(mobj_t *mo);
@ -335,6 +335,8 @@ FUNCMATH boolean P_WeaponOrPanel(mobjtype_t type);
void P_CalcChasePostImg(player_t *player, camera_t *thiscam);
boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled);
world_t *P_GetCameraWorld(camera_t *cam);
void P_Attract(mobj_t *source, mobj_t *enemy, boolean nightsgrab);
mobj_t *P_GetClosestAxis(mobj_t *source);

View file

@ -1385,6 +1385,14 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f
} else // Well, that makes it easy. Just get the ceiling height
return sector->ceilingheight;
}
world_t *P_GetCameraWorld(camera_t *cam)
{
if (cam->subsector == NULL)
return NULL;
return (world_t *)cam->subsector->sector->world;
}
static void P_PlayerFlip(mobj_t *mo)
{
if (!mo->player)
@ -1463,7 +1471,7 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
if (!gravsector) // If there is no 3D floor gravity, check sector's gravity
gravsector = mo->subsector->sector;
gravityadd = -FixedMul(gravity, P_GetSectorGravityFactor(gravsector));
gravityadd = -FixedMul(world->gravity, P_GetSectorGravityFactor(gravsector));
if ((gravsector->flags & MSF_GRAVITYFLIP) && gravityadd > 0)
{
@ -3238,8 +3246,8 @@ void P_MobjCheckWater(mobj_t *mobj)
|| ((rover->fofflags & FOF_BLOCKOTHERS) && !mobj->player)))
continue;
topheight = P_GetSpecialTopZ(mobj, sectors + rover->secnum, sector);
bottomheight = P_GetSpecialBottomZ(mobj, sectors + rover->secnum, sector);
topheight = P_GetSpecialTopZ(mobj, P_GetMobjWorld(mobj)->sectors + rover->secnum, sector);
bottomheight = P_GetSpecialBottomZ(mobj, P_GetMobjWorld(mobj)->sectors + rover->secnum, sector);
if (mobj->eflags & MFE_VERTICALFLIP)
{
@ -3760,12 +3768,12 @@ static void P_CheckCrumblingPlatforms(mobj_t *mobj)
if (mobj->eflags & MFE_VERTICALFLIP)
{
if (P_GetSpecialBottomZ(mobj, sectors + rover->secnum, node->m_sector) != mobj->z + mobj->height)
if (P_GetSpecialBottomZ(mobj, P_GetMobjWorld(mobj)->sectors + rover->secnum, node->m_sector) != mobj->z + mobj->height)
continue;
}
else
{
if (P_GetSpecialTopZ(mobj, sectors + rover->secnum, node->m_sector) != mobj->z)
if (P_GetSpecialTopZ(mobj, P_GetMobjWorld(mobj)->sectors + rover->secnum, node->m_sector) != mobj->z)
continue;
}
@ -5354,7 +5362,7 @@ static void P_Boss7Thinker(mobj_t *mobj)
dist = P_AproxDistance(hitspot->x - mobj->x, hitspot->y - mobj->y);
horizontal = dist / airtime;
vertical = (gravity*airtime)/2;
vertical = (world->gravity*airtime)/2;
mobj->momx = FixedMul(horizontal, FINECOSINE(an));
mobj->momy = FixedMul(horizontal, FINESINE(an));
@ -5482,7 +5490,7 @@ static void P_Boss9Thinker(mobj_t *mobj)
{
P_InstaThrust(mobj, mobj->angle, -4*FRACUNIT);
P_TryMove(mobj, mobj->x+mobj->momx, mobj->y+mobj->momy, true);
mobj->momz -= gravity;
mobj->momz -= world->gravity;
if (mobj->z < mobj->watertop || mobj->z < (mobj->floorz + 16*FRACUNIT))
{
mobj->watertop = mobj->floorz + 32*FRACUNIT;
@ -6758,19 +6766,16 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield)
return true;
}
void P_RunShields(void)
void P_RunShields(world_t *w)
{
INT32 i;
// run shields
for (i = 0; i < world->numshields; i++)
for (INT32 i = 0; i < w->numshields; i++)
{
if (!P_MobjWasRemoved(world->shields[i]))
P_ShieldLook(world->shields[i], world->shields[i]->threshold);
P_SetTarget(&world->shields[i], NULL);
if (!P_MobjWasRemoved(w->shields[i]))
P_ShieldLook(w->shields[i], w->shields[i]->threshold);
P_SetTarget(&w->shields[i], NULL);
}
world->numshields = 0;
w->numshields = 0;
}
static boolean P_AddShield(mobj_t *thing)
@ -6807,13 +6812,13 @@ static boolean P_AddShield(mobj_t *thing)
return true;
}
void P_RunOverlays(void)
void P_RunOverlays(world_t *w)
{
// run overlays
mobj_t *mo, *next = NULL;
fixed_t destx,desty,zoffs;
for (mo = world->overlaycap; mo; mo = next)
for (mo = w->overlaycap; mo; mo = next)
{
I_Assert(!P_MobjWasRemoved(mo));
@ -6878,7 +6883,7 @@ void P_RunOverlays(void)
P_SetThingPosition(mo);
P_CheckPosition(mo, mo->x, mo->y);
}
P_SetTarget(&world->overlaycap, NULL);
P_SetTarget(&w->overlaycap, NULL);
}
// Called only when MT_OVERLAY thinks.
@ -11456,7 +11461,7 @@ mobjtype_t P_GetMobjtype(UINT16 mthingtype)
//
// P_RespawnSpecials
//
void P_RespawnSpecials(void)
void P_RespawnSpecials(world_t *w)
{
mapthing_t *mthing = NULL;
@ -11471,15 +11476,15 @@ void P_RespawnSpecials(void)
return;
// nothing left to respawn?
if (world->iquehead == world->iquetail)
if (w->iquehead == w->iquetail)
return;
// the first item in the queue is the first to respawn
// wait at least 30 seconds
if (leveltime - world->itemrespawntime[world->iquetail] < (tic_t)cv_itemrespawntime.value*TICRATE)
if (leveltime - w->itemrespawntime[w->iquetail] < (tic_t)cv_itemrespawntime.value*TICRATE)
return;
mthing = world->itemrespawnque[world->iquetail];
mthing = w->itemrespawnque[w->iquetail];
#ifdef PARANOIA
if (!mthing)
@ -11490,7 +11495,7 @@ void P_RespawnSpecials(void)
P_SpawnMapThing(mthing);
// pull it from the que
world->iquetail = (world->iquetail+1)&(ITEMQUESIZE-1);
w->iquetail = (w->iquetail+1)&(ITEMQUESIZE-1);
}
//

View file

@ -4164,6 +4164,9 @@ static inline void P_NetArchiveSpecials(void)
// Sky number
WRITEINT32(save_p, archiveworld->skynum);
// Gravity
WRITEFIXED(save_p, archiveworld->gravity);
// Current global weather type
WRITEUINT8(save_p, archiveworld->weather);
@ -4196,6 +4199,7 @@ static void P_NetUnArchiveSpecials(void)
P_SetupLevelSky(j, false); // Don't call P_SetupWorldSky from there
P_SetupWorldSky(j, unarchiveworld);
unarchiveworld->gravity = READFIXED(save_p);
unarchiveworld->weather = READUINT8(save_p);
if (world->weather)
@ -4250,7 +4254,8 @@ static inline void P_UnArchiveSPGame(INT16 mapoverride)
if(!mapheaderinfo[gamemap-1])
P_AllocMapHeader(gamemap-1);
//lastmapsaved = gamemap;
curmapheader = nextmapheader = mapheaderinfo[gamemap-1];
worldmapheader = curmapheader;
lastmaploaded = gamemap;
tokenlist = 0;
@ -4337,8 +4342,6 @@ static void P_NetArchiveMisc(boolean resending)
WRITEUINT32(save_p, countdown);
WRITEUINT32(save_p, countdown2);
WRITEFIXED(save_p, baseworld->gravity);
WRITEUINT32(save_p, countdowntimer);
WRITEUINT8(save_p, countdowntimeup);
@ -4438,8 +4441,6 @@ static inline boolean P_NetUnArchiveMisc(boolean reloading)
countdown = READUINT32(save_p);
countdown2 = READUINT32(save_p);
gravity = READFIXED(save_p);
countdowntimer = (tic_t)READUINT32(save_p);
countdowntimeup = (boolean)READUINT8(save_p);
@ -4798,7 +4799,7 @@ void P_SaveNetGame(boolean resending)
for (w = 0; w < numworlds; w++)
{
if (player->world == worldlist[w])
if (P_GetPlayerWorld(player) == worldlist[w])
{
player->worldnum = w;
break;
@ -4931,6 +4932,10 @@ static void P_NetUnArchiveWorlds(boolean reloading)
UnArchiveWorld();
}
gamemap = worldlist[0]->gamemap;
curmapheader = nextmapheader = mapheaderinfo[gamemap-1];
worldmapheader = curmapheader;
P_NetUnArchiveColormaps();
RelinkWorldsToEntities();

View file

@ -6881,9 +6881,7 @@ static boolean P_LoadMapFromFile(void)
static void P_InitLevelSky(INT32 skynum, player_t *player)
{
if (player == &players[consoleplayer])
P_SetupSkyTexture(skynum);
P_SetupSkyTexture(skynum);
P_SetupWorldSky(skynum, world);
levelskynum = skynum;
}
@ -6940,7 +6938,7 @@ static void P_InitPlayerSettings(INT32 i, boolean canresetlives)
players[i].pflags &= ~(PF_GAMETYPEOVER);
}
static void P_InitWorldSettings(void)
static void P_InitWorldSettings(mapheader_t *mapheader)
{
leveltime = 0;
@ -6953,17 +6951,14 @@ static void P_InitWorldSettings(void)
if ((netgame || multiplayer) && !G_IsSpecialStage(gamemap))
nummaprings = -1;
else
nummaprings = mapheaderinfo[gamemap-1]->startrings;
// emerald hunt
hunt1 = hunt2 = hunt3 = NULL;
nummaprings = mapheader->startrings;
// map time limit
if (mapheaderinfo[gamemap-1]->countdown)
if (mapheader->countdown)
{
INT32 i;
tic_t maxtime = 0;
countdowntimer = mapheaderinfo[gamemap-1]->countdown * TICRATE;
countdowntimer = mapheader->countdown * TICRATE;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
@ -6991,20 +6986,17 @@ static void P_InitWorldSettings(void)
stagefailed = G_IsSpecialStage(gamemap);
}
static void P_InitLevelSettings(player_t *player, boolean addworld, boolean fromnetsave)
static void P_InitLevelSettings(mapheader_t *mapheader, player_t *player, boolean addworld, boolean fromnetsave)
{
INT32 i;
boolean canresetlives = true;
if (!addworld)
P_InitWorldSettings();
P_InitWorldSettings(mapheader);
// Reset temporary record data
memset(&ntemprecords, 0, sizeof(nightsdata_t));
// earthquake camera
memset(&quake,0,sizeof(struct quake));
if ((netgame || multiplayer) && G_GametypeUsesCoopStarposts() && cv_coopstarposts.value == 2)
{
for (i = 0; i < MAXPLAYERS; i++)
@ -7067,7 +7059,7 @@ void P_RespawnThings(void)
P_RemoveMobj((mobj_t *)think);
}
P_InitLevelSettings(NULL, false, false);
P_InitLevelSettings(worldmapheader, NULL, false, false);
localaiming = 0;
localaiming2 = 0;
@ -7081,7 +7073,7 @@ void P_RespawnThings(void)
static void P_RunLevelScript(const char *scriptname)
{
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_SCRIPTISFILE))
if (!(worldmapheader->levelflags & LF_SCRIPTISFILE))
{
lumpnum_t lumpnum;
char newname[9];
@ -7414,9 +7406,9 @@ static void P_RunSpecialStageWipe(void)
S_StartSound(NULL, sfx_s3kaf);
// Fade music! Time it to S3KAF: 0.25 seconds is snappy.
if (RESETMUSIC ||
if (S_ShouldResetMusic(nextmapheader) ||
strnicmp(S_MusicName(),
(mapmusflags & MUSIC_RELOADRESET) ? mapheaderinfo[gamemap - 1]->musname : mapmusname, 7))
(mapmusflags & MUSIC_RELOADRESET) ? nextmapheader->musname : mapmusname, 7))
S_FadeOutStopMusic(MUSICRATE/4); //FixedMul(FixedDiv(F_GetWipeLength(wipedefs[wipe_speclevel_towhite])*NEWTICRATERATIO, NEWTICRATE), MUSICRATE)
F_WipeStartScreen();
@ -7584,7 +7576,7 @@ static void P_InitGametype(player_t *player, boolean addworld)
CV_StealthSetValue(&cv_numlaps,
(cv_basenumlaps.value)
? cv_basenumlaps.value
: mapheaderinfo[gamemap - 1]->numlaps);
: nextmapheader->numlaps);
}
/** Loads a level from a lump or external wad.
@ -7603,7 +7595,7 @@ boolean P_LoadLevel(player_t *player, boolean addworld, boolean fromnetsave, boo
levelloading = true;
// This is needed. Don't touch.
maptol = mapheaderinfo[gamemap-1]->typeoflevel;
maptol = nextmapheader->typeoflevel;
gametyperules = gametypedefaultrules[gametype];
CON_Drawer(); // let the user know what we are going to do
@ -7625,18 +7617,18 @@ boolean P_LoadLevel(player_t *player, boolean addworld, boolean fromnetsave, boo
// Clear CECHO messages
HU_ClearCEcho();
if (mapheaderinfo[gamemap-1]->runsoc[0] != '#')
P_RunSOC(mapheaderinfo[gamemap-1]->runsoc);
if (nextmapheader->runsoc[0] != '#')
P_RunSOC(nextmapheader->runsoc);
if (cv_runscripts.value && mapheaderinfo[gamemap-1]->scriptname[0] != '#')
P_RunLevelScript(mapheaderinfo[gamemap-1]->scriptname);
if (cv_runscripts.value && nextmapheader->scriptname[0] != '#')
P_RunLevelScript(nextmapheader->scriptname);
P_InitLevelSettings(player, addworld, fromnetsave);
P_InitLevelSettings(nextmapheader, player, addworld, fromnetsave);
postimgtype = postimgtype2 = postimg_none;
if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0')
P_ForceCharacter(mapheaderinfo[gamemap-1]->forcecharacter);
if (nextmapheader->forcecharacter[0] != '\0')
P_ForceCharacter(nextmapheader->forcecharacter);
if (!dedicated)
{
@ -7694,9 +7686,9 @@ boolean P_LoadLevel(player_t *player, boolean addworld, boolean fromnetsave, boo
// Fade out music here. Deduct 2 tics so the fade volume actually reaches 0.
// But don't halt the music! S_Start will take care of that. This dodges a MIDI crash bug.
if (!(reloadinggamestate || titlemapinaction) && (RESETMUSIC ||
if (!(reloadinggamestate || titlemapinaction) && (S_ShouldResetMusic(nextmapheader) ||
strnicmp(S_MusicName(),
(mapmusflags & MUSIC_RELOADRESET) ? mapheaderinfo[gamemap-1]->musname : mapmusname, 7)))
(mapmusflags & MUSIC_RELOADRESET) ? nextmapheader->musname : mapmusname, 7)))
{
S_FadeMusic(0, FixedMul(
FixedDiv((F_GetWipeLength(wipedefs[wipe_level_toblack])-2)*NEWTICRATERATIO, NEWTICRATE), MUSICRATE));
@ -7722,9 +7714,9 @@ boolean P_LoadLevel(player_t *player, boolean addworld, boolean fromnetsave, boo
char tx[64];
V_DrawSmallString(1, 191, V_ALLOWLOWERCASE|V_TRANSLUCENT|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("Speeding off to..."));
snprintf(tx, 63, "%s%s%s",
mapheaderinfo[gamemap-1]->lvlttl,
(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " Zone",
(mapheaderinfo[gamemap-1]->actnum > 0) ? va(" %d",mapheaderinfo[gamemap-1]->actnum) : "");
nextmapheader->lvlttl,
(nextmapheader->levelflags & LF_NOZONE) ? "" : " Zone",
(nextmapheader->actnum > 0) ? va(" %d",nextmapheader->actnum) : "");
V_DrawSmallString(1, 195, V_ALLOWLOWERCASE|V_TRANSLUCENT|V_SNAPTOLEFT|V_SNAPTOBOTTOM, tx);
I_UpdateNoVsync();
}
@ -7732,7 +7724,7 @@ boolean P_LoadLevel(player_t *player, boolean addworld, boolean fromnetsave, boo
// As oddly named as this is, this handles music only.
// We should be fine starting it here.
// Don't do this during titlemap, because the menu code handles music by itself.
S_Start();
S_Start(nextmapheader);
levelfadecol = (ranspecialwipe) ? 0 : 31;
@ -7740,10 +7732,17 @@ boolean P_LoadLevel(player_t *player, boolean addworld, boolean fromnetsave, boo
F_EndTextPrompt(false, true);
}
}
else
{
S_SetMapMusic(nextmapheader);
S_StopMusic();
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
}
if (player && (!titlemapinaction))
P_UnloadWorldPlayer(player);
// Initialize the world
world = P_InitNewWorld();
thlist = world->thlist;
@ -7796,7 +7795,7 @@ boolean P_LoadLevel(player_t *player, boolean addworld, boolean fromnetsave, boo
if (lastloadedmaplumpnum == LUMPERROR)
I_Error("Map %s not found.\n", maplumpname);
R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette);
R_ReInitColormaps(worldmapheader->palette);
if (!addworld)
{
// Init Boom colormaps.
@ -7805,7 +7804,7 @@ boolean P_LoadLevel(player_t *player, boolean addworld, boolean fromnetsave, boo
CON_SetupBackColormap();
// SRB2 determines the sky texture to be used depending on the map header.
P_InitLevelSky(mapheaderinfo[gamemap-1]->skynum, player);
P_InitLevelSky(worldmapheader->skynum, player);
P_ResetSpawnpoints();
@ -7821,6 +7820,10 @@ boolean P_LoadLevel(player_t *player, boolean addworld, boolean fromnetsave, boo
// init anything that P_SpawnSlopes/P_LoadThings needs to know
P_InitSpecials();
// Defaults in case levels don't have them set.
sstimer = worldmapheader->sstimer*TICRATE + 6;
ssspheres = worldmapheader->ssspheres;
P_SpawnSlopes(fromnetsave);
P_SpawnMapThings(!fromnetsave);
@ -7916,12 +7919,12 @@ boolean P_LoadLevel(player_t *player, boolean addworld, boolean fromnetsave, boo
P_MapEnd(); // just in case MapLoad modifies tmthing
}
// No render mode or reloading gamestate, stop here.
if (rendermode == render_none || reloadinggamestate)
// Done here
if (addworld)
return true;
//if (!runforself || (addworld && splitscreen))
if (addworld)
// No render mode or reloading gamestate, stop here.
if (rendermode == render_none || reloadinggamestate)
return true;
R_ResetViewInterpolation(0);

View file

@ -396,23 +396,18 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2)
s1 = t1->subsector->sector;
s2 = t2->subsector->sector;
// Check in REJECT table.
if (s1->world == s2->world
&& t1->world == t2->world
&& t1->world == s1->world
&& t2->world == s2->world)
{
world_t *w = s1->world;
size_t pnum = (s1-w->sectors)*w->numsectors + (s2-w->sectors);
world_t *w = P_GetMobjWorld(t1);
if (w->rejectmatrix != NULL)
{
if (w->rejectmatrix[pnum>>3] & (1 << (pnum&7))) // can't possibly be connected
return false;
}
}
else
// Cannot possibly be seen if the worlds don't match
if (w != P_GetMobjWorld(t2))
return false;
else if (w->rejectmatrix != NULL)
{
// Check in REJECT table.
size_t pnum = (s1-w->sectors)*w->numsectors + (s2-w->sectors);
if (w->rejectmatrix[pnum>>3] & (1 << (pnum&7))) // can't possibly be connected
return false;
}
// killough 11/98: shortcut for melee situations
// same subsector? obviously visible

View file

@ -1391,11 +1391,11 @@ static boolean P_CheckNightsTriggerLine(line_t *triggerline, mobj_t *actor)
if (specialtype == 323)
{
// run only when no mares are found
if (donomares && P_FindLowestMare() != UINT8_MAX)
if (donomares && P_FindLowestMare(world) != UINT8_MAX)
return false;
// run only if there is a mare present
if (!donomares && P_FindLowestMare() == UINT8_MAX)
if (!donomares && P_FindLowestMare(world) == UINT8_MAX)
return false;
// run only if player is nightserizing from non-nights
@ -1505,7 +1505,7 @@ static boolean P_CheckPlayerMareOld(line_t *triggerline)
if (!(maptol & TOL_NIGHTS))
return false;
mare = P_FindLowestMare();
mare = P_FindLowestMare(world);
if (triggerline->flags & ML_NOCLIMB)
return mare <= targetmare;
@ -1524,7 +1524,7 @@ static boolean P_CheckPlayerMare(line_t *triggerline)
if (!(maptol & TOL_NIGHTS))
return false;
mare = P_FindLowestMare();
mare = P_FindLowestMare(world);
switch (triggerline->args[2])
{
@ -2009,10 +2009,10 @@ static void P_PlaySFX(INT32 sfxnum, mobj_t *mo, sector_t *callsec, INT16 tag, te
if (!Tag_Find(&rover->master->frontsector->tags, tag))
continue;
if (camobj->z > P_GetSpecialTopZ(camobj, sectors + rover->secnum, camobj->subsector->sector))
if (camobj->z > P_GetSpecialTopZ(camobj, P_GetMobjWorld(camobj)->sectors + rover->secnum, camobj->subsector->sector))
continue;
if (camobj->z + camobj->height < P_GetSpecialBottomZ(camobj, sectors + rover->secnum, camobj->subsector->sector))
if (camobj->z + camobj->height < P_GetSpecialBottomZ(camobj, P_GetMobjWorld(camobj)->sectors + rover->secnum, camobj->subsector->sector))
continue;
foundit = true;
@ -3000,17 +3000,17 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
case 444: // Earthquake camera
{
quake.intensity = line->args[1] << FRACBITS;
quake.radius = line->args[2] << FRACBITS;
quake.time = line->args[0];
world->quake.intensity = line->args[1] << FRACBITS;
world->quake.radius = line->args[2] << FRACBITS;
world->quake.time = line->args[0];
quake.epicenter = NULL; /// \todo
world->quake.epicenter = NULL; /// \todo
// reasonable defaults.
if (!quake.intensity)
quake.intensity = 8<<FRACBITS;
if (!quake.radius)
quake.radius = 512<<FRACBITS;
if (!world->quake.intensity)
world->quake.intensity = 8<<FRACBITS;
if (!world->quake.radius)
world->quake.radius = 512<<FRACBITS;
break;
}
@ -3968,8 +3968,8 @@ boolean P_IsFlagAtBase(mobjtype_t flag)
if (!(rover->master->frontsector->specialflags & specialflag))
continue;
if (!(mo->z <= P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector)
&& mo->z >= P_GetSpecialBottomZ(mo, sectors + rover->secnum, mo->subsector->sector)))
if (!(mo->z <= P_GetSpecialTopZ(mo, P_GetMobjWorld(mo)->sectors + rover->secnum, mo->subsector->sector)
&& mo->z >= P_GetSpecialBottomZ(mo, P_GetMobjWorld(mo)->sectors + rover->secnum, mo->subsector->sector)))
continue;
return true;
@ -3993,8 +3993,8 @@ boolean P_IsMobjTouchingSectorPlane(mobj_t *mo, sector_t *sec)
boolean P_IsMobjTouching3DFloor(mobj_t *mo, ffloor_t *ffloor, sector_t *sec)
{
fixed_t topheight = P_GetSpecialTopZ(mo, sectors + ffloor->secnum, sec);
fixed_t bottomheight = P_GetSpecialBottomZ(mo, sectors + ffloor->secnum, sec);
fixed_t topheight = P_GetSpecialTopZ(mo, P_GetMobjWorld(mo)->sectors + ffloor->secnum, sec);
fixed_t bottomheight = P_GetSpecialBottomZ(mo, P_GetMobjWorld(mo)->sectors + ffloor->secnum, sec);
if (((ffloor->fofflags & FOF_BLOCKPLAYER) && mo->player)
|| ((ffloor->fofflags & FOF_BLOCKOTHERS) && !mo->player))
@ -5385,7 +5385,7 @@ void P_CheckMobjTrigger(mobj_t *mobj, boolean pushable)
*
* \sa P_CheckTimeLimit, P_CheckPointLimit
*/
void P_UpdateSpecials(void)
void P_UpdateSpecials(world_t *w)
{
anim_t *anim;
INT32 i;
@ -5415,8 +5415,8 @@ void P_UpdateSpecials(void)
/// \todo do not check the non-animate flat.. link the animated ones?
/// \note its faster than the original anywaysince it animates only
/// flats used in the level, and there's usually very few of them
foundflats = world->flats;
for (j = 0; j < world->numflats; j++, foundflats++)
foundflats = w->flats;
for (j = 0; j < w->numflats; j++, foundflats++)
{
if (foundflats->speed) // it is an animated flat
{
@ -6085,32 +6085,33 @@ static void P_RunLevelLoadExecutors(void)
void P_InitSpecials(void)
{
// Set the default gravity. Custom gravity overrides this setting.
world->gravity = gravity = mapheaderinfo[gamemap-1]->gravity;
world->gravity = worldmapheader->gravity;
// Defaults in case levels don't have them set.
sstimer = mapheaderinfo[gamemap-1]->sstimer*TICRATE + 6;
ssspheres = mapheaderinfo[gamemap-1]->ssspheres;
// Set globalweather
world->weather = worldmapheader->weather;
P_InitLocalSpecials();
}
void P_InitLocalSpecials(void)
{
if (numworlds < 2)
CheckForBustableBlocks = CheckForBouncySector = CheckForQuicksand = CheckForMarioBlocks = CheckForFloatBob = CheckForReverseGravity = false;
// Set curWeather
switch (mapheaderinfo[gamemap-1]->weather)
switch (worldmapheader->weather)
{
case PRECIP_SNOW: // snow
case PRECIP_RAIN: // rain
case PRECIP_STORM: // storm
case PRECIP_STORM_NORAIN: // storm w/o rain
case PRECIP_STORM_NOSTRIKES: // storm w/o lightning
curWeather = mapheaderinfo[gamemap-1]->weather;
curWeather = worldmapheader->weather;
break;
default: // blank/none
curWeather = PRECIP_NONE;
break;
}
// Set globalweather
world->weather = mapheaderinfo[gamemap-1]->weather;
}
void P_ApplyFlatAlignment(sector_t *sector, angle_t flatangle, fixed_t xoffs, fixed_t yoffs, boolean floor, boolean ceiling)
@ -6247,7 +6248,7 @@ void P_SpawnSpecials(boolean fromnetsave)
break;
case 11: // Custom global gravity!
world->gravity = gravity = sector->floorheight/1000;
world->gravity = sector->floorheight/1000;
break;
}
}

View file

@ -485,12 +485,13 @@ void P_SetupLevelFlatAnims(void);
// at map load
void P_InitSpecials(void);
void P_InitLocalSpecials(void);
void P_ApplyFlatAlignment(sector_t* sector, angle_t flatangle, fixed_t xoffs, fixed_t yoffs, boolean floor, boolean ceiling);
fixed_t P_GetSectorGravityFactor(sector_t *sec);
void P_SpawnSpecials(boolean fromnetsave);
// every tic
void P_UpdateSpecials(void);
void P_UpdateSpecials(world_t *w);
sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number);
sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo);
sector_t *P_MobjTouchingSectorSpecialFlag(mobj_t *mo, sectorspecialflags_t flag);

View file

@ -361,18 +361,9 @@ static inline void P_RunThinkers(void)
static inline void P_RunWorldThinkers(void)
{
INT32 i;
PS_START_TIMING(ps_thinkertime);
if (!(netgame || multiplayer) || (numworlds < 2))
{
P_RunThinkers();
PS_STOP_TIMING(ps_thinkertime);
return;
}
for (i = 0; i < numworlds; i++)
for (INT32 i = 0; i < numworlds; i++)
{
world_t *w = worldlist[i];
@ -519,7 +510,7 @@ static inline void P_DoSpecialStageStuff(void)
players[i].powers[pw_underwater] = players[i].powers[pw_spacetime] = 0;
}
//if (sstimer < 15*TICRATE+6 && sstimer > 7 && (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC))
//if (sstimer < 15*TICRATE+6 && sstimer > 7 && (worldmapheader->levelflags & LF_SPEEDMUSIC))
//S_SpeedMusic(1.4f);
if (sstimer && !objectplacing)
@ -637,65 +628,27 @@ static inline void P_DoCTFStuff(void)
static inline void P_RunWorldSpecials(void)
{
INT32 i;
if (!(netgame || multiplayer) || (numworlds < 2))
{
P_RunShields();
P_RunOverlays();
P_UpdateSpecials();
P_RespawnSpecials();
return;
}
for (i = 0; i < numworlds; i++)
for (INT32 i = 0; i < numworlds; i++)
{
world_t *w = worldlist[i];
if (!w->players)
continue;
// Just in case.
P_SetWorld(w);
P_RunShields();
P_RunOverlays();
P_UpdateSpecials();
P_RespawnSpecials();
P_RunShields(w);
P_RunOverlays(w);
P_UpdateSpecials(w);
P_RespawnSpecials(w);
P_PrecipitationEffects(w); // Lightning, rain sounds, etc.
}
}
static inline void P_WorldPrecipitationEffects(void)
static void RunLuaHook(int hook)
{
INT32 i;
if (!(netgame || multiplayer) || (numworlds < 2))
{
P_PrecipitationEffects(baseworld);
return;
}
for (i = 0; i < numworlds; i++)
{
world_t *w = worldlist[i];
if (!w->players)
continue;
P_PrecipitationEffects(w);
}
}
static inline void RunLuaHookForWorld(int hook)
{
INT32 i;
if (!(netgame || multiplayer) || (numworlds < 2))
{
LUA_HookVoid(hook);
return;
}
for (i = 0; i < numworlds; i++)
for (INT32 i = 0; i < numworlds; i++)
{
world_t *w = worldlist[i];
@ -708,17 +661,9 @@ static inline void RunLuaHookForWorld(int hook)
}
}
static inline void RunLuaThinkFrameForWorld(void)
static inline void RunLuaThinkFrame(void)
{
INT32 i;
if (!(netgame || multiplayer) || (numworlds < 2))
{
LUA_HookThinkFrame();
return;
}
for (i = 0; i < numworlds; i++)
for (INT32 i = 0; i < numworlds; i++)
{
world_t *w = worldlist[i];
@ -731,6 +676,21 @@ static inline void RunLuaThinkFrameForWorld(void)
}
}
static void P_WorldPostUpdate(world_t *w)
{
if (w->quake.time)
{
fixed_t ir = w->quake.intensity>>1;
/// \todo Calculate distance from epicenter if set and modulate the intensity accordingly based on radius.
w->quake.x = M_RandomRange(-ir,ir);
w->quake.y = M_RandomRange(-ir,ir);
w->quake.z = M_RandomRange(-ir,ir);
--w->quake.time;
}
else
w->quake.x = w->quake.y = w->quake.z = 0;
}
//
// P_Ticker
//
@ -738,6 +698,8 @@ void P_Ticker(boolean run)
{
INT32 i;
P_SetWorld(localworld);
// Increment jointime and quittime even if paused
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i])
@ -815,7 +777,7 @@ void P_Ticker(boolean run)
player_t *player = &players[i];
if (numworlds > 1 && !titlemapinaction && !player->bot)
P_SetWorld(player->world);
P_SetWorld(P_GetPlayerWorld(player));
P_PlayerThink(player);
}
@ -846,22 +808,19 @@ void P_Ticker(boolean run)
player_t *player = &players[i];
if (numworlds > 1 && !titlemapinaction && !player->bot)
P_SetWorld(player->world);
P_SetWorld(P_GetPlayerWorld(player));
P_PlayerAfterThink(player);
}
PS_START_TIMING(ps_lua_thinkframe_time);
RunLuaThinkFrameForWorld();
RunLuaThinkFrame();
PS_STOP_TIMING(ps_lua_thinkframe_time);
}
// Run shield positioning
P_RunWorldSpecials();
// Lightning, rain sounds, etc.
P_WorldPrecipitationEffects();
if (run)
leveltime++;
timeinmap++;
@ -898,17 +857,16 @@ void P_Ticker(boolean run)
if (countdown2)
countdown2--;
if (quake.time)
for (i = 0; i < numworlds; i++)
{
fixed_t ir = quake.intensity>>1;
/// \todo Calculate distance from epicenter if set and modulate the intensity accordingly based on radius.
quake.x = M_RandomRange(-ir,ir);
quake.y = M_RandomRange(-ir,ir);
quake.z = M_RandomRange(-ir,ir);
--quake.time;
world_t *w = worldlist[i];
if (!w->players)
continue;
P_SetWorld(w);
P_WorldPostUpdate(w);
}
else
quake.x = quake.y = quake.z = 0;
if (metalplayback)
G_ReadMetalTic(metalplayback);
@ -921,7 +879,7 @@ void P_Ticker(boolean run)
if (modeattacking)
G_GhostTicker();
RunLuaHookForWorld(HOOK(PostThinkFrame));
RunLuaHook(HOOK(PostThinkFrame));
}
if (run)
@ -962,6 +920,8 @@ void P_Ticker(boolean run)
}
P_MapEnd();
P_SetWorld(localworld);
}
// Abbreviated ticker for pre-loading, calls thinkers and assorted things
@ -981,7 +941,7 @@ void P_PreTicker(INT32 frames)
R_UpdateAllMobjInterpolators();
RunLuaHookForWorld(HOOK(PreThinkFrame));
RunLuaHook(HOOK(PreThinkFrame));
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo))
@ -999,7 +959,7 @@ void P_PreTicker(INT32 frames)
players[i].cmd.angleturn = players[i].angleturn;
if (numworlds > 1 && !titlemapinaction && !player->bot)
P_SetWorld(player->world);
P_SetWorld(P_GetPlayerWorld(player));
P_PlayerThink(player);
memcpy(&players[i].cmd, &temptic, sizeof(ticcmd_t));
@ -1014,17 +974,17 @@ void P_PreTicker(INT32 frames)
player_t *player = &players[i];
if (numworlds > 1 && !titlemapinaction && !player->bot)
P_SetWorld(player->world);
P_SetWorld(P_GetPlayerWorld(player));
P_PlayerAfterThink(&players[i]);
}
RunLuaThinkFrameForWorld();
RunLuaThinkFrame();
// Run shield positioning
P_RunWorldSpecials();
RunLuaHookForWorld(HOOK(PostThinkFrame));
RunLuaHook(HOOK(PostThinkFrame));
R_UpdateLevelInterpolators();
R_UpdateViewInterpolation();

View file

@ -419,7 +419,7 @@ void P_ResetScore(player_t *player)
//
// Returns the lowest open mare available
//
UINT8 P_FindLowestMare(void)
UINT8 P_FindLowestMare(world_t *w)
{
thinker_t *th;
mobj_t *mo2;
@ -430,7 +430,7 @@ UINT8 P_FindLowestMare(void)
// scan the thinkers
// to find the egg capsule with the lowest mare
for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next)
for (th = w->thlist[THINK_MOBJ].next; th != &w->thlist[THINK_MOBJ]; th = th->next)
{
if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed)
continue;
@ -469,7 +469,7 @@ boolean P_TransferToNextMare(player_t *player)
mobj_t *mo2;
mobj_t *closestaxis = NULL;
INT32 lowestaxisnum = -1;
UINT8 mare = P_FindLowestMare();
UINT8 mare = P_FindLowestMare(P_GetPlayerWorld(player));
fixed_t dist1, dist2 = 0;
if (mare == 255)
@ -726,7 +726,7 @@ static void P_DeNightserizePlayer(player_t *player)
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL);
// Reset music to beginning if MIXNIGHTSCOUNTDOWN
if ((mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN)
if ((worldmapheader->levelflags & LF_MIXNIGHTSCOUNTDOWN)
#ifdef _WIN32
&& S_MusicType() != MU_MID
#endif
@ -742,7 +742,7 @@ static void P_DeNightserizePlayer(player_t *player)
player->oldscale = 0;
// Restore from drowning music
if ((mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN)
if ((worldmapheader->levelflags & LF_MIXNIGHTSCOUNTDOWN)
#ifdef _WIN32
&& S_MusicType() != MU_MID
#endif
@ -755,7 +755,7 @@ static void P_DeNightserizePlayer(player_t *player)
// Reset the music if you did not destroy all the capsules, because you failed.
// Why make the all-capsules exception: because it's your reward for nearly finishing the level!
// (unless the player auto-loses upon denightserizing; for death case, see above.)
if (P_FindLowestMare() != UINT8_MAX || G_IsSpecialStage(gamemap))
if (P_FindLowestMare(P_GetPlayerWorld(player)) != UINT8_MAX || G_IsSpecialStage(gamemap))
S_SetMusicPosition(0);
}
else
@ -813,7 +813,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
player->bonustime = false;
// Restore from drowning music
if (mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN)
if (worldmapheader->levelflags & LF_MIXNIGHTSCOUNTDOWN)
{
S_StopSoundByNum(sfx_timeup);
S_StopFadingMusic();
@ -1331,7 +1331,7 @@ void P_GiveCoopLives(player_t *player, INT32 numlives, boolean sound)
void P_DoSuperTransformation(player_t *player, boolean giverings)
{
player->powers[pw_super] = 1;
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC) && P_IsLocalPlayer(player))
if (!(worldmapheader->levelflags & LF_NOSSMUSIC) && P_IsLocalPlayer(player))
P_PlayJingle(player, JT_SUPER);
S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi
@ -1345,7 +1345,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
player->rings = 50;
// Just in case.
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC))
if (!(worldmapheader->levelflags & LF_NOSSMUSIC))
{
player->powers[pw_extralife] = 0;
player->powers[pw_invulnerability] = 0;
@ -1371,7 +1371,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount)
player = player->botleader;
// NiGHTS does it different!
if (gamestate == GS_LEVEL && mapheaderinfo[gamemap-1]->typeoflevel & TOL_NIGHTS)
if (gamestate == GS_LEVEL && worldmapheader->typeoflevel & TOL_NIGHTS)
{
if ((netgame || multiplayer) && G_IsSpecialStage(gamemap))
{ // Pseudo-shared score for multiplayer special stages.
@ -1581,7 +1581,7 @@ boolean P_EvaluateMusicStatus(UINT16 status, const char *musname)
break;
case JT_SUPER: // Super Sonic
result = (players[i].powers[pw_super] && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC));
result = (players[i].powers[pw_super] && !(worldmapheader->levelflags & LF_NOSSMUSIC));
break;
case JT_GOVER: // Game Over
@ -1630,7 +1630,7 @@ void P_RestoreMusic(player_t *player)
return;
// Super
else if (player->powers[pw_super] && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC)
else if (player->powers[pw_super] && !(worldmapheader->levelflags & LF_NOSSMUSIC)
&& !S_RecallMusic(JT_SUPER, false))
P_PlayJingle(player, JT_SUPER);
@ -1648,7 +1648,7 @@ void P_RestoreMusic(player_t *player)
{
strlcpy(S_sfx[sfx_None].caption, "Speed shoes", 12);
S_StartCaption(sfx_None, -1, player->powers[pw_sneakers]);
if (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC)
if (worldmapheader->levelflags & LF_SPEEDMUSIC)
{
S_SpeedMusic(1.4f);
if (!S_RecallMusic(JT_MASTER, true))
@ -3017,7 +3017,7 @@ static void P_CheckInvincibilityTimer(player_t *player)
P_SpawnShieldOrb(player);
}
if (!player->powers[pw_super] || (mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC))
if (!player->powers[pw_super] || (worldmapheader->levelflags & LF_NOSSMUSIC))
P_RestoreMusic(player);
}
}
@ -5579,7 +5579,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
{
fixed_t potentialmomz;
if (player->charability == CA_SLOWFALL)
potentialmomz = FixedMul(gravity, -4*player->mo->scale);
potentialmomz = FixedMul(world->gravity, -4*player->mo->scale);
else
potentialmomz = ((player->speed < 10*player->mo->scale)
? (player->speed - 10*player->mo->scale)/5
@ -7098,7 +7098,7 @@ static void P_NiGHTSMovement(player_t *player)
}
else if (P_IsLocalPlayer(player) && player->nightstime == 10*TICRATE)
{
if (mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN)
if (worldmapheader->levelflags & LF_MIXNIGHTSCOUNTDOWN)
{
S_FadeMusic(0, 10*MUSICRATE);
S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS.
@ -9044,10 +9044,10 @@ void P_Earthquake(mobj_t *inflictor, mobj_t *source, fixed_t radius)
if (inflictor->player && P_IsLocalPlayer(inflictor->player))
{
quake.epicenter = NULL;
quake.intensity = 8*inflictor->scale;
quake.time = 8;
quake.radius = scaledradius;
world->quake.epicenter = NULL;
world->quake.intensity = 8*inflictor->scale;
world->quake.time = 8;
world->quake.radius = scaledradius;
}
P_RadiusAttack(inflictor, source, radius, 0, false);
@ -9326,12 +9326,13 @@ boolean P_HomingAttack(mobj_t *source, mobj_t *enemy) // Home in on your target
}
// Search for emeralds
void P_FindEmerald(void)
void P_FindEmerald(world_t *w)
{
thinker_t *th;
mobj_t *mo2;
hunt1 = hunt2 = hunt3 = NULL;
for (unsigned i = 0; i < NUM_EMERALD_HUNT_LOCATIONS; i++)
w->emerald_hunt_locations[i] = NULL;
// scan the remaining thinkers
// to find all emeralds
@ -9343,12 +9344,11 @@ void P_FindEmerald(void)
mo2 = (mobj_t *)th;
if (mo2->type == MT_EMERHUNT)
{
if (!hunt1)
hunt1 = mo2;
else if (!hunt2)
hunt2 = mo2;
else if (!hunt3)
hunt3 = mo2;
for (unsigned i = 0; i < NUM_EMERALD_HUNT_LOCATIONS; i++)
{
if (w->emerald_hunt_locations[i] == NULL)
P_SetTarget(&w->emerald_hunt_locations[i], mo2);
}
}
}
return;
@ -9476,7 +9476,7 @@ static void P_PlayerSetRaceRealTime(player_t *player)
for (i = 0; i < numworlds; i++)
{
if (player->world == worldlist[i])
if (P_GetPlayerWorld(player) == worldlist[i])
break;
}
@ -11043,7 +11043,7 @@ static void P_MinecartThink(player_t *player)
minecart->eflags &= ~MFE_ONGROUND;
minecart->z += P_MobjFlip(minecart);
if (sidelock)
P_ParabolicMove(minecart, sidelock->x, sidelock->y, sidelock->z, gravity, max(currentSpeed, 10 * FRACUNIT));
P_ParabolicMove(minecart, sidelock->x, sidelock->y, sidelock->z, world->gravity, max(currentSpeed, 10 * FRACUNIT));
else
minecart->momz = 10 * FRACUNIT;
@ -11618,7 +11618,7 @@ void P_PlayerThink(player_t *player)
// so we can fade music
if (!exitfadestarted &&
player->exiting > 0 && player->exiting <= 1*TICRATE &&
(!multiplayer || G_CoopGametype() ? !mapheaderinfo[gamemap-1]->musinterfadeout : true) &&
(!multiplayer || G_CoopGametype() ? !worldmapheader->musinterfadeout : true) &&
// don't fade if we're fading during intermission. follows Y_StartIntermission intertype = int_coop
((gametyperules & GTR_RACE) ? countdown2 == 0 : true) && // don't fade on timeout
player->lives > 0 && // don't fade on game over (competition)

View file

@ -59,6 +59,9 @@ world_t *P_InitWorld(void)
{
world_t *w = Z_Calloc(sizeof(world_t), PU_STATIC, NULL);
w->gamemap = gamemap;
if (!mapheaderinfo[w->gamemap-1])
P_AllocMapHeader(w->gamemap-1);
w->header = mapheaderinfo[w->gamemap-1];
w->thlist = Z_Calloc(sizeof(thinker_t) * NUM_THINKERLISTS, PU_STATIC, NULL);
return w;
}
@ -144,9 +147,18 @@ void P_SetWorld(world_t *w)
P_SetGameWorld(w);
worldmapheader = w->header;
thlist = w->thlist;
gamemap = w->gamemap;
gravity = w->gravity;
}
//
// Gets a player's current world.
//
world_t *P_GetPlayerWorld(player_t *player)
{
return (world_t *)player->world;
}
//
@ -154,8 +166,8 @@ void P_SetWorld(world_t *w)
//
void P_DetachPlayerWorld(player_t *player)
{
if (player->world != NULL)
((world_t *)player->world)->players--;
if (P_GetPlayerWorld(player) != NULL)
P_GetPlayerWorld(player)->players--;
player->world = NULL;
if (player->mo && !P_MobjWasRemoved(player->mo))
@ -199,7 +211,7 @@ void P_RoamIntoWorld(player_t *player, INT32 mapnum)
}
}
if (w == player->world)
if (w == P_GetPlayerWorld(player))
return;
else if (w)
P_SwitchWorld(player, w);
@ -263,8 +275,8 @@ void P_SwitchWorld(player_t *player, world_t *w)
if (!playeringame[playernum] || !player->mo || P_MobjWasRemoved(player->mo))
return;
if (player->world)
P_RemoveMobjConnections(player->mo, player->world);
if (P_GetPlayerWorld(player))
P_RemoveMobjConnections(player->mo, P_GetPlayerWorld(player));
if (player->followmobj)
{
@ -275,19 +287,18 @@ void P_SwitchWorld(player_t *player, world_t *w)
P_SwitchPlayerWorld(player, w);
P_SetWorld(w);
if (local || splitscreen)
P_InitSpecials();
P_InitLocalSpecials();
P_UnsetThingPosition(player->mo);
P_MoveThinkerToWorld(w, THINK_MOBJ, (thinker_t *)(player->mo));
G_MovePlayerToSpawnOrStarpost(playernum);
if (local && !splitscreen)
{
localworld = world;
S_Start();
P_SetupSkyTexture(w->skynum);
}
P_SetupSkyTexture(w->skynum);
if (player == &players[displayplayer])
P_ResetCamera(player, (splitscreen && playernum == 1) ? &camera2 : &camera);
@ -303,6 +314,13 @@ void P_SwitchWorld(player_t *player, world_t *w)
if (rendermode == render_opengl)
HWR_LoadLevel();
#endif
if (local || splitscreen)
{
S_SetMapMusic(worldmapheader);
S_StopMusic();
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
}
}
void Command_Switchworld_f(void)
@ -328,18 +346,12 @@ void Command_Switchworld_f(void)
void Command_Listworlds_f(void)
{
INT32 worldnum;
world_t *w;
for (worldnum = 0; worldnum < numworlds; worldnum++)
for (INT32 i = 0; i < numworlds; i++)
{
w = worldlist[worldnum];
CONS_Printf("World %d (%p)\n", worldnum, w);
CONS_Printf("Gamemap: %d\n", w->gamemap);
CONS_Printf("vt %d sg %d sc %d ss %d nd %d ld %d sd %d mt %d\n",
w->numvertexes, w->numsegs, w->numsectors, w->numsubsectors, w->numnodes, w->numlines, w->numsides, w->nummapthings);
CONS_Printf("Player count: %d\n", w->players);
world_t *w = worldlist[i];
CONS_Printf("World %d\n", i);
CONS_Printf(" Gamemap: %d\n", w->gamemap);
CONS_Printf(" Player count: %d\n", w->players);
}
}
@ -466,7 +478,7 @@ void P_UnloadWorldPlayer(player_t *player)
boolean P_MobjIsConnected(mobj_t *mobj1, mobj_t *mobj2)
{
return (mobj2 && !P_MobjWasRemoved(mobj2) && mobj1->world == mobj2->world);
return mobj2 && !P_MobjWasRemoved(mobj2) && P_GetMobjWorld(mobj1) == P_GetMobjWorld(mobj2);
}
void P_RemoveMobjConnections(mobj_t *mobj, world_t *w)
@ -491,3 +503,8 @@ void P_RemoveMobjConnections(mobj_t *mobj, world_t *w)
P_SetTarget(&mobj->hprev, NULL);
}
}
world_t *P_GetMobjWorld(mobj_t *mobj)
{
return (world_t *)mobj->world;
}

View file

@ -65,6 +65,8 @@ typedef struct
mobj_t *overlaycap;
mapheader_t *header;
fixed_t gravity;
INT32 skynum; // used for keeping track of the current sky
@ -97,6 +99,12 @@ typedef struct
tic_t itemrespawntime[ITEMQUESIZE];
size_t iquehead, iquetail;
struct quake quake;
// Emerald locations
mobj_t *emerald_hunt_locations[NUM_EMERALD_HUNT_LOCATIONS];
// All that boring blockmap stuff
UINT8 *rejectmatrix; // for fast sight rejection
INT32 *blockmaplump; // offsets in blockmap are from here
INT32 *blockmap; // Big blockmap
@ -160,12 +168,15 @@ void P_SetWorld(world_t *w);
void P_RoamIntoWorld(player_t *player, INT32 mapnum);
void P_SwitchWorld(player_t *player, world_t *w);
world_t *P_GetPlayerWorld(player_t *player);
void P_DetachPlayerWorld(player_t *player);
void P_SwitchPlayerWorld(player_t *player, world_t *newworld);
boolean P_TransferCarriedPlayers(player_t *player, world_t *w);
boolean P_MobjIsConnected(mobj_t *mobj1, mobj_t *mobj2);
void P_RemoveMobjConnections(mobj_t *mobj, world_t *w);
world_t *P_GetMobjWorld(mobj_t *mobj);
void Command_Switchworld_f(void);
void Command_Listworlds_f(void);

View file

@ -244,9 +244,6 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
*ceilinglightlevel = sec->ceilinglightsec == -1 ?
(sec->ceilinglightabsolute ? sec->ceilinglightlevel : max(0, min(255, sec->lightlevel + sec->ceilinglightlevel))) : viewworld->sectors[sec->ceilinglightsec].lightlevel;
// if (sec->midmap != -1)
// mapnum = sec->midmap;
// In original colormap code, this block did not run if sec->midmap was set
if (!sec->extra_colormap && sec->heightsec != -1)
{
const sector_t *s = &viewworld->sectors[sec->heightsec];
@ -1073,18 +1070,18 @@ static void R_Subsector(size_t num)
}
}
// killough 9/18/98: Fix underwater slowdown, by passing real sector
// instead of fake one. Improve sprite lighting by basing sprite
// lightlevels on floor & ceiling lightlevels in the surrounding area.
//
// 10/98 killough:
//
// NOTE: TeamTNT fixed this bug incorrectly, messing up sprite lighting!!!
// That is part of the 242 effect!!! If you simply pass sub->sector to
// the old code you will not get correct lighting for underwater sprites!!!
// Either you must pass the fake sector and handle validcount here, on the
// real sector, or you must account for the lighting in some other way,
// like passing it as an argument.
// killough 9/18/98: Fix underwater slowdown, by passing real sector
// instead of fake one. Improve sprite lighting by basing sprite
// lightlevels on floor & ceiling lightlevels in the surrounding area.
//
// 10/98 killough:
//
// NOTE: TeamTNT fixed this bug incorrectly, messing up sprite lighting!!!
// That is part of the 242 effect!!! If you simply pass sub->sector to
// the old code you will not get correct lighting for underwater sprites!!!
// Either you must pass the fake sector and handle validcount here, on the
// real sector, or you must account for the lighting in some other way,
// like passing it as an argument.
R_AddSprites(sub->sector, (floorlightlevel+ceilinglightlevel)/2);
firstseg = NULL;

View file

@ -696,7 +696,7 @@ void R_DestroyLevelInterpolators(void *wptr, thinker_t *thinker)
// reasons.
void R_AddMobjInterpolator(mobj_t *mobj)
{
world_t *w = (world_t *)mobj->world;
world_t *w = P_GetMobjWorld(mobj);
if (!w)
return;
@ -729,7 +729,7 @@ void R_AddMobjInterpolator(mobj_t *mobj)
void R_RemoveMobjInterpolator(mobj_t *mobj)
{
world_t *w = (world_t *)mobj->world;
world_t *w = P_GetMobjWorld(mobj);
if (!w)
return;

View file

@ -1187,7 +1187,7 @@ void R_SetupFrame(player_t *player)
}
}
}
newview->z += quake.z;
newview->z += viewworld->quake.z;
newview->player = player;
@ -1195,8 +1195,8 @@ void R_SetupFrame(player_t *player)
{
newview->x = thiscam->x;
newview->y = thiscam->y;
newview->x += quake.x;
newview->y += quake.y;
newview->x += viewworld->quake.x;
newview->y += viewworld->quake.y;
if (thiscam->subsector)
newview->sector = thiscam->subsector->sector;
@ -1207,8 +1207,8 @@ void R_SetupFrame(player_t *player)
{
newview->x = r_viewmobj->x;
newview->y = r_viewmobj->y;
newview->x += quake.x;
newview->y += quake.y;
newview->x += viewworld->quake.x;
newview->y += viewworld->quake.y;
if (r_viewmobj->subsector)
newview->sector = r_viewmobj->subsector->sector;
@ -1286,9 +1286,9 @@ void R_SkyboxFrame(player_t *player)
newview->y = r_viewmobj->y;
newview->z = r_viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle!
if (mapheaderinfo[gamemap-1])
if (viewworld->header)
{
mapheader_t *mh = mapheaderinfo[gamemap-1];
mapheader_t *mh = viewworld->header;
vector3_t campos = {0,0,0}; // Position of player's actual view point
if (player->awayviewtics) {
@ -1307,9 +1307,9 @@ void R_SkyboxFrame(player_t *player)
// Earthquake effects should be scaled in the skybox
// (if an axis isn't used, the skybox won't shake in that direction)
campos.x += quake.x;
campos.y += quake.y;
campos.z += quake.z;
campos.x += viewworld->quake.x;
campos.y += viewworld->quake.y;
campos.z += viewworld->quake.z;
if (viewworld->skyboxmo[1]) // Is there a viewpoint?
{
@ -1509,9 +1509,9 @@ void R_PrepareViewWorld(player_t *player)
R_SetViewMobj(player);
if (r_viewmobj)
P_SetViewWorld(r_viewmobj->world);
else if (player->world)
P_SetViewWorld(player->world);
P_SetViewWorld(P_GetMobjWorld(r_viewmobj));
else if (P_GetPlayerWorld(player))
P_SetViewWorld(P_GetPlayerWorld(player));
else if (localworld && !splitscreen) // Yes?
P_SetViewWorld(localworld);
else

View file

@ -275,7 +275,7 @@ void Portal_AddSkybox (const visplane_t* plane)
portal->viewz = viewworld->skyboxmo[0]->z;
portal->viewangle = viewangle + viewworld->skyboxmo[0]->angle;
mh = mapheaderinfo[gamemap-1];
mh = viewworld->header;
// If a relative viewpoint exists, offset the viewpoint.
if (viewworld->skyboxmo[1])

View file

@ -225,7 +225,7 @@ boolean R_SkinUsable(INT32 playernum, INT32 skinnum)
return true;
}
if (Playing() && mapheaderinfo[gamemap-1] && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum))
if (Playing() && worldmapheader && (R_SkinAvailable(worldmapheader->forcecharacter) == skinnum))
{
// Force 1.
return true;

View file

@ -2380,9 +2380,6 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
INT32 lightnum;
fixed_t limit_dist, hoop_limit_dist;
if (rendermode != render_soft)
return;
// BSP is traversed by subsector.
// A sector might have been split into several
// subsectors during BSP building.

View file

@ -1783,6 +1783,20 @@ boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi)
);
}
INT32 S_ShouldResetMusic(mapheader_t *mapheader)
{
if (modeattacking)
return 0;
if (cv_resetmusicbyheader.value)
{
if (mapheader->musforcereset != -1)
return mapheader->musforcereset;
}
return cv_resetmusic.value;
}
/// ------------------------
/// Music Effects
/// ------------------------
@ -2424,25 +2438,32 @@ boolean S_FadeOutStopMusic(UINT32 ms)
/// Init & Others
/// ------------------------
void S_SetMapMusic(mapheader_t *mapheader)
{
strncpy(mapmusname, mapheader->musname, 7);
mapmusname[6] = 0;
mapmusflags = (mapheader->mustrack & MUSIC_TRACKMASK);
mapmusposition = mapheader->muspos;
}
void S_PlayMapMusic(mapheader_t *mapheader, boolean reset)
{
if (mapmusflags & MUSIC_RELOADRESET)
S_SetMapMusic(mapheader);
if (S_ShouldResetMusic(mapheader) || reset)
S_StopMusic();
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
}
//
// Per level startup code.
// Kills playing sounds at start of level,
// determines music if any, changes music.
//
void S_StartEx(boolean reset)
void S_StartEx(mapheader_t *mapheader, boolean reset)
{
if (mapmusflags & MUSIC_RELOADRESET)
{
strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
mapmusname[6] = 0;
mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK);
mapmusposition = mapheaderinfo[gamemap-1]->muspos;
}
if (RESETMUSIC || reset)
S_StopMusic();
S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0);
S_PlayMapMusic(mapheader, reset);
S_ResetMusicStack();
music_stack_noposition = false;
music_stack_fadeout = 0;
@ -2483,8 +2504,8 @@ static void Command_Tunes_f(void)
}
else if (!strcasecmp(tunearg, "-default"))
{
tunearg = mapheaderinfo[gamemap-1]->musname;
track = mapheaderinfo[gamemap-1]->mustrack;
tunearg = worldmapheader->musname;
track = worldmapheader->mustrack;
}
if (strlen(tunearg) > 6) // This is automatic -- just show the error just in case

View file

@ -18,6 +18,7 @@
#include "sounds.h"
#include "m_fixed.h"
#include "command.h"
#include "doomstat.h"
#include "tables.h" // angle_t
#ifdef HAVE_OPENMPT
@ -37,11 +38,7 @@ extern consvar_t cv_resetmusicbyheader;
extern consvar_t cv_1upsound;
#define RESETMUSIC (!modeattacking && \
(cv_resetmusicbyheader.value ? \
(mapheaderinfo[gamemap-1]->musforcereset != -1 ? mapheaderinfo[gamemap-1]->musforcereset : cv_resetmusic.value) \
: cv_resetmusic.value) \
)
INT32 S_ShouldResetMusic(mapheader_t *mapheader);
extern consvar_t cv_gamedigimusic;
extern consvar_t cv_gamemidimusic;
@ -125,8 +122,10 @@ void S_InitSfxChannels(INT32 sfxVolume);
//
void S_StopSounds(void);
void S_ClearSfx(void);
void S_StartEx(boolean reset);
#define S_Start() S_StartEx(false)
void S_SetMapMusic(mapheader_t *mapheader);
void S_PlayMapMusic(mapheader_t *mapheader, boolean reset);
void S_StartEx(mapheader_t *mapheader, boolean reset);
#define S_Start(mapheader) S_StartEx(mapheader, false)
//
// Basically a W_GetNumForName that adds "ds" at the beginning of the string. Returns a lumpnum.

View file

@ -150,7 +150,7 @@ static void Midiplayer_Onchange(void)
Mix_Timidity_addToPathList(cv_miditimiditypath.string);
if (restart)
S_StartEx(true);
S_StartEx(worldmapheader, true);
}
static void MidiSoundfontPath_Onchange(void)
@ -188,7 +188,7 @@ static void MidiSoundfontPath_Onchange(void)
if (!Mix_SetSoundFonts(cv_midisoundfontpath.string))
CONS_Alert(CONS_ERROR, "Sound font error: %s", Mix_GetError());
else
S_StartEx(true);
S_StartEx(worldmapheader, true);
}
}
}

View file

@ -739,7 +739,7 @@ static void ST_drawTime(void)
// right now before the island blows up with you on it!"
// "Blows up??" *awkward silence* "I've got to get outta
// here and find Amy and Tails right away!"
else if (mapheaderinfo[gamemap-1]->countdown)
else if (worldmapheader->countdown)
{
tics = countdowntimer;
downwards = true;
@ -1232,15 +1232,15 @@ static void ST_cacheLevelTitle(void)
#define SETPATCH(default, warning, custom, idx) \
{ \
lumpnum_t patlumpnum = LUMPERROR; \
if (mapheaderinfo[gamemap-1]->custom[0] != '\0') \
if (worldmapheader->custom[0] != '\0') \
{ \
patlumpnum = W_CheckNumForName(mapheaderinfo[gamemap-1]->custom); \
patlumpnum = W_CheckNumForName(worldmapheader->custom); \
if (patlumpnum != LUMPERROR) \
lt_patches[idx] = (patch_t *)W_CachePatchNum(patlumpnum, PU_HUDGFX); \
} \
if (patlumpnum == LUMPERROR) \
{ \
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_WARNINGTITLE)) \
if (!(worldmapheader->levelflags & LF_WARNINGTITLE)) \
lt_patches[idx] = (patch_t *)W_CachePatchName(default, PU_HUDGFX); \
else \
lt_patches[idx] = (patch_t *)W_CachePatchName(warning, PU_HUDGFX); \
@ -1343,9 +1343,9 @@ void ST_runTitleCard(void)
//
void ST_drawTitleCard(void)
{
char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl;
char *subttl = mapheaderinfo[gamemap-1]->subttl;
UINT8 actnum = mapheaderinfo[gamemap-1]->actnum;
char *lvlttl = worldmapheader->lvlttl;
char *subttl = worldmapheader->subttl;
UINT8 actnum = worldmapheader->actnum;
INT32 lvlttlxpos, ttlnumxpos, zonexpos;
INT32 subttlxpos = BASEVIDWIDTH/2;
INT32 ttlscroll = FixedInt(lt_scroll);
@ -1412,7 +1412,7 @@ void ST_drawTitleCard(void)
}
V_DrawLevelTitle(lvlttlxpos - ttlscroll, 80, V_PERPLAYER, lvlttl);
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
if (!(worldmapheader->levelflags & LF_NOZONE))
V_DrawLevelTitle(zonexpos + ttlscroll, 104, V_PERPLAYER, M_GetText("Zone"));
V_DrawCenteredString(subttlxpos - ttlscroll, 135, V_PERPLAYER|V_ALLOWLOWERCASE, subttl);
@ -2558,20 +2558,21 @@ static INT32 ST_drawEmeraldHuntIcon(mobj_t *hunt, patch_t **patches, INT32 offse
static void ST_doHuntIconsAndSound(void)
{
INT32 interval = 0, newinterval = 0;
mobj_t **hunt = world->emerald_hunt_locations;
if (hunt1 && hunt1->health)
interval = ST_drawEmeraldHuntIcon(hunt1, hunthoming, -20);
if (hunt[0] && hunt[0]->health)
interval = ST_drawEmeraldHuntIcon(hunt[0], hunthoming, -20);
if (hunt2 && hunt2->health)
if (hunt[1] && hunt[1]->health)
{
newinterval = ST_drawEmeraldHuntIcon(hunt2, hunthoming, 0);
newinterval = ST_drawEmeraldHuntIcon(hunt[1], hunthoming, 0);
if (newinterval && (!interval || newinterval < interval))
interval = newinterval;
}
if (hunt3 && hunt3->health)
if (hunt[2] && hunt[2]->health)
{
newinterval = ST_drawEmeraldHuntIcon(hunt3, hunthoming, 20);
newinterval = ST_drawEmeraldHuntIcon(hunt[2], hunthoming, 20);
if (newinterval && (!interval || newinterval < interval))
interval = newinterval;
}
@ -2671,7 +2672,7 @@ static void ST_overlayDrawer(void)
// Check for a valid level title
// If the HUD is enabled
// And, if Lua is running, if the HUD library has the stage title enabled
if (G_IsTitleCardAvailable() && *mapheaderinfo[gamemap-1]->lvlttl != '\0' && !(hu_showscores && (netgame || multiplayer)))
if (G_IsTitleCardAvailable() && *worldmapheader->lvlttl != '\0' && !(hu_showscores && (netgame || multiplayer)))
{
stagetitle = true;
ST_preDrawTitleCard();

View file

@ -399,7 +399,7 @@ const char *R_GetPalname(UINT16 num)
const char *GetPalette(void)
{
if (gamestate == GS_LEVEL)
return R_GetPalname(mapheaderinfo[gamemap-1]->palette);
return R_GetPalname(worldmapheader->palette);
return "PLAYPAL";
}

View file

@ -248,8 +248,8 @@ void Y_LoadIntermissionData(void)
// grab an interscreen if appropriate
if (mapheaderinfo[gamemap-1]->interscreen[0] != '#')
interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH);
if (worldmapheader->interscreen[0] != '#')
interpic = W_CachePatchName(worldmapheader->interscreen, PU_PATCH);
else // no interscreen? use default background
bgpatch = W_CachePatchName("INTERSCR", PU_PATCH);
break;
@ -263,8 +263,8 @@ void Y_LoadIntermissionData(void)
data.spec.pcontinues = W_CachePatchName("YB_CONTI", PU_PATCH);
// grab an interscreen if appropriate
if (mapheaderinfo[gamemap-1]->interscreen[0] != '#')
interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH);
if (worldmapheader->interscreen[0] != '#')
interpic = W_CachePatchName(worldmapheader->interscreen, PU_PATCH);
else // no interscreen? use default background
bgtile = W_CachePatchName("SPECTILE", PU_PATCH);
break;
@ -1043,15 +1043,15 @@ void Y_Ticker(void)
if (!intertic) // first time only
{
if (mapheaderinfo[gamemap-1]->musinterfadeout
if (worldmapheader->musinterfadeout
#ifdef _WIN32
// can't fade midi due to win32 volume hack
&& S_MusicType() != MU_MID
#endif
)
S_FadeOutStopMusic(mapheaderinfo[gamemap-1]->musinterfadeout);
else if (mapheaderinfo[gamemap-1]->musintername[0] && S_MusicExists(mapheaderinfo[gamemap-1]->musintername, !midi_disabled, !digital_disabled))
S_ChangeMusicInternal(mapheaderinfo[gamemap-1]->musintername, false); // don't loop it
S_FadeOutStopMusic(worldmapheader->musinterfadeout);
else if (worldmapheader->musintername[0] && S_MusicExists(worldmapheader->musintername, !midi_disabled, !digital_disabled))
S_ChangeMusicInternal(worldmapheader->musintername, false); // don't loop it
else
S_ChangeMusicInternal("_clear", false); // don't loop it
tallydonetic = -1;
@ -1120,15 +1120,15 @@ void Y_Ticker(void)
if (!intertic) // first time only
{
if (mapheaderinfo[gamemap-1]->musinterfadeout
if (worldmapheader->musinterfadeout
#ifdef _WIN32
// can't fade midi due to win32 volume hack
&& S_MusicType() != MU_MID
#endif
)
S_FadeOutStopMusic(mapheaderinfo[gamemap-1]->musinterfadeout);
else if (mapheaderinfo[gamemap-1]->musintername[0] && S_MusicExists(mapheaderinfo[gamemap-1]->musintername, !midi_disabled, !digital_disabled))
S_ChangeMusicInternal(mapheaderinfo[gamemap-1]->musintername, false); // don't loop it
S_FadeOutStopMusic(worldmapheader->musinterfadeout);
else if (worldmapheader->musintername[0] && S_MusicExists(worldmapheader->musintername, !midi_disabled, !digital_disabled))
S_ChangeMusicInternal(worldmapheader->musintername, false); // don't loop it
else
S_ChangeMusicInternal("_clear", false); // don't loop it
tallydonetic = -1;
@ -1348,10 +1348,10 @@ void Y_StartIntermission(void)
data.coop.tics = players[consoleplayer].realtime;
// get act number
data.coop.actnum = mapheaderinfo[gamemap-1]->actnum;
data.coop.actnum = worldmapheader->actnum;
// grab an interscreen if appropriate
if (mapheaderinfo[gamemap-1]->interscreen[0] != '#')
if (worldmapheader->interscreen[0] != '#')
{
useinterpic = true;
usebuffer = false;
@ -1369,9 +1369,9 @@ void Y_StartIntermission(void)
// set up the "got through act" message according to skin name
if (stagefailed)
{
strcpy(data.coop.passed1, mapheaderinfo[gamemap-1]->lvlttl);
strcpy(data.coop.passed1, worldmapheader->lvlttl);
if (mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)
if (worldmapheader->levelflags & LF_NOZONE)
{
data.spec.passed2[0] = '\0';
}
@ -1386,25 +1386,25 @@ void Y_StartIntermission(void)
if (strlen(skins[players[consoleplayer].skin].realname) > 13)
{
strcpy(data.coop.passed1, "you got");
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "through act" : "through the act");
strcpy(data.coop.passed2, (worldmapheader->actnum) ? "through act" : "through the act");
}
// long enough that "X GOT" won't fit so use "X PASSED THE ACT"
else if (strlen(skins[players[consoleplayer].skin].realname) > 8)
{
strcpy(data.coop.passed1, skins[players[consoleplayer].skin].realname);
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "passed act" : "passed the act");
strcpy(data.coop.passed2, (worldmapheader->actnum) ? "passed act" : "passed the act");
}
// length is okay for normal use
else
{
snprintf(data.coop.passed1, sizeof data.coop.passed1, "%s got",
skins[players[consoleplayer].skin].realname);
strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "through act" : "through the act");
strcpy(data.coop.passed2, (worldmapheader->actnum) ? "through act" : "through the act");
}
}
// set X positions
if (mapheaderinfo[gamemap-1]->actnum)
if (worldmapheader->actnum)
{
data.coop.passedx1 = 62 + (176 - V_LevelNameWidth(data.coop.passed1))/2;
data.coop.passedx2 = 62 + (176 - V_LevelNameWidth(data.coop.passed2))/2;
@ -1418,7 +1418,7 @@ void Y_StartIntermission(void)
// at the start of intermission, and precalculating it would preclude mods
// changing the font to one of a slightly different width.
if ((stagefailed) && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
if ((stagefailed) && !(worldmapheader->levelflags & LF_NOZONE))
{
// Bit of a hack, offset so that the "Zone" text is right aligned like title cards.
data.coop.passedx2 = (data.coop.passedx1 + V_LevelNameWidth(data.coop.passed1)) - V_LevelNameWidth(data.coop.passed2);
@ -1433,7 +1433,7 @@ void Y_StartIntermission(void)
Y_AwardSpecialStageBonus();
// grab an interscreen if appropriate
if (mapheaderinfo[gamemap-1]->interscreen[0] != '#')
if (worldmapheader->interscreen[0] != '#')
useinterpic = true;
else
useinterpic = false;