From e49d12b7310ec4f1a9e6ec415a85be1f6143d28f Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 5 Aug 2019 15:00:09 -0700 Subject: [PATCH 01/70] Expose CV_FindVar (cherry picked from commit 0e9d69d6a3759686ca8bb567817be650291ea0e1) --- src/command.c | 4 ++-- src/command.h | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/command.c b/src/command.c index 33d8ead96..309881382 100644 --- a/src/command.c +++ b/src/command.c @@ -54,7 +54,7 @@ static void COM_Add_f(void); static void CV_EnforceExecVersion(void); static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr); static boolean CV_Command(void); -static consvar_t *CV_FindVar(const char *name); +consvar_t *CV_FindVar(const char *name); static const char *CV_StringValue(const char *var_name); static consvar_t *consvar_vars; // list of registered console variables @@ -1055,7 +1055,7 @@ static const char *cv_null_string = ""; * \return Pointer to the variable if found, or NULL. * \sa CV_FindNetVar */ -static consvar_t *CV_FindVar(const char *name) +consvar_t *CV_FindVar(const char *name) { consvar_t *cvar; diff --git a/src/command.h b/src/command.h index 51e161cd0..54584bb2d 100644 --- a/src/command.h +++ b/src/command.h @@ -140,6 +140,9 @@ void CV_ToggleExecVersion(boolean enable); // register a variable for use at the console void CV_RegisterVar(consvar_t *variable); +// returns a console variable by name +consvar_t *CV_FindVar(const char *name); + // sets changed to 0 for every console variable void CV_ClearChangedFlags(void); From 7df6a3090a41c585bbc9752b3447b9922b5da26f Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 5 Aug 2019 15:00:21 -0700 Subject: [PATCH 02/70] Lua CV_FindVar function (cherry picked from commit b5746c231d17cd7b58c6b633e242d5ad26ad7017) --- src/lua_consolelib.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 58e720c85..65dd553cd 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -427,6 +427,26 @@ static int lib_cvRegisterVar(lua_State *L) return 1; } +static int lib_cvFindVar(lua_State *L) +{ + consvar_t *cv; + if (( cv = CV_FindVar(luaL_checkstring(L,1)) )) + { + lua_settop(L,1);/* We only want one argument in the stack. */ + lua_pushlightuserdata(L, cv);/* Now the second value on stack. */ + luaL_getmetatable(L, META_CVAR); + /* + The metatable is the last value on the stack, so this + applies it to the second value, which is the cvar. + */ + lua_setmetatable(L,2); + lua_pushvalue(L,2); + return 1; + } + else + return 0; +} + // CONS_Printf for a single player // Use 'print' in baselib for a global message. static int lib_consPrintf(lua_State *L) @@ -466,6 +486,7 @@ static luaL_Reg lib[] = { {"COM_BufAddText", lib_comBufAddText}, {"COM_BufInsertText", lib_comBufInsertText}, {"CV_RegisterVar", lib_cvRegisterVar}, + {"CV_FindVar", lib_cvFindVar}, {"CONS_Printf", lib_consPrintf}, {NULL, NULL} }; From 51404130af736868d7474beaf388bcdef706e6d1 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 01:44:27 -0300 Subject: [PATCH 03/70] Respawn delay gametype rule --- src/dehacked.c | 1 + src/doomstat.h | 1 + src/g_game.c | 10 +++++----- src/p_user.c | 25 ++++++++++++++----------- src/st_stuff.c | 2 +- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index b77939c2a..939e8c8cf 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8928,6 +8928,7 @@ static const char *const GAMETYPERULE_LIST[] = { "OVERTIME", "HURTMESSAGES", "SPAWNINVUL", + "RESPAWNDELAY", NULL }; diff --git a/src/doomstat.h b/src/doomstat.h index b7bb7a362..5dc3a6eb9 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -423,6 +423,7 @@ enum GameTypeRules GTR_OVERTIME = 1<<26, // Allow overtime GTR_HURTMESSAGES = 1<<27, // Hit and death messages GTR_SPAWNINVUL = 1<<28, // Babysitting deterrent + GTR_RESPAWNDELAY = 1<<29, // Respawn delay }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index 19b18ef8c..3f1441922 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3201,17 +3201,17 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = GTR_RACE|GTR_SPAWNENEMIES|GTR_SPAWNINVUL|GTR_ALLOWEXIT, // Match - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_SPAWNINVUL|GTR_PITYSHIELD|GTR_DEATHPENALTY, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD|GTR_DEATHPENALTY, // Team Match - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_SPAWNINVUL|GTR_PITYSHIELD, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, // Tag - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_SPAWNINVUL, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, // Hide and Seek - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_SPAWNINVUL, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, // CTF - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_SPAWNINVUL|GTR_PITYSHIELD, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, }; // diff --git a/src/p_user.c b/src/p_user.c index fbcc17d24..a85457ad4 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9462,19 +9462,22 @@ static void P_DeathThink(player_t *player) // Respawn with jump button, force respawn time (3 second default, cheat protected) in shooter modes. if (cmd->buttons & BT_JUMP) { + // You're a spectator, so respawn right away. if (gametype != GT_COOP && player->spectator) player->playerstate = PST_REBORN; - else switch(gametype) { - case GT_COOP: - case GT_COMPETITION: - case GT_RACE: - if (player->deadtimer > TICRATE) - player->playerstate = PST_REBORN; - break; - default: - if (player->deadtimer > cv_respawntime.value*TICRATE) - player->playerstate = PST_REBORN; - break; + else + { + // Give me one second. + INT32 respawndelay = TICRATE; + + // Non-platform gametypes + if (gametyperules & GTR_RESPAWNDELAY) + respawndelay = (cv_respawntime.value*TICRATE); + + // You've been dead for enough time. + // You may now respawn. + if (player->deadtimer > respawndelay) + player->playerstate = PST_REBORN; } } diff --git a/src/st_stuff.c b/src/st_stuff.c index 5e05030c3..d8b9a8059 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2202,7 +2202,7 @@ static void ST_drawTextHUD(void) donef12 = true; } } - else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) // Death overrides spectator text. + else if ((gametyperules & GTR_RESPAWNDELAY) && stplyr->playerstate == PST_DEAD && stplyr->lives) // Death overrides spectator text. { INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE; From 56e94182d5de9d497307cb12e886275a4edf8eb6 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 02:07:13 -0300 Subject: [PATCH 04/70] P_SetupCamera funny --- src/p_setup.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 9acc4adb3..39f2ef545 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2447,17 +2447,10 @@ static void P_SetupCamera(void) { mapthing_t *thing; - switch (gametype) - { - case GT_MATCH: - case GT_TAG: + if ((gametyperules & GTR_DEATHMATCHSTARTS) || (gametype == GT_MATCH || gametype == GT_TAG)) thing = deathmatchstarts[0]; - break; - - default: + else thing = playerstarts[0]; - break; - } if (thing) { From 9613bdeca69bde37ecd452ec3649c5798b02f6c0 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 12:14:33 -0300 Subject: [PATCH 05/70] use GTR_DEATHMATCHSTARTS --- src/g_game.c | 13 ++++++------- src/p_setup.c | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 3f1441922..3ba3ab40f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2689,8 +2689,7 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost) // -- DM/Tag/CTF-spectator/etc -- // Order: DM->CTF->Coop - else if ((gametyperules & GTR_DEATHMATCHSTARTS) || gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF - || ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && !(players[playernum].pflags & PF_TAGIT))) + else if ((gametyperules & GTR_DEATHMATCHSTARTS) && !(players[playernum].pflags & PF_TAGIT)) { if (!(spawnpoint = G_FindMatchStart(playernum)) // find a DM start && !(spawnpoint = G_FindCTFStart(playernum))) // find a CTF start @@ -3201,17 +3200,17 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = GTR_RACE|GTR_SPAWNENEMIES|GTR_SPAWNINVUL|GTR_ALLOWEXIT, // Match - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD|GTR_DEATHPENALTY, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD|GTR_DEATHPENALTY, // Team Match - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, // Tag - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, // Hide and Seek - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, // CTF - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, }; // diff --git a/src/p_setup.c b/src/p_setup.c index 39f2ef545..5fc740191 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2447,7 +2447,7 @@ static void P_SetupCamera(void) { mapthing_t *thing; - if ((gametyperules & GTR_DEATHMATCHSTARTS) || (gametype == GT_MATCH || gametype == GT_TAG)) + if (gametyperules & GTR_DEATHMATCHSTARTS) thing = deathmatchstarts[0]; else thing = playerstarts[0]; From 1d0d40492272db90d9f0a12278c247e78a5a5c0c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 12:17:38 -0300 Subject: [PATCH 06/70] check if the gametype allows spectators to allow jump key respawn --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index a85457ad4..e9c32813a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9463,7 +9463,7 @@ static void P_DeathThink(player_t *player) if (cmd->buttons & BT_JUMP) { // You're a spectator, so respawn right away. - if (gametype != GT_COOP && player->spectator) + if ((gametyperules & GTR_SPECTATORS) && player->spectator) player->playerstate = PST_REBORN; else { From 5c023739e6e80cc6f1faeac5ecaa39ceb89d5b6f Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 12:23:50 -0300 Subject: [PATCH 07/70] change this > to >= --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index b3ff8ce71..5e405156c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4690,7 +4690,7 @@ static boolean M_CanShowLevelOnPlatter(INT32 mapnum, INT32 gt) if (gt == GT_RACE && (mapheaderinfo[mapnum]->typeoflevel & TOL_RACE)) return true; - if (gt > 0 && gt < gametypecount && (mapheaderinfo[mapnum]->typeoflevel & gametypetol[gt])) + if (gt >= 0 && gt < gametypecount && (mapheaderinfo[mapnum]->typeoflevel & gametypetol[gt])) return true; return false; From f8eed7171a8d63176bf2e43b8662d58befbf0758 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 12:28:00 -0300 Subject: [PATCH 08/70] add G_CompetitionGametype(void) --- src/g_game.c | 10 ++++++++++ src/g_game.h | 1 + src/p_setup.c | 2 +- src/p_user.c | 2 +- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 3ba3ab40f..28de6693f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3492,6 +3492,16 @@ boolean G_TagGametype(void) return (gametyperules & GTR_TAG); } +// +// G_CompetitionGametype +// +// For gametypes that are race gametypes, and have lives. +// +boolean G_CompetitionGametype(void) +{ + return ((gametyperules & GTR_RACE) && (gametyperules & GTR_LIVES)); +} + /** Get the typeoflevel flag needed to indicate support of a gametype. * In single-player, this always returns TOL_SP. * \param gametype The gametype for which support is desired. diff --git a/src/g_game.h b/src/g_game.h index 238dd1964..6916bba6e 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -223,6 +223,7 @@ boolean G_GametypeHasSpectators(void); boolean G_RingSlingerGametype(void); boolean G_PlatformGametype(void); boolean G_TagGametype(void); +boolean G_CompetitionGametype(void); boolean G_EnoughPlayersFinished(void); void G_ExitLevel(void); void G_NextLevel(void); diff --git a/src/p_setup.c b/src/p_setup.c index 5fc740191..3f49a1680 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2159,7 +2159,7 @@ static void P_LevelInitStuff(void) { G_PlayerReborn(i, true); - if (canresetlives && (netgame || multiplayer) && playeringame[i] && (gametype == GT_COMPETITION || players[i].lives <= 0)) + if (canresetlives && (netgame || multiplayer) && playeringame[i] && (G_CompetitionGametype() || players[i].lives <= 0)) { // In Co-Op, replenish a user's lives if they are depleted. players[i].lives = cv_startinglives.value; diff --git a/src/p_user.c b/src/p_user.c index e9c32813a..ff6ffc677 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9491,7 +9491,7 @@ static void P_DeathThink(player_t *player) INT32 i, deadtimercheck = INT32_MAX; // In a net/multiplayer game, and out of lives - if (gametype == GT_COMPETITION) + if (G_CompetitionGametype()) { for (i = 0; i < MAXPLAYERS; i++) { From f0d58368f912941c9a46edf29cab87fc76be8a1b Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 12:29:21 -0300 Subject: [PATCH 09/70] look for GTR_LIVES rule instead of coop/competition gametype --- src/p_user.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index ff6ffc677..3f407d6a9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1230,7 +1230,7 @@ void P_GivePlayerLives(player_t *player, INT32 numlives) if (gamestate == GS_LEVEL) { - if (player->lives == INFLIVES || (gametype != GT_COOP && gametype != GT_COMPETITION)) + if (player->lives == INFLIVES || !(gametyperules & GTR_LIVES)) { P_GivePlayerRings(player, 100*numlives); return; @@ -1395,7 +1395,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) player->score = MAXSCORE; // check for extra lives every 50000 pts - if (!ultimatemode && !modeattacking && player->score > oldscore && player->score % 50000 < amount && (gametype == GT_COMPETITION || gametype == GT_COOP)) + if (!ultimatemode && !modeattacking && player->score > oldscore && player->score % 50000 < amount && (gametyperules & GTR_LIVES)) { P_GivePlayerLives(player, (player->score/50000) - (oldscore/50000)); P_PlayLivesJingle(player); From 6b8839d5aaee3212b3c0a7f6976504fb235759f7 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 12:34:35 -0300 Subject: [PATCH 10/70] burst emeralds with GTR_MATCHEMERALDS --- src/p_inter.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 56a76b15c..a8b169db5 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3201,10 +3201,12 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) player->powers[pw_carry] = CR_NONE; // Burst weapons and emeralds in Match/CTF only - if (source && (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF)) + if (source) { - P_PlayerRingBurst(player, player->rings); - P_PlayerEmeraldBurst(player, false); + if (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF) + P_PlayerRingBurst(player, player->rings); + if (gametyperules & GTR_MATCHEMERALDS) + P_PlayerEmeraldBurst(player, false); } // Get rid of shield From ed29efd9ebf1ccd90ded05742dcdad5a5de04249 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 16:58:55 -0300 Subject: [PATCH 11/70] ST_drawLivesArea stuff. --- src/st_stuff.c | 134 ++++++++++++++++++++++++++++--------------------- 1 file changed, 77 insertions(+), 57 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index d8b9a8059..02b559cbf 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -845,69 +845,13 @@ static void ST_drawLivesArea(void) hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, faceprefix[stplyr->skin], colormap); } - // Lives number + // Metal Sonic recording if (metalrecording) { if (((2*leveltime)/TICRATE) & 1) V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, hudinfo[HUD_LIVES].f|V_PERPLAYER|V_REDMAP|V_HUDTRANS, "REC"); } - else if (G_GametypeUsesLives() || gametype == GT_RACE) - { - // x - V_DrawScaledPatch(hudinfo[HUD_LIVES].x+22, hudinfo[HUD_LIVES].y+10, - hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, stlivex); - - // lives number - if (gametype == GT_RACE) - { - livescount = INFLIVES; - notgreyedout = true; - } - else if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) - { - INT32 i; - livescount = 0; - notgreyedout = (stplyr->lives > 0); - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - - if (players[i].lives < 1) - continue; - - if (players[i].lives > 1) - notgreyedout = true; - - if (players[i].lives == INFLIVES) - { - livescount = INFLIVES; - break; - } - else if (livescount < 99) - livescount += (players[i].lives); - } - } - else - { - livescount = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? INFLIVES : stplyr->lives); - notgreyedout = true; - } - - if (livescount == INFLIVES) - V_DrawCharacter(hudinfo[HUD_LIVES].x+50, hudinfo[HUD_LIVES].y+8, - '\x16' | 0x80 | hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, false); - else - { - if (stplyr->playerstate == PST_DEAD && !(stplyr->spectator) && (livescount || stplyr->deadtimer < (TICRATE<<1))) - livescount++; - if (livescount > 99) - livescount = 99; - V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, - hudinfo[HUD_LIVES].f|V_PERPLAYER|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF), va("%d",livescount)); - } - } // Spectator else if (stplyr->spectator) v_colmap = V_GRAYMAP; @@ -934,6 +878,82 @@ static void ST_drawLivesArea(void) v_colmap = V_BLUEMAP; } } + // Lives number + else + { + boolean candrawlives = true; + + // Co-op and Competition, normal life counter + if (G_GametypeUsesLives()) + { + // Handle cooplives here + if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) + { + INT32 i; + livescount = 0; + notgreyedout = (stplyr->lives > 0); + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (players[i].lives < 1) + continue; + + if (players[i].lives > 1) + notgreyedout = true; + + if (players[i].lives == INFLIVES) + { + livescount = INFLIVES; + break; + } + else if (livescount < 99) + livescount += (players[i].lives); + } + } + else + { + livescount = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? INFLIVES : stplyr->lives); + notgreyedout = true; + } + } + // Infinity symbol (Race) + else if (G_PlatformGametype() && !(gametyperules & GTR_LIVES)) + { + livescount = INFLIVES; + notgreyedout = true; + } + // Otherwise nothing, sorry. + // Special Stages keep not showing lives, + // as G_GametypeUsesLives() returns false in + // Special Stages, and the infinity symbol + // cannot show up because Special Stages + // still have the GTR_LIVES gametype rule + // by default. + else + candrawlives = false; + + // Draw the lives counter here. + if (candrawlives) + { + // x + V_DrawScaledPatch(hudinfo[HUD_LIVES].x+22, hudinfo[HUD_LIVES].y+10, hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, stlivex); + if (livescount == INFLIVES) + V_DrawCharacter(hudinfo[HUD_LIVES].x+50, hudinfo[HUD_LIVES].y+8, + '\x16' | 0x80 | hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, false); + else + { + if (stplyr->playerstate == PST_DEAD && !(stplyr->spectator) && (livescount || stplyr->deadtimer < (TICRATE<<1))) + livescount++; + if (livescount > 99) + livescount = 99; + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, + hudinfo[HUD_LIVES].f|V_PERPLAYER|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF), va("%d",livescount)); + } + } +#undef ST_drawLivesX + } // name v_colmap |= (V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER); From 1f96f701730ab80348097852523b9b7d94e22892 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 17:08:20 -0300 Subject: [PATCH 12/70] Preparing for the inevitable gametype rule that will handle cooplives... --- src/d_netcmd.c | 2 +- src/g_game.c | 14 ++++++++++++++ src/g_game.h | 1 + src/hu_stuff.c | 4 ++-- src/lua_baselib.c | 18 ++++++++++++++++++ src/p_inter.c | 4 ++-- src/p_user.c | 6 +++--- src/st_stuff.c | 8 ++++---- src/y_inter.c | 4 ++-- 9 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 4e14ca25f..77cb3bcd0 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3800,7 +3800,7 @@ static void CoopLives_OnChange(void) { INT32 i; - if (!(netgame || multiplayer) || gametype != GT_COOP) + if (!(netgame || multiplayer) || !G_GametypeUsesCoopLives()) return; switch (cv_cooplives.value) diff --git a/src/g_game.c b/src/g_game.c index 28de6693f..08422ee58 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3439,6 +3439,20 @@ boolean G_GametypeUsesLives(void) return false; } +// +// G_GametypeUsesCoopLives +// +// Returns true if the current gametype uses +// the cooplives CVAR. False otherwise. +// +boolean G_GametypeUsesCoopLives(void) +{ + // Preparing for the inevitable + // gametype rule that will + // handle cooplives... + return (gametype == GT_COOP); +} + // // G_GametypeHasTeams // diff --git a/src/g_game.h b/src/g_game.h index 6916bba6e..8e25554ab 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -218,6 +218,7 @@ void G_SetGametypeDescription(INT16 gtype, char *descriptiontext, UINT8 leftcolo INT32 G_GetGametypeByName(const char *gametypestr); boolean G_IsSpecialStage(INT32 mapnum); boolean G_GametypeUsesLives(void); +boolean G_GametypeUsesCoopLives(void); boolean G_GametypeHasTeams(void); boolean G_GametypeHasSpectators(void); boolean G_RingSlingerGametype(void); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index d9801793b..3844cf903 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2434,7 +2434,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I } } - if (G_GametypeUsesLives() && !(gametyperankings[gametype] == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives + if (G_GametypeUsesLives() && !(G_GametypeUsesCoopLives() && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|(greycheck ? V_60TRANS : 0), va("%dx", players[tab[i].num].lives)); else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT) { @@ -2743,7 +2743,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline | (greycheck ? V_TRANSLUCENT : 0) | V_ALLOWLOWERCASE, name); - if (G_GametypeUsesLives() && !(gametyperankings[gametype] == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives + if (G_GametypeUsesLives() && !(G_GametypeUsesCoopLives() && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE, va("%dx", players[tab[i].num].lives)); else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT) V_DrawSmallScaledPatch(x-28, y-4, 0, tagico); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 695e9367e..e3ded8256 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2854,6 +2854,14 @@ static int lib_gGametypeUsesLives(lua_State *L) return 1; } +static int lib_gGametypeUsesCoopLives(lua_State *L) +{ + //HUDSAFE + INLEVEL + lua_pushboolean(L, G_GametypeUsesCoopLives()); + return 1; +} + static int lib_gGametypeHasTeams(lua_State *L) { //HUDSAFE @@ -2894,6 +2902,14 @@ static int lib_gTagGametype(lua_State *L) return 1; } +static int lib_gCompetitionGametype(lua_State *L) +{ + //HUDSAFE + INLEVEL + lua_pushboolean(L, G_CompetitionGametype()); + return 1; +} + static int lib_gTicsToHours(lua_State *L) { tic_t rtic = luaL_checkinteger(L, 1); @@ -3139,11 +3155,13 @@ static luaL_Reg lib[] = { {"G_ExitLevel",lib_gExitLevel}, {"G_IsSpecialStage",lib_gIsSpecialStage}, {"G_GametypeUsesLives",lib_gGametypeUsesLives}, + {"G_GametypeUsesCoopLives",lib_gGametypeUsesCoopLives}, {"G_GametypeHasTeams",lib_gGametypeHasTeams}, {"G_GametypeHasSpectators",lib_gGametypeHasSpectators}, {"G_RingSlingerGametype",lib_gRingSlingerGametype}, {"G_PlatformGametype",lib_gPlatformGametype}, {"G_TagGametype",lib_gTagGametype}, + {"G_CompetitionGametype",lib_gCompetitionGametype}, {"G_TicsToHours",lib_gTicsToHours}, {"G_TicsToMinutes",lib_gTicsToMinutes}, {"G_TicsToSeconds",lib_gTicsToSeconds}, diff --git a/src/p_inter.c b/src/p_inter.c index a8b169db5..6fd0c91d1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2523,7 +2523,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->colorized = false; G_GhostAddColor(GHC_NORMAL); - if ((target->player->lives <= 1) && (netgame || multiplayer) && (gametype == GT_COOP) && (cv_cooplives.value == 0)) + if ((target->player->lives <= 1) && (netgame || multiplayer) && G_GametypeUsesCoopLives() && (cv_cooplives.value == 0)) ; else if (!target->player->bot && !target->player->spectator && (target->player->lives != INFLIVES) && G_GametypeUsesLives()) @@ -2533,7 +2533,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (target->player->lives <= 0) // Tails 03-14-2000 { boolean gameovermus = false; - if ((netgame || multiplayer) && (gametype == GT_COOP) && (cv_cooplives.value != 1)) + if ((netgame || multiplayer) && G_GametypeUsesCoopLives() && (cv_cooplives.value != 1)) { INT32 i; for (i = 0; i < MAXPLAYERS; i++) diff --git a/src/p_user.c b/src/p_user.c index 3f407d6a9..38560fe97 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1236,7 +1236,7 @@ void P_GivePlayerLives(player_t *player, INT32 numlives) return; } - if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) + if ((netgame || multiplayer) && G_GametypeUsesCoopLives() && cv_cooplives.value == 0) { P_GivePlayerRings(player, 100*numlives); if (player->lives - prevlives >= numlives) @@ -1267,7 +1267,7 @@ docooprespawn: void P_GiveCoopLives(player_t *player, INT32 numlives, boolean sound) { - if (!((netgame || multiplayer) && gametype == GT_COOP)) + if (!((netgame || multiplayer) && G_GametypeUsesCoopLives())) { P_GivePlayerLives(player, numlives); if (sound) @@ -9298,7 +9298,7 @@ boolean P_GetLives(player_t *player) { INT32 i, maxlivesplayer = -1, livescheck = 1; if (!(netgame || multiplayer) - || (gametype != GT_COOP) + || !G_GametypeUsesCoopLives() || (player->lives == INFLIVES)) return true; diff --git a/src/st_stuff.c b/src/st_stuff.c index 02b559cbf..9e761b1ab 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -887,7 +887,7 @@ static void ST_drawLivesArea(void) if (G_GametypeUsesLives()) { // Handle cooplives here - if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) + if ((netgame || multiplayer) && G_GametypeUsesCoopLives() && cv_cooplives.value == 3) { INT32 i; livescount = 0; @@ -914,7 +914,7 @@ static void ST_drawLivesArea(void) } else { - livescount = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? INFLIVES : stplyr->lives); + livescount = (((netgame || multiplayer) && G_GametypeUsesCoopLives() && cv_cooplives.value == 0) ? INFLIVES : stplyr->lives); notgreyedout = true; } } @@ -2246,7 +2246,7 @@ static void ST_drawTextHUD(void) textHUDdraw(M_GetText("\x82""Wait for the stage to end...")) else if (G_PlatformGametype()) { - if (gametype == GT_COOP) + if (G_GametypeUsesCoopLives()) { if (stplyr->lives <= 0 && cv_cooplives.value == 2 @@ -2657,7 +2657,7 @@ static void ST_overlayDrawer(void) INT32 i = MAXPLAYERS; INT32 deadtimer = stplyr->spectator ? TICRATE : (stplyr->deadtimer-(TICRATE<<1)); - if ((gametype == GT_COOP) + if (G_GametypeUsesCoopLives() && (netgame || multiplayer) && (cv_cooplives.value != 1)) { diff --git a/src/y_inter.c b/src/y_inter.c index b26c0797e..62b3d553d 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1977,7 +1977,7 @@ static void Y_AwardCoopBonuses(void) if (i == consoleplayer) { - data.coop.gotlife = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? 0 : ptlives); + data.coop.gotlife = (((netgame || multiplayer) && G_GametypeUsesCoopLives() && cv_cooplives.value == 0) ? 0 : ptlives); M_Memcpy(&data.coop.bonuses, &localbonuses, sizeof(data.coop.bonuses)); } } @@ -2032,7 +2032,7 @@ static void Y_AwardSpecialStageBonus(void) if (i == consoleplayer) { - data.spec.gotlife = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? 0 : ptlives); + data.spec.gotlife = (((netgame || multiplayer) && G_GametypeUsesCoopLives() && cv_cooplives.value == 0) ? 0 : ptlives); M_Memcpy(&data.spec.bonuses, &localbonuses, sizeof(data.spec.bonuses)); // Continues related From 3b341245f13cdf2a5e3ef425e2b73aaea6cf5d27 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 17:14:56 -0300 Subject: [PATCH 13/70] Same deal, but for starposts. --- src/g_game.c | 24 +++++++++++++++++++----- src/g_game.h | 1 + src/lua_baselib.c | 9 +++++++++ src/p_inter.c | 2 +- src/p_setup.c | 4 ++-- src/p_user.c | 4 ++-- 6 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 08422ee58..2d9f2663e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2890,11 +2890,11 @@ void G_DoReborn(INT32 playernum) if (countdowntimeup || (!(netgame || multiplayer) && gametype == GT_COOP)) resetlevel = true; - else if (gametype == GT_COOP && (netgame || multiplayer) && !G_IsSpecialStage(gamemap)) + else if ((G_GametypeUsesCoopLives() || G_GametypeUsesCoopStarposts()) && (netgame || multiplayer) && !G_IsSpecialStage(gamemap)) { boolean notgameover = true; - if (cv_cooplives.value != 0 && player->lives <= 0) // consider game over first + if (G_GametypeUsesCoopLives() && (cv_cooplives.value != 0 && player->lives <= 0)) // consider game over first { for (i = 0; i < MAXPLAYERS; i++) { @@ -2929,7 +2929,7 @@ void G_DoReborn(INT32 playernum) } } - if (notgameover && cv_coopstarposts.value == 2) + if (G_GametypeUsesCoopStarposts() && (notgameover && cv_coopstarposts.value == 2)) { for (i = 0; i < MAXPLAYERS; i++) { @@ -3005,7 +3005,7 @@ void G_DoReborn(INT32 playernum) } // restore time in netgame (see also p_setup.c) - if ((netgame || multiplayer) && gametype == GT_COOP && cv_coopstarposts.value == 2) + if ((netgame || multiplayer) && G_GametypeUsesCoopStarposts() && cv_coopstarposts.value == 2) { // is this a hack? maybe tic_t maxstarposttime = 0; @@ -3076,7 +3076,7 @@ void G_AddPlayer(INT32 playernum) if (!players[i].exiting) notexiting++; - if (!(cv_coopstarposts.value && (gametype == GT_COOP) && (p->starpostnum < players[i].starpostnum))) + if (!(cv_coopstarposts.value && G_GametypeUsesCoopStarposts() && (p->starpostnum < players[i].starpostnum))) continue; p->starpostscale = players[i].starpostscale; @@ -3453,6 +3453,20 @@ boolean G_GametypeUsesCoopLives(void) return (gametype == GT_COOP); } +// +// G_GametypeUsesCoopStarposts +// +// Returns true if the current gametype uses +// the coopstarposts CVAR. False otherwise. +// +boolean G_GametypeUsesCoopStarposts(void) +{ + // Preparing for the inevitable + // gametype rule that will + // handle coopstarposts... + return (gametype == GT_COOP); +} + // // G_GametypeHasTeams // diff --git a/src/g_game.h b/src/g_game.h index 8e25554ab..68e78789f 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -219,6 +219,7 @@ INT32 G_GetGametypeByName(const char *gametypestr); boolean G_IsSpecialStage(INT32 mapnum); boolean G_GametypeUsesLives(void); boolean G_GametypeUsesCoopLives(void); +boolean G_GametypeUsesCoopStarposts(void); boolean G_GametypeHasTeams(void); boolean G_GametypeHasSpectators(void); boolean G_RingSlingerGametype(void); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index e3ded8256..2a82ec512 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2862,6 +2862,14 @@ static int lib_gGametypeUsesCoopLives(lua_State *L) return 1; } +static int lib_gGametypeUsesCoopStarposts(lua_State *L) +{ + //HUDSAFE + INLEVEL + lua_pushboolean(L, G_GametypeUsesCoopStarposts()); + return 1; +} + static int lib_gGametypeHasTeams(lua_State *L) { //HUDSAFE @@ -3156,6 +3164,7 @@ static luaL_Reg lib[] = { {"G_IsSpecialStage",lib_gIsSpecialStage}, {"G_GametypeUsesLives",lib_gGametypeUsesLives}, {"G_GametypeUsesCoopLives",lib_gGametypeUsesCoopLives}, + {"G_GametypeUsesCoopStarposts",lib_gGametypeUsesCoopStarposts}, {"G_GametypeHasTeams",lib_gGametypeHasTeams}, {"G_GametypeHasSpectators",lib_gGametypeHasSpectators}, {"G_RingSlingerGametype",lib_gRingSlingerGametype}, diff --git a/src/p_inter.c b/src/p_inter.c index 6fd0c91d1..f2d34bd7d 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1451,7 +1451,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->starpostnum >= special->health) return; // Already hit this post - if (cv_coopstarposts.value && gametype == GT_COOP && (netgame || multiplayer)) + if (cv_coopstarposts.value && G_GametypeUsesCoopStarposts() && (netgame || multiplayer)) { for (i = 0; i < MAXPLAYERS; i++) { diff --git a/src/p_setup.c b/src/p_setup.c index 3f49a1680..e09ecf6c3 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2141,7 +2141,7 @@ static void P_LevelInitStuff(void) // earthquake camera memset(&quake,0,sizeof(struct quake)); - if ((netgame || multiplayer) && gametype == GT_COOP && cv_coopstarposts.value == 2) + if ((netgame || multiplayer) && G_GametypeUsesCoopStarposts() && cv_coopstarposts.value == 2) { for (i = 0; i < MAXPLAYERS; i++) { @@ -2848,7 +2848,7 @@ boolean P_SetupLevel(boolean skipprecip) } // restore time in netgame (see also g_game.c) - if ((netgame || multiplayer) && gametype == GT_COOP && cv_coopstarposts.value == 2) + if ((netgame || multiplayer) && G_GametypeUsesCoopStarposts() && cv_coopstarposts.value == 2) { // is this a hack? maybe tic_t maxstarposttime = 0; diff --git a/src/p_user.c b/src/p_user.c index 38560fe97..9ad85cac1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9447,7 +9447,7 @@ static void P_DeathThink(player_t *player) player->playerstate = PST_REBORN; else if ((player->lives > 0 || j != MAXPLAYERS) && !(!(netgame || multiplayer) && G_IsSpecialStage(gamemap))) // Don't allow "click to respawn" in special stages! { - if (gametype == GT_COOP && (netgame || multiplayer) && cv_coopstarposts.value == 2) + if (G_GametypeUsesCoopStarposts() && (netgame || multiplayer) && cv_coopstarposts.value == 2) { P_ConsiderAllGone(); if ((player->deadtimer > TICRATE<<1) || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE))) @@ -11537,7 +11537,7 @@ void P_PlayerThink(player_t *player) #else if (player->spectator && #endif - gametype == GT_COOP && (netgame || multiplayer) && cv_coopstarposts.value == 2) + G_GametypeUsesCoopStarposts() && (netgame || multiplayer) && cv_coopstarposts.value == 2) P_ConsiderAllGone(); if (player->playerstate == PST_DEAD) From 4b2c88fab8bc2645b744385c6b827006a48801ab Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 17:15:23 -0300 Subject: [PATCH 14/70] Fix CoopLives_OnChange. --- src/d_netcmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 77cb3bcd0..154bcb625 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3745,7 +3745,7 @@ static void CoopStarposts_OnChange(void) { INT32 i; - if (!(netgame || multiplayer) || gametype != GT_COOP) + if (!(netgame || multiplayer) || !G_GametypeUsesCoopStarposts()) return; switch (cv_coopstarposts.value) From e03eaa554bff41f31538be11b66e9b36a9a3989e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 17:22:55 -0300 Subject: [PATCH 15/70] In P_KillPlayer, check for the gametype's rules, instead of the gametype itself, before bursting rings. --- src/p_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_inter.c b/src/p_inter.c index f2d34bd7d..87b0c0a43 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3203,7 +3203,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) // Burst weapons and emeralds in Match/CTF only if (source) { - if (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF) + if ((gametyperules & GTR_RINGSLINGER) && !(gametyperules & GTR_TAG)) P_PlayerRingBurst(player, player->rings); if (gametyperules & GTR_MATCHEMERALDS) P_PlayerEmeraldBurst(player, false); From 1fb244d87fde7662f5808d6450eb146d58f56680 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 18:24:08 -0300 Subject: [PATCH 16/70] GTR_HIDETIME, not GTR_TAG --- src/st_stuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 9e761b1ab..35dd861c5 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -723,7 +723,7 @@ static void ST_drawTime(void) downwards = true; } // Post-hidetime normal. - else if (gametyperules & GTR_TAG) + else if (gametyperules & GTR_HIDETIME) tics = stplyr->realtime - hidetime*TICRATE; // "Shadow! What are you doing? Hurry and get back here // right now before the island blows up with you on it!" From 4b604328d56af04201c1e3edfef9147705bf041c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 19:47:03 -0300 Subject: [PATCH 17/70] Rename GTR_HIDETIME to GTR_STARTCOUNTDOWN. --- src/dehacked.c | 2 +- src/doomstat.h | 2 +- src/g_game.c | 4 ++-- src/st_stuff.c | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 939e8c8cf..5023f55ee 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8909,7 +8909,7 @@ static const char *const GAMETYPERULE_LIST[] = { "TAG", "POINTLIMIT", "TIMELIMIT", - "HIDETIME", + "STARTCOUNTDOWN", "HIDEFROZEN", "BLINDFOLDED", "FIRSTPERSON", diff --git a/src/doomstat.h b/src/doomstat.h index 5dc3a6eb9..faedf48d5 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -404,7 +404,7 @@ enum GameTypeRules GTR_TAG = 1<<7, // Tag and Hide and Seek GTR_POINTLIMIT = 1<<8, // Ringslinger point limit GTR_TIMELIMIT = 1<<9, // Ringslinger time limit - GTR_HIDETIME = 1<<10, // Hide time (Tag and Hide and Seek) + GTR_STARTCOUNTDOWN = 1<<10, // Hide time countdown (Tag and Hide and Seek) GTR_HIDEFROZEN = 1<<11, // Frozen after hide time (Hide and Seek, but not Tag) GTR_BLINDFOLDED = 1<<12, // Blindfolded view (Tag and Hide and Seek) GTR_FIRSTPERSON = 1<<13, // First person camera diff --git a/src/g_game.c b/src/g_game.c index 2d9f2663e..4adc0d604 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3205,9 +3205,9 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, // Tag - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_STARTCOUNTDOWN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, // Hide and Seek - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_STARTCOUNTDOWN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, // CTF GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, diff --git a/src/st_stuff.c b/src/st_stuff.c index 35dd861c5..960953b1b 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -694,7 +694,7 @@ static void ST_drawTime(void) else { // Counting down the hidetime? - if ((gametyperules & GTR_HIDETIME) && (stplyr->realtime <= (hidetime*TICRATE))) + if ((gametyperules & GTR_STARTCOUNTDOWN) && (stplyr->realtime <= (hidetime*TICRATE))) { tics = (hidetime*TICRATE - stplyr->realtime); if (tics < 3*TICRATE) @@ -705,7 +705,7 @@ static void ST_drawTime(void) else { // Hidetime finish! - if ((gametyperules & GTR_HIDETIME) && (stplyr->realtime < ((hidetime+1)*TICRATE))) + if ((gametyperules & GTR_STARTCOUNTDOWN) && (stplyr->realtime < ((hidetime+1)*TICRATE))) ST_drawRaceNum(hidetime*TICRATE - stplyr->realtime); // Time limit? @@ -723,7 +723,7 @@ static void ST_drawTime(void) downwards = true; } // Post-hidetime normal. - else if (gametyperules & GTR_HIDETIME) + else if (gametyperules & GTR_STARTCOUNTDOWN) tics = stplyr->realtime - hidetime*TICRATE; // "Shadow! What are you doing? Hurry and get back here // right now before the island blows up with you on it!" From 45af6d889906401067abe72fc73ae338934995ab Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 19:49:34 -0300 Subject: [PATCH 18/70] Rename GTR_MATCHEMERALDS to GTR_POWERSTONES. --- src/dehacked.c | 2 +- src/doomstat.h | 2 +- src/g_game.c | 4 ++-- src/p_inter.c | 2 +- src/p_mobj.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 5023f55ee..3c7fe25aa 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8913,7 +8913,7 @@ static const char *const GAMETYPERULE_LIST[] = { "HIDEFROZEN", "BLINDFOLDED", "FIRSTPERSON", - "MATCHEMERALDS", + "POWERSTONES", "TEAMFLAGS", "PITYSHIELD", "DEATHPENALTY", diff --git a/src/doomstat.h b/src/doomstat.h index faedf48d5..8046b5ed9 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -408,7 +408,7 @@ enum GameTypeRules GTR_HIDEFROZEN = 1<<11, // Frozen after hide time (Hide and Seek, but not Tag) GTR_BLINDFOLDED = 1<<12, // Blindfolded view (Tag and Hide and Seek) GTR_FIRSTPERSON = 1<<13, // First person camera - GTR_MATCHEMERALDS = 1<<14, // Ringslinger emeralds (Match and CTF) + GTR_POWERSTONES = 1<<14, // Power stones (Match and CTF) GTR_TEAMFLAGS = 1<<15, // Gametype has team flags (CTF) GTR_PITYSHIELD = 1<<16, // Award pity shield GTR_DEATHPENALTY = 1<<17, // Death score penalty diff --git a/src/g_game.c b/src/g_game.c index 4adc0d604..c8e185f56 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3200,7 +3200,7 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = GTR_RACE|GTR_SPAWNENEMIES|GTR_SPAWNINVUL|GTR_ALLOWEXIT, // Match - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD|GTR_DEATHPENALTY, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_POWERSTONES|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD|GTR_DEATHPENALTY, // Team Match GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, @@ -3210,7 +3210,7 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_STARTCOUNTDOWN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, // CTF - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_POWERSTONES|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, }; // diff --git a/src/p_inter.c b/src/p_inter.c index 87b0c0a43..2bbfafdb7 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3205,7 +3205,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) { if ((gametyperules & GTR_RINGSLINGER) && !(gametyperules & GTR_TAG)) P_PlayerRingBurst(player, player->rings); - if (gametyperules & GTR_MATCHEMERALDS) + if (gametyperules & GTR_POWERSTONES) P_PlayerEmeraldBurst(player, false); } diff --git a/src/p_mobj.c b/src/p_mobj.c index 75bc174a5..b6ec5df83 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11893,7 +11893,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) if (!cv_powerstones.value) return false; - if (!(gametyperules & GTR_MATCHEMERALDS)) + if (!(gametyperules & GTR_POWERSTONES)) return false; runemeraldmanager = true; From 093a1baf1d134ddac3fec5724552dc75f9390cb1 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 19:50:14 -0300 Subject: [PATCH 19/70] Remove debugging stuff. --- src/lua_script.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/lua_script.c b/src/lua_script.c index 18d9a87c2..eb1afaf09 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -299,9 +299,7 @@ int LUA_PushGlobals(lua_State *L, const char *word) // See the above. int LUA_CheckGlobals(lua_State *L, const char *word) { - if (fastcmp(word, "gametyperules")) - gametyperules = (UINT32)luaL_checkinteger(L, 2); - else if (fastcmp(word, "redscore")) + if (fastcmp(word, "redscore")) redscore = (UINT32)luaL_checkinteger(L, 2); else if (fastcmp(word, "bluescore")) bluescore = (UINT32)luaL_checkinteger(L, 2); From 7a00b3a331d86a06c6a27999999623c1308bc088 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 19:56:18 -0300 Subject: [PATCH 20/70] Add GTR_FRIENDLY. --- src/dehacked.c | 1 + src/doomstat.h | 49 +++++++++++++++++++++++++------------------------ src/g_game.c | 12 +++--------- 3 files changed, 29 insertions(+), 33 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 3c7fe25aa..799428455 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8905,6 +8905,7 @@ static const char *const GAMETYPERULE_LIST[] = { "FRIENDLYFIRE", "LIVES", "TEAMS", + "FRIENDLY", "RACE", "TAG", "POINTLIMIT", diff --git a/src/doomstat.h b/src/doomstat.h index 8046b5ed9..42c05ba63 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -400,30 +400,31 @@ enum GameTypeRules GTR_FRIENDLYFIRE = 1<<3, // Always allow friendly fire GTR_LIVES = 1<<4, // Co-op and Competition GTR_TEAMS = 1<<5, // Team Match, CTF - GTR_RACE = 1<<6, // Race and Competition - GTR_TAG = 1<<7, // Tag and Hide and Seek - GTR_POINTLIMIT = 1<<8, // Ringslinger point limit - GTR_TIMELIMIT = 1<<9, // Ringslinger time limit - GTR_STARTCOUNTDOWN = 1<<10, // Hide time countdown (Tag and Hide and Seek) - GTR_HIDEFROZEN = 1<<11, // Frozen after hide time (Hide and Seek, but not Tag) - GTR_BLINDFOLDED = 1<<12, // Blindfolded view (Tag and Hide and Seek) - GTR_FIRSTPERSON = 1<<13, // First person camera - GTR_POWERSTONES = 1<<14, // Power stones (Match and CTF) - GTR_TEAMFLAGS = 1<<15, // Gametype has team flags (CTF) - GTR_PITYSHIELD = 1<<16, // Award pity shield - GTR_DEATHPENALTY = 1<<17, // Death score penalty - GTR_NOSPECTATORSPAWN = 1<<18, // Use with GTR_SPECTATORS, spawn in the map instead of with the spectators - GTR_DEATHMATCHSTARTS = 1<<19, // Use deathmatch starts - GTR_SPECIALSTAGES = 1<<20, // Allow special stages - GTR_EMERALDTOKENS = 1<<21, // Spawn emerald tokens - GTR_EMERALDHUNT = 1<<22, // Emerald Hunt - GTR_SPAWNENEMIES = 1<<23, // Spawn enemies - GTR_ALLOWEXIT = 1<<24, // Allow exit sectors - GTR_NOTITLECARD = 1<<25, // Don't show the title card - GTR_OVERTIME = 1<<26, // Allow overtime - GTR_HURTMESSAGES = 1<<27, // Hit and death messages - GTR_SPAWNINVUL = 1<<28, // Babysitting deterrent - GTR_RESPAWNDELAY = 1<<29, // Respawn delay + GTR_FRIENDLY = 1<<6, // Co-op + GTR_RACE = 1<<7, // Race and Competition + GTR_TAG = 1<<8, // Tag and Hide and Seek + GTR_POINTLIMIT = 1<<9, // Ringslinger point limit + GTR_TIMELIMIT = 1<<10, // Ringslinger time limit + GTR_STARTCOUNTDOWN = 1<<11, // Hide time countdown (Tag and Hide and Seek) + GTR_HIDEFROZEN = 1<<12, // Frozen after hide time (Hide and Seek, but not Tag) + GTR_BLINDFOLDED = 1<<13, // Blindfolded view (Tag and Hide and Seek) + GTR_FIRSTPERSON = 1<<14, // First person camera + GTR_POWERSTONES = 1<<15, // Power stones (Match and CTF) + GTR_TEAMFLAGS = 1<<16, // Gametype has team flags (CTF) + GTR_PITYSHIELD = 1<<17, // Award pity shield + GTR_DEATHPENALTY = 1<<18, // Death score penalty + GTR_NOSPECTATORSPAWN = 1<<19, // Use with GTR_SPECTATORS, spawn in the map instead of with the spectators + GTR_DEATHMATCHSTARTS = 1<<20, // Use deathmatch starts + GTR_SPECIALSTAGES = 1<<21, // Allow special stages + GTR_EMERALDTOKENS = 1<<22, // Spawn emerald tokens + GTR_EMERALDHUNT = 1<<23, // Emerald Hunt + GTR_SPAWNENEMIES = 1<<24, // Spawn enemies + GTR_ALLOWEXIT = 1<<25, // Allow exit sectors + GTR_NOTITLECARD = 1<<26, // Don't show the title card + GTR_OVERTIME = 1<<27, // Allow overtime + GTR_HURTMESSAGES = 1<<28, // Hit and death messages + GTR_SPAWNINVUL = 1<<29, // Babysitting deterrent + GTR_RESPAWNDELAY = 1<<30, // Respawn delay }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index c8e185f56..67b6c2098 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3193,7 +3193,7 @@ const char *Gametype_ConstantNames[NUMGAMETYPES] = UINT32 gametypedefaultrules[NUMGAMETYPES] = { // Co-op - GTR_CAMPAIGN|GTR_LIVES|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDHUNT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES, + GTR_CAMPAIGN|GTR_LIVES|GTR_FRIENDLY|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDHUNT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES, // Competition GTR_RACE|GTR_LIVES|GTR_SPAWNENEMIES|GTR_EMERALDTOKENS|GTR_SPAWNINVUL|GTR_ALLOWEXIT, // Race @@ -3447,10 +3447,7 @@ boolean G_GametypeUsesLives(void) // boolean G_GametypeUsesCoopLives(void) { - // Preparing for the inevitable - // gametype rule that will - // handle cooplives... - return (gametype == GT_COOP); + return (gametyperules & (GTR_LIVES|GTR_FRIENDLY)) == (GTR_LIVES|GTR_FRIENDLY); } // @@ -3461,10 +3458,7 @@ boolean G_GametypeUsesCoopLives(void) // boolean G_GametypeUsesCoopStarposts(void) { - // Preparing for the inevitable - // gametype rule that will - // handle coopstarposts... - return (gametype == GT_COOP); + return (gametyperules & GTR_FRIENDLY); } // From ae0acfba0feeba6aaed4dd1ca247c0e9a3bd2774 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 20:18:21 -0300 Subject: [PATCH 21/70] Organise gametype ruleset again. --- src/dehacked.c | 22 ++++++++++---------- src/doomstat.h | 56 +++++++++++++++++++++++++------------------------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 799428455..d71ed854c 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8902,34 +8902,34 @@ static const char *const GAMETYPERULE_LIST[] = { "CAMPAIGN", "RINGSLINGER", "SPECTATORS", - "FRIENDLYFIRE", "LIVES", "TEAMS", + "FIRSTPERSON", + "POWERSTONES", + "TEAMFLAGS", "FRIENDLY", + "SPECIALSTAGES", + "EMERALDTOKENS", + "EMERALDHUNT", "RACE", "TAG", "POINTLIMIT", "TIMELIMIT", + "OVERTIME", + "HURTMESSAGES", + "FRIENDLYFIRE", "STARTCOUNTDOWN", "HIDEFROZEN", "BLINDFOLDED", - "FIRSTPERSON", - "POWERSTONES", - "TEAMFLAGS", + "RESPAWNDELAY", "PITYSHIELD", "DEATHPENALTY", "NOSPECTATORSPAWN", "DEATHMATCHSTARTS", - "SPECIALSTAGES", - "EMERALDTOKENS", - "EMERALDHUNT", + "SPAWNINVUL", "SPAWNENEMIES", "ALLOWEXIT", "NOTITLECARD", - "OVERTIME", - "HURTMESSAGES", - "SPAWNINVUL", - "RESPAWNDELAY", NULL }; diff --git a/src/doomstat.h b/src/doomstat.h index 42c05ba63..1e0eb4815 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -397,34 +397,34 @@ enum GameTypeRules GTR_CAMPAIGN = 1, // Linear Co-op map progression, don't allow random maps GTR_RINGSLINGER = 1<<1, // Outside of Co-op, Competition, and Race (overriden by cv_ringslinger) GTR_SPECTATORS = 1<<2, // Outside of Co-op, Competition, and Race - GTR_FRIENDLYFIRE = 1<<3, // Always allow friendly fire - GTR_LIVES = 1<<4, // Co-op and Competition - GTR_TEAMS = 1<<5, // Team Match, CTF - GTR_FRIENDLY = 1<<6, // Co-op - GTR_RACE = 1<<7, // Race and Competition - GTR_TAG = 1<<8, // Tag and Hide and Seek - GTR_POINTLIMIT = 1<<9, // Ringslinger point limit - GTR_TIMELIMIT = 1<<10, // Ringslinger time limit - GTR_STARTCOUNTDOWN = 1<<11, // Hide time countdown (Tag and Hide and Seek) - GTR_HIDEFROZEN = 1<<12, // Frozen after hide time (Hide and Seek, but not Tag) - GTR_BLINDFOLDED = 1<<13, // Blindfolded view (Tag and Hide and Seek) - GTR_FIRSTPERSON = 1<<14, // First person camera - GTR_POWERSTONES = 1<<15, // Power stones (Match and CTF) - GTR_TEAMFLAGS = 1<<16, // Gametype has team flags (CTF) - GTR_PITYSHIELD = 1<<17, // Award pity shield - GTR_DEATHPENALTY = 1<<18, // Death score penalty - GTR_NOSPECTATORSPAWN = 1<<19, // Use with GTR_SPECTATORS, spawn in the map instead of with the spectators - GTR_DEATHMATCHSTARTS = 1<<20, // Use deathmatch starts - GTR_SPECIALSTAGES = 1<<21, // Allow special stages - GTR_EMERALDTOKENS = 1<<22, // Spawn emerald tokens - GTR_EMERALDHUNT = 1<<23, // Emerald Hunt - GTR_SPAWNENEMIES = 1<<24, // Spawn enemies - GTR_ALLOWEXIT = 1<<25, // Allow exit sectors - GTR_NOTITLECARD = 1<<26, // Don't show the title card - GTR_OVERTIME = 1<<27, // Allow overtime - GTR_HURTMESSAGES = 1<<28, // Hit and death messages - GTR_SPAWNINVUL = 1<<29, // Babysitting deterrent - GTR_RESPAWNDELAY = 1<<30, // Respawn delay + GTR_LIVES = 1<<3, // Co-op and Competition + GTR_TEAMS = 1<<4, // Team Match, CTF + GTR_FIRSTPERSON = 1<<5, // First person camera + GTR_POWERSTONES = 1<<6, // Power stones (Match and CTF) + GTR_TEAMFLAGS = 1<<7, // Gametype has team flags (CTF) + GTR_FRIENDLY = 1<<8, // Co-op + GTR_SPECIALSTAGES = 1<<9, // Allow special stages + GTR_EMERALDTOKENS = 1<<10, // Spawn emerald tokens + GTR_EMERALDHUNT = 1<<11, // Emerald Hunt + GTR_RACE = 1<<12, // Race and Competition + GTR_TAG = 1<<13, // Tag and Hide and Seek + GTR_POINTLIMIT = 1<<14, // Ringslinger point limit + GTR_TIMELIMIT = 1<<15, // Ringslinger time limit + GTR_OVERTIME = 1<<16, // Allow overtime + GTR_HURTMESSAGES = 1<<17, // Hit and death messages + GTR_FRIENDLYFIRE = 1<<18, // Always allow friendly fire + GTR_STARTCOUNTDOWN = 1<<19, // Hide time countdown (Tag and Hide and Seek) + GTR_HIDEFROZEN = 1<<20, // Frozen after hide time (Hide and Seek, but not Tag) + GTR_BLINDFOLDED = 1<<21, // Blindfolded view (Tag and Hide and Seek) + GTR_RESPAWNDELAY = 1<<22, // Respawn delay + GTR_PITYSHIELD = 1<<23, // Award pity shield + GTR_DEATHPENALTY = 1<<24, // Death score penalty + GTR_NOSPECTATORSPAWN = 1<<25, // Use with GTR_SPECTATORS, spawn in the map instead of with the spectators + GTR_DEATHMATCHSTARTS = 1<<26, // Use deathmatch starts + GTR_SPAWNINVUL = 1<<27, // Babysitting deterrent + GTR_SPAWNENEMIES = 1<<28, // Spawn enemies + GTR_ALLOWEXIT = 1<<29, // Allow exit sectors + GTR_NOTITLECARD = 1<<30, // Don't show the title card }; // String names for gametypes From 216657192002bcfc74de14b1251ff52f25b8b3b1 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 20:33:28 -0300 Subject: [PATCH 22/70] Add GTR_CUTSCENES. And I ran out of rule slots. Cool. --- src/d_main.c | 2 +- src/dehacked.c | 1 + src/doomstat.h | 1 + src/g_game.c | 8 ++++---- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index e25ef998e..e79234730 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -715,7 +715,7 @@ void D_StartTitle(void) if (netgame) { - if (gametype == GT_COOP) + if (gametyperules & GTR_CAMPAIGN) { G_SetGamestate(GS_WAITINGPLAYERS); // hack to prevent a command repeat diff --git a/src/dehacked.c b/src/dehacked.c index d71ed854c..9a4e0d499 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8930,6 +8930,7 @@ static const char *const GAMETYPERULE_LIST[] = { "SPAWNENEMIES", "ALLOWEXIT", "NOTITLECARD", + "CUTSCENES", NULL }; diff --git a/src/doomstat.h b/src/doomstat.h index 1e0eb4815..6d1d6eb36 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -425,6 +425,7 @@ enum GameTypeRules GTR_SPAWNENEMIES = 1<<28, // Spawn enemies GTR_ALLOWEXIT = 1<<29, // Allow exit sectors GTR_NOTITLECARD = 1<<30, // Don't show the title card + GTR_CUTSCENES = 1<<31, // Play cutscenes, ending, credits, and evaluation }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index 67b6c2098..e201faf6a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3193,7 +3193,7 @@ const char *Gametype_ConstantNames[NUMGAMETYPES] = UINT32 gametypedefaultrules[NUMGAMETYPES] = { // Co-op - GTR_CAMPAIGN|GTR_LIVES|GTR_FRIENDLY|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDHUNT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES, + GTR_CAMPAIGN|GTR_LIVES|GTR_FRIENDLY|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDHUNT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES|GTR_CUTSCENES, // Competition GTR_RACE|GTR_LIVES|GTR_SPAWNENEMIES|GTR_EMERALDTOKENS|GTR_SPAWNINVUL|GTR_ALLOWEXIT, // Race @@ -3765,7 +3765,7 @@ void G_AfterIntermission(void) HU_ClearCEcho(); - if (mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking && skipstats <= 1) // Start a custom cutscene. + if ((gametyperules & GTR_CUTSCENES) && mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking && skipstats <= 1) // Start a custom cutscene. F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false); else { @@ -3875,7 +3875,7 @@ static void G_DoContinued(void) void G_EndGame(void) { // Only do evaluation and credits in coop games. - if (gametype == GT_COOP) + if (gametyperules & GTR_CUTSCENES) { if (nextmap == 1103-1) // end game with ending { @@ -4578,7 +4578,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean automapactive = false; imcontinuing = false; - if (!skipprecutscene && mapheaderinfo[gamemap-1]->precutscenenum && !modeattacking) // Start a custom cutscene. + if ((gametyperules & GTR_CUTSCENES) && !skipprecutscene && mapheaderinfo[gamemap-1]->precutscenenum && !modeattacking) // Start a custom cutscene. F_StartCustomCutscene(mapheaderinfo[gamemap-1]->precutscenenum-1, true, resetplayer); else G_DoLoadLevel(resetplayer); From 5b1b5569469e0cf30ae9297342e6f873217dcc89 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 20:54:22 -0300 Subject: [PATCH 23/70] Remove characters that will not be allowed in the constant string. --- src/g_game.c | 96 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 55 insertions(+), 41 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index e201faf6a..37dd292f9 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3251,50 +3251,64 @@ INT16 G_AddGametype(UINT32 rules) // void G_AddGametypeConstant(INT16 gtype, const char *newgtconst) { - char *gtconst = Z_Malloc(strlen(newgtconst) + 3, PU_STATIC, NULL); - // Copy GT_ and the gametype name. - strcpy(gtconst, "GT_"); - strcat(gtconst, newgtconst); + size_t r = 0; // read + size_t w = 0; // write + char *gtconst = Z_Calloc(strlen(newgtconst) + 3, PU_STATIC, NULL); + char *tmpconst = Z_Calloc(strlen(newgtconst), PU_STATIC, NULL); + + // Copy the gametype name. + strcpy(tmpconst, newgtconst); + // Make uppercase. - strupr(gtconst); - // Remove characters. -#define REMOVECHAR(chr) \ - { \ - char *chrfind = strchr(gtconst, chr); \ - while (chrfind) \ - { \ - *chrfind = '_'; \ - chrfind = strchr(chrfind, chr); \ - } \ + strupr(tmpconst); + + // Prepare to write the new constant string now. + strcpy(gtconst, "GT_"); + + // Remove characters that will not be allowed in the constant string. + for (; r < strlen(tmpconst); r++) + { + boolean writechar = true; + char rc = tmpconst[r]; + switch (rc) + { + // Space + case ' ': + // Used for operations + case '+': + case '-': + case '*': + case '/': + case '%': + case '^': + // Part of Lua's syntax + case '#': + case '=': + case '~': + case '<': + case '>': + case '(': + case ')': + case '{': + case '}': + case '[': + case ']': + case ':': + case ';': + case ',': + case '.': + writechar = false; + break; + } + if (writechar) + { + gtconst[3 + w] = rc; + w++; + } } - // Space - REMOVECHAR(' ') - // Used for operations - REMOVECHAR('+') - REMOVECHAR('-') - REMOVECHAR('*') - REMOVECHAR('/') - REMOVECHAR('%') - REMOVECHAR('^') - // Part of Lua's syntax - REMOVECHAR('#') - REMOVECHAR('=') - REMOVECHAR('~') - REMOVECHAR('<') - REMOVECHAR('>') - REMOVECHAR('(') - REMOVECHAR(')') - REMOVECHAR('{') - REMOVECHAR('}') - REMOVECHAR('[') - REMOVECHAR(']') - REMOVECHAR(':') - REMOVECHAR(';') - REMOVECHAR(',') - REMOVECHAR('.') - -#undef REMOVECHAR + // Free the temporary string. + Z_Free(tmpconst); // Finally, set the constant string. Gametype_ConstantNames[gtype] = gtconst; From dede51fc4c86343efb031ec67e6e09def5fb0fd6 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 21:05:42 -0300 Subject: [PATCH 24/70] Disallow few more characters. --- src/g_game.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 37dd292f9..779592713 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3272,8 +3272,10 @@ void G_AddGametypeConstant(INT16 gtype, const char *newgtconst) char rc = tmpconst[r]; switch (rc) { - // Space + // Space, at sign and question mark case ' ': + case '@': + case '?': // Used for operations case '+': case '-': @@ -3281,6 +3283,8 @@ void G_AddGametypeConstant(INT16 gtype, const char *newgtconst) case '/': case '%': case '^': + case '&': + case '!': // Part of Lua's syntax case '#': case '=': From aaef412823945719c30231d4c41d3fb9053dc0fb Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 30 Dec 2019 11:33:22 +0100 Subject: [PATCH 25/70] Add basic textmap support; currently crashes when trying to free the virtres, at vres_free(). --- src/doomdef.h | 2 + src/m_misc.c | 14 ++ src/p_setup.c | 371 +++++++++++++++++++++++++++++++++++++++++++++++++- src/w_wad.c | 2 + 4 files changed, 382 insertions(+), 7 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 51a15bd64..0d673a426 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -461,6 +461,8 @@ extern void *(*M_Memcpy)(void* dest, const void* src, size_t n) FUNCNONNULL; char *va(const char *format, ...) FUNCPRINTF; char *M_GetToken(const char *inputString); void M_UnGetToken(void); +UINT32 M_GetTokenPos(void); +void M_SetTokenPos(UINT32 newPos); char *sizeu1(size_t num); char *sizeu2(size_t num); char *sizeu3(size_t num); diff --git a/src/m_misc.c b/src/m_misc.c index b0a1fb8c5..edb24ab1e 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -1908,6 +1908,20 @@ void M_UnGetToken(void) endPos = oldendPos; } +/** Returns the current token's position. + */ +UINT32 M_GetTokenPos(void) +{ + return endPos; +} + +/** Sets the current token's position. + */ +void M_SetTokenPos(UINT32 newPos) +{ + endPos = newPos; +} + /** Count bits in a number. */ UINT8 M_CountBits(UINT32 num, UINT8 size) diff --git a/src/p_setup.c b/src/p_setup.c index 99da5ccee..c7eb50382 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -83,6 +83,8 @@ #include "p_slopes.h" #endif +#include "fastcmp.h" // textmap parsing + // // Map MD5, calculated on level load. // Sent to clients in PT_SERVERINFO. @@ -1236,10 +1238,367 @@ static void P_LoadThings(UINT8 *data) } } +// Stores positions for relevant map data spread through a TEXTMAP. +UINT32 mapthingsPos[UINT16_MAX]; +UINT32 linesPos[UINT16_MAX]; +UINT32 sidesPos[UINT16_MAX]; +UINT32 vertexesPos[UINT16_MAX]; +UINT32 sectorsPos[UINT16_MAX]; + +static boolean TextmapCount (UINT8 *data, size_t size) +{ + char *nsp1 = M_GetToken((char *)data); + boolean ret = true; + + // Determine total amount of map data in TEXTMAP. + // Look for namespace at the beginning. + if (fastcmp(nsp1, "namespace")) + { + char *nsp2 = M_GetToken(NULL); + char *tkn = M_GetToken(NULL); + + // Check if namespace is valid. + if (!fastcmp(nsp2, "srb2")) + CONS_Alert(CONS_WARNING, "Invalid namespace '%s', only 'srb2' is supported.\n", nsp2); + Z_Free(nsp2); + + while (tkn != NULL && M_GetTokenPos() < size) + { + // Avoid anything inside bracketed stuff, only look for external keywords. + // Assuming there's only one level of bracket nesting. + if (fastcmp(tkn, "{")) + { + Z_Free(tkn); + while (!fastcmp(tkn, "}")) + { + Z_Free(tkn); + tkn = M_GetToken(NULL); + } + } + // Check for valid fields. + else if (fastcmp(tkn, "thing")) + mapthingsPos[nummapthings++] = M_GetTokenPos(); + else if (fastcmp(tkn, "linedef")) + linesPos[numlines++] = M_GetTokenPos(); + else if (fastcmp(tkn, "sidedef")) + sidesPos[numsides++] = M_GetTokenPos(); + else if (fastcmp(tkn, "vertex")) + vertexesPos[numvertexes++] = M_GetTokenPos(); + else if (fastcmp(tkn, "sector")) + sectorsPos[numsectors++] = M_GetTokenPos(); + else + CONS_Alert(CONS_NOTICE, "Unknown field '%s'.\n", tkn); + + Z_Free(tkn); + tkn = M_GetToken(NULL); + } + } + else + { + CONS_Alert(CONS_WARNING, "No namespace at beginning of lump!\n"); + ret = false; + } + + Z_Free(nsp1); + return ret; +} + +static char* dat; + +/** Auxiliary function for TextmapParse. + * + * \param Vertex number. + * \param Parameter string. + */ +static void TextmapVertex(UINT32 i, char *param) +{ + if (fastcmp(param, "x")) + vertexes[i].x = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + else if (fastcmp(param, "y")) + vertexes[i].y = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); +} + +/** Auxiliary function for TextmapParse. + * + * \param Sector number. + * \param Parameter string. + */ +static void TextmapSector(UINT32 i, char *param) +{ + if (fastcmp(param, "heightfloor")) + sectors[i].floorheight = atol(dat = M_GetToken(NULL)) << FRACBITS; + else if (fastcmp(param, "heightceiling")) + sectors[i].ceilingheight = atol(dat = M_GetToken(NULL)) << FRACBITS; + if (fastcmp(param, "texturefloor")) + sectors[i].floorpic = P_AddLevelFlat(dat = M_GetToken(NULL), foundflats); + else if (fastcmp(param, "textureceiling")) + sectors[i].ceilingpic = P_AddLevelFlat(dat = M_GetToken(NULL), foundflats); + else if (fastcmp(param, "lightlevel")) + sectors[i].lightlevel = atol(dat = M_GetToken(NULL)); + else if (fastcmp(param, "special")) + sectors[i].special = atol(dat = M_GetToken(NULL)); + else if (fastcmp(param, "id")) + sectors[i].tag = atol(dat = M_GetToken(NULL)); +} + +/** Auxiliary function for TextmapParse. + * + * \param Side number. + * \param Parameter string. + */ +static void TextmapSide(UINT32 i, char *param) +{ + if (fastcmp(param, "offsetx")) + sides[i].textureoffset = atol(dat = M_GetToken(NULL))<z = 0; + + TextmapParse(vertexesPos[i], i, TextmapVertex); + } + + for (i = 0, sc = sectors; i < numsectors; i++, sc++) + { + // Defaults. + sc->floorheight = 0; + sc->ceilingheight = 0; + + sc->floorpic = 0; + sc->ceilingpic = 0; + + sc->lightlevel = 255; + + sc->special = 0; + sc->tag = 0; + + sc->floor_xoffs = sc->floor_yoffs = sc->ceiling_xoffs = sc->ceiling_yoffs = 0; + sc->floorpic_angle = sc->ceilingpic_angle = 0; + + TextmapParse(sectorsPos[i], i, TextmapSector); + + P_InitializeSector(sc); + } + + for (i = 0, ld = lines; i < numlines; i++, ld++) + { + // Defaults. + ld->tag = 0; + ld->special = 0; + ld->sidenum[1] = 0xffff; + + TextmapParse(linesPos[i], i, TextmapLine); + + P_InitializeLinedef(ld); + } + + for (i = 0, sd = sides; i < numsides; i++, sd++) + { + // Defaults. + sd->rowoffset = 0; + sd->textureoffset = 0; + + sd->toptexture = R_TextureNumForName("-"); + sd->midtexture = R_TextureNumForName("-"); + sd->bottomtexture = R_TextureNumForName("-"); + sd->repeatcnt = 0; + + TextmapParse(sidesPos[i], i, TextmapSide); + } + + for (i = 0, mt = mapthings; i < nummapthings; i++, mt++) + { + // Defaults. + mt->z = 0; + mt->angle = 0; + + TextmapParse(mapthingsPos[i], i, TextmapThing); + } +} + +/** Provides a fix to the flat alignment coordinate transform from standard Textmaps. + */ +static void TextmapFixFlatOffsets (void) +{ + fixed_t pc, ps; + fixed_t xoffs, yoffs; + size_t i; + sector_t* sec = sectors; + for (i = 0; i < numsectors; i++, sec++) + { + if (sec->floorpic_angle) + { + pc = FINECOSINE(sec->floorpic_angle>>ANGLETOFINESHIFT); + ps = FINESINE (sec->floorpic_angle>>ANGLETOFINESHIFT); + xoffs = sec->floor_xoffs; + yoffs = sec->floor_yoffs; + #define MAXFLATSIZE (2048<floor_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); + sec->floor_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); + #undef MAXFLATSIZE + } + + if (sec->ceilingpic_angle) + { + pc = FINECOSINE(sec->ceilingpic_angle>>ANGLETOFINESHIFT); + ps = FINESINE (sec->ceilingpic_angle>>ANGLETOFINESHIFT); + xoffs = sec->ceiling_xoffs; + yoffs = sec->ceiling_yoffs; + #define MAXFLATSIZE (2048<ceiling_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); + sec->ceiling_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); + #undef MAXFLATSIZE + } + } +} + static void P_LoadMapData(const virtres_t *virt) { virtlump_t* virtvertexes = NULL, * virtsectors = NULL, * virtsidedefs = NULL, * virtlinedefs = NULL, * virtthings = NULL; -#ifdef UDMF virtlump_t* textmap = vres_Find(virt, "TEXTMAP"); // Count map data. @@ -1252,10 +1611,9 @@ static void P_LoadMapData(const virtres_t *virt) numsectors = 0; // Count how many entries for each type we got in textmap. - //TextmapCount(vtextmap->data, vtextmap->size); + TextmapCount(textmap->data, textmap->size); } else -#endif { virtthings = vres_Find(virt, "THINGS"); virtvertexes = vres_Find(virt, "VERTEXES"); @@ -1305,15 +1663,14 @@ static void P_LoadMapData(const virtres_t *virt) numlevelflats = 0; -#ifdef UDMF + // Load map data. if (textmap) { - + P_LoadTextmap(); + TextmapFixFlatOffsets(); } else -#endif { - // Strict map data P_LoadVertices(virtvertexes->data); P_LoadSectors(virtsectors->data); P_LoadLinedefs(virtlinedefs->data); diff --git a/src/w_wad.c b/src/w_wad.c index 62992441a..47c3f42d0 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1942,6 +1942,8 @@ void vres_Free(virtres_t* vres) Z_Free(vres->vlumps[vres->numlumps].data); Z_Free(vres->vlumps); Z_Free(vres); + + CONS_Printf("A A A\n"); } /** (Debug) Prints lumps from a virtual resource into console. From 0839287609c3639e7f35057743c48175130a64eb Mon Sep 17 00:00:00 2001 From: lachwright Date: Mon, 30 Dec 2019 19:00:45 +0800 Subject: [PATCH 26/70] Add unused sounds and remove unused sound slots --- src/sounds.c | 42 +++++++++++++++++++++++++----------------- src/sounds.h | 42 +++++++++++++++++++++++++----------------- 2 files changed, 50 insertions(+), 34 deletions(-) diff --git a/src/sounds.c b/src/sounds.c index 175bd8960..720ba851e 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -187,6 +187,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"shield", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pity Shield"}, // generic GET! {"wirlsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Whirlwind Shield"}, // Whirlwind GET! {"forcsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Force Shield"}, // Force GET! + {"frcssg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Weak Force Shield"}, // Force GET...? (consider making a custom shield with this instead of a single-hit force shield!) {"elemsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Elemental Shield"}, // Elemental GET! {"armasg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Armageddon Shield"}, // Armaggeddon GET! {"attrsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Attraction Shield"}, // Attract GET! @@ -220,6 +221,9 @@ sfxinfo_t S_sfx[NUMSFX] = {"sprong", false, 112, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Power spring"}, {"lvfal1", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rumble"}, {"pscree", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "SCREE!"}, + {"iceb", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ice crack"}, + {"shattr", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Shattering"}, + {"antiri", true, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Depletion"}, // Menu, interface {"chchng", false, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Score"}, @@ -233,6 +237,9 @@ sfxinfo_t S_sfx[NUMSFX] = {"wepchg", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Weapon change"}, // Weapon switch is identical to menu for now {"wtrdng", true, 212, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aquaphobia"}, // make sure you can hear the DING DING! Tails 03-08-2000 {"zelda", false, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Discovery"}, + {"adderr", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Error"}, + {"notadd", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Reject"}, + {"addfil", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Accept"}, // NiGHTS {"ideya", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Success"}, @@ -427,24 +434,9 @@ sfxinfo_t S_sfx[NUMSFX] = {"s25e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"s25f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"s260", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s261", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s262", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s263", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s264", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s265", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s266", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s267", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s268", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s269", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s26a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s26b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s26c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s26d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s26e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s26f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s270", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // S3&K sounds + {"s3k2b", true, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got Emerald"}, // Got Emerald! {"s3k33", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sparkle"}, // stereo in original game, identical to latter {"s3k34", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sparkle"}, // mono in original game, identical to previous {"s3k35", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hurt"}, @@ -566,6 +558,21 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3ka9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aquaphobia"}, {"s3kaa", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bumper"}, {"s3kab", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kab1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kab2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kab3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kab4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kab5", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kab6", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kab7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kab8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kab9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kaba", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kabb", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kabc", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kabd", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kabe", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kabf", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, {"s3kac", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got Continue"}, {"s3kad", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "GO!"}, {"s3kae", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pinball flipper"}, @@ -604,7 +611,8 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3kc5l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Revving up"}, // ditto {"s3kc6s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Orbiting"}, {"s3kc6l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Orbiting"}, // ditto - {"s3kc7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aiming"}, + {"s3kc7s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aiming"}, + {"s3kc7l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aiming"}, // ditto {"s3kc8s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sliding"}, {"s3kc8l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sliding"}, // ditto {"s3kc9s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Swinging"}, diff --git a/src/sounds.h b/src/sounds.h index e520c6243..039349d4f 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -236,6 +236,7 @@ typedef enum sfx_shield, sfx_wirlsg, sfx_forcsg, + sfx_frcssg, sfx_elemsg, sfx_armasg, sfx_attrsg, @@ -269,6 +270,9 @@ typedef enum sfx_sprong, sfx_lvfal1, sfx_pscree, + sfx_iceb, + sfx_shattr, + sfx_antiri, // Menu, interface sfx_chchng, @@ -282,6 +286,9 @@ typedef enum sfx_wepchg, sfx_wtrdng, sfx_zelda, + sfx_adderr, + sfx_notadd, + sfx_addfil, // NiGHTS sfx_ideya, @@ -476,24 +483,9 @@ typedef enum sfx_s25e, sfx_s25f, sfx_s260, - sfx_s261, - sfx_s262, - sfx_s263, - sfx_s264, - sfx_s265, - sfx_s266, - sfx_s267, - sfx_s268, - sfx_s269, - sfx_s26a, - sfx_s26b, - sfx_s26c, - sfx_s26d, - sfx_s26e, - sfx_s26f, - sfx_s270, // S3&K sounds + sfx_s3k2b, sfx_s3k33, sfx_s3k34, sfx_s3k35, @@ -615,6 +607,21 @@ typedef enum sfx_s3ka9, sfx_s3kaa, sfx_s3kab, + sfx_s3kab1, + sfx_s3kab2, + sfx_s3kab3, + sfx_s3kab4, + sfx_s3kab5, + sfx_s3kab6, + sfx_s3kab7, + sfx_s3kab8, + sfx_s3kab9, + sfx_s3kaba, + sfx_s3kabb, + sfx_s3kabc, + sfx_s3kabd, + sfx_s3kabe, + sfx_s3kabf, sfx_s3kac, sfx_s3kad, sfx_s3kae, @@ -653,7 +660,8 @@ typedef enum sfx_s3kc5l, sfx_s3kc6s, sfx_s3kc6l, - sfx_s3kc7, + sfx_s3kc7s, + sfx_s3kc7l, sfx_s3kc8s, sfx_s3kc8l, sfx_s3kc9s, From ed114f655bd84576d8f3eea314921b9cc611b49e Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 30 Dec 2019 12:07:02 +0100 Subject: [PATCH 27/70] Fixed missing M_GetToken(NULL); --- src/p_setup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_setup.c b/src/p_setup.c index c7eb50382..71d1ca880 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1269,6 +1269,7 @@ static boolean TextmapCount (UINT8 *data, size_t size) if (fastcmp(tkn, "{")) { Z_Free(tkn); + tkn = M_GetToken(NULL); while (!fastcmp(tkn, "}")) { Z_Free(tkn); From f49b8de5fd8999965f28bc7fcec5ff666ac1b3d3 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 30 Dec 2019 12:07:54 +0100 Subject: [PATCH 28/70] Adapt P_MakeMapMD5() for textmaps. --- src/p_setup.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 71d1ca880..198b8ae6a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2668,27 +2668,34 @@ static INT32 P_MakeBufferMD5(const char *buffer, size_t len, void *resblock) static void P_MakeMapMD5(virtres_t *virt, void *dest) { - unsigned char linemd5[16]; - unsigned char sectormd5[16]; - unsigned char thingmd5[16]; - unsigned char sidedefmd5[16]; + virtlump_t* textmap = vres_Find(virt, "TEXTMAP"); unsigned char resmd5[16]; - UINT8 i; - // Create a hash for the current map - // get the actual lumps! - virtlump_t *virtlines = vres_Find(virt, "LINEDEFS"); - virtlump_t *virtsectors = vres_Find(virt, "SECTORS"); - virtlump_t *virtmthings = vres_Find(virt, "THINGS"); - virtlump_t *virtsides = vres_Find(virt, "SIDEDEFS"); + if (textmap) + P_MakeBufferMD5((char*)textmap->data, textmap->size, resmd5); + else + { + unsigned char linemd5[16]; + unsigned char sectormd5[16]; + unsigned char thingmd5[16]; + unsigned char sidedefmd5[16]; + UINT8 i; - P_MakeBufferMD5((char*)virtlines->data, virtlines->size, linemd5); - P_MakeBufferMD5((char*)virtsectors->data, virtsectors->size, sectormd5); - P_MakeBufferMD5((char*)virtmthings->data, virtmthings->size, thingmd5); - P_MakeBufferMD5((char*)virtsides->data, virtsides->size, sidedefmd5); + // Create a hash for the current map + // get the actual lumps! + virtlump_t* virtlines = vres_Find(virt, "LINEDEFS"); + virtlump_t* virtsectors = vres_Find(virt, "SECTORS"); + virtlump_t* virtmthings = vres_Find(virt, "THINGS"); + virtlump_t* virtsides = vres_Find(virt, "SIDEDEFS"); - for (i = 0; i < 16; i++) - resmd5[i] = (linemd5[i] + sectormd5[i] + thingmd5[i] + sidedefmd5[i]) & 0xFF; + P_MakeBufferMD5((char*)virtlines->data, virtlines->size, linemd5); + P_MakeBufferMD5((char*)virtsectors->data, virtsectors->size, sectormd5); + P_MakeBufferMD5((char*)virtmthings->data, virtmthings->size, thingmd5); + P_MakeBufferMD5((char*)virtsides->data, virtsides->size, sidedefmd5); + + for (i = 0; i < 16; i++) + resmd5[i] = (linemd5[i] + sectormd5[i] + thingmd5[i] + sidedefmd5[i]) & 0xFF; + } M_Memcpy(dest, &resmd5, 16); } From 493c6c8ae2e725870ceded26f97ed5b936ff4bea Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 30 Dec 2019 12:23:31 +0100 Subject: [PATCH 29/70] AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --- src/w_wad.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index 47c3f42d0..62992441a 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1942,8 +1942,6 @@ void vres_Free(virtres_t* vres) Z_Free(vres->vlumps[vres->numlumps].data); Z_Free(vres->vlumps); Z_Free(vres); - - CONS_Printf("A A A\n"); } /** (Debug) Prints lumps from a virtual resource into console. From f9aabe753e76bb028746251b7ab867b297285c23 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 30 Dec 2019 12:31:55 +0100 Subject: [PATCH 30/70] Refactor TextmapFixFlatOffsets(). --- src/p_setup.c | 53 +++++++++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 198b8ae6a..2334a9a03 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1523,6 +1523,7 @@ static void P_LoadTextmap (void) TextmapParse(sectorsPos[i], i, TextmapSector); P_InitializeSector(sc); + TextmapFixFlatOffsets(sc); } for (i = 0, ld = lines; i < numlines; i++, ld++) @@ -1563,37 +1564,30 @@ static void P_LoadTextmap (void) /** Provides a fix to the flat alignment coordinate transform from standard Textmaps. */ -static void TextmapFixFlatOffsets (void) +static void TextmapFixFlatOffsets (sector_t* sec) { - fixed_t pc, ps; - fixed_t xoffs, yoffs; - size_t i; - sector_t* sec = sectors; - for (i = 0; i < numsectors; i++, sec++) + if (sec->floorpic_angle) { - if (sec->floorpic_angle) - { - pc = FINECOSINE(sec->floorpic_angle>>ANGLETOFINESHIFT); - ps = FINESINE (sec->floorpic_angle>>ANGLETOFINESHIFT); - xoffs = sec->floor_xoffs; - yoffs = sec->floor_yoffs; - #define MAXFLATSIZE (2048<floor_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); - sec->floor_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); - #undef MAXFLATSIZE - } + fixed_t pc = FINECOSINE(sec->floorpic_angle>>ANGLETOFINESHIFT); + fixed_t ps = FINESINE (sec->floorpic_angle>>ANGLETOFINESHIFT); + fixed_t xoffs = sec->floor_xoffs; + fixed_t yoffs = sec->floor_yoffs; + #define MAXFLATSIZE (2048<floor_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); + sec->floor_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); + #undef MAXFLATSIZE + } - if (sec->ceilingpic_angle) - { - pc = FINECOSINE(sec->ceilingpic_angle>>ANGLETOFINESHIFT); - ps = FINESINE (sec->ceilingpic_angle>>ANGLETOFINESHIFT); - xoffs = sec->ceiling_xoffs; - yoffs = sec->ceiling_yoffs; - #define MAXFLATSIZE (2048<ceiling_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); - sec->ceiling_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); - #undef MAXFLATSIZE - } + if (sec->ceilingpic_angle) + { + fixed_t pc = FINECOSINE(sec->ceilingpic_angle>>ANGLETOFINESHIFT); + fixed_t ps = FINESINE (sec->ceilingpic_angle>>ANGLETOFINESHIFT); + fixed_t xoffs = sec->ceiling_xoffs; + fixed_t yoffs = sec->ceiling_yoffs; + #define MAXFLATSIZE (2048<ceiling_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); + sec->ceiling_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); + #undef MAXFLATSIZE } } @@ -1666,10 +1660,7 @@ static void P_LoadMapData(const virtres_t *virt) // Load map data. if (textmap) - { P_LoadTextmap(); - TextmapFixFlatOffsets(); - } else { P_LoadVertices(virtvertexes->data); From e43df2993fd06e7e3acefdb58a08a8f47b7b4e68 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 30 Dec 2019 12:33:24 +0100 Subject: [PATCH 31/70] Move TextmapFixFlatOffsets() above P_LoadTextmap() so that it can compile. --- src/p_setup.c | 58 +++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 2334a9a03..09ef07c1a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1478,6 +1478,35 @@ static void TextmapParse(UINT32 dataPos, size_t num, void (*parser)(UINT32, char Z_Free(open); } +/** Provides a fix to the flat alignment coordinate transform from standard Textmaps. + */ +static void TextmapFixFlatOffsets (sector_t* sec) +{ + if (sec->floorpic_angle) + { + fixed_t pc = FINECOSINE(sec->floorpic_angle>>ANGLETOFINESHIFT); + fixed_t ps = FINESINE (sec->floorpic_angle>>ANGLETOFINESHIFT); + fixed_t xoffs = sec->floor_xoffs; + fixed_t yoffs = sec->floor_yoffs; + #define MAXFLATSIZE (2048<floor_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); + sec->floor_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); + #undef MAXFLATSIZE + } + + if (sec->ceilingpic_angle) + { + fixed_t pc = FINECOSINE(sec->ceilingpic_angle>>ANGLETOFINESHIFT); + fixed_t ps = FINESINE (sec->ceilingpic_angle>>ANGLETOFINESHIFT); + fixed_t xoffs = sec->ceiling_xoffs; + fixed_t yoffs = sec->ceiling_yoffs; + #define MAXFLATSIZE (2048<ceiling_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); + sec->ceiling_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); + #undef MAXFLATSIZE + } +} + /** Loads the textmap data, after obtaining the elements count and allocating their respective space. */ static void P_LoadTextmap (void) @@ -1562,35 +1591,6 @@ static void P_LoadTextmap (void) } } -/** Provides a fix to the flat alignment coordinate transform from standard Textmaps. - */ -static void TextmapFixFlatOffsets (sector_t* sec) -{ - if (sec->floorpic_angle) - { - fixed_t pc = FINECOSINE(sec->floorpic_angle>>ANGLETOFINESHIFT); - fixed_t ps = FINESINE (sec->floorpic_angle>>ANGLETOFINESHIFT); - fixed_t xoffs = sec->floor_xoffs; - fixed_t yoffs = sec->floor_yoffs; - #define MAXFLATSIZE (2048<floor_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); - sec->floor_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); - #undef MAXFLATSIZE - } - - if (sec->ceilingpic_angle) - { - fixed_t pc = FINECOSINE(sec->ceilingpic_angle>>ANGLETOFINESHIFT); - fixed_t ps = FINESINE (sec->ceilingpic_angle>>ANGLETOFINESHIFT); - fixed_t xoffs = sec->ceiling_xoffs; - fixed_t yoffs = sec->ceiling_yoffs; - #define MAXFLATSIZE (2048<ceiling_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); - sec->ceiling_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); - #undef MAXFLATSIZE - } -} - static void P_LoadMapData(const virtres_t *virt) { virtlump_t* virtvertexes = NULL, * virtsectors = NULL, * virtsidedefs = NULL, * virtlinedefs = NULL, * virtthings = NULL; From 4aee4e3684ce3f70e6a6e60fc427eb998ddb0b9c Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 30 Dec 2019 13:27:05 +0100 Subject: [PATCH 32/70] Refactor TextmapCount --- src/p_setup.c | 107 +++++++++++++++++++++++++------------------------- 1 file changed, 53 insertions(+), 54 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 09ef07c1a..ccb528687 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1245,63 +1245,71 @@ UINT32 sidesPos[UINT16_MAX]; UINT32 vertexesPos[UINT16_MAX]; UINT32 sectorsPos[UINT16_MAX]; -static boolean TextmapCount (UINT8 *data, size_t size) +// Determine total amount of map data in TEXTMAP. +static boolean TextmapCount(UINT8 *data, size_t size) { - char *nsp1 = M_GetToken((char *)data); - boolean ret = true; + char *tkn = M_GetToken((char *)data); + + nummapthings = 0; + numlines = 0; + numsides = 0; + numvertexes = 0; + numsectors = 0; - // Determine total amount of map data in TEXTMAP. // Look for namespace at the beginning. - if (fastcmp(nsp1, "namespace")) + if (!fastcmp(tkn, "namespace")) { - char *nsp2 = M_GetToken(NULL); - char *tkn = M_GetToken(NULL); + Z_Free(tkn); + CONS_Alert(CONS_WARNING, "No namespace at beginning of lump!\n"); + return false; + } + Z_Free(tkn); - // Check if namespace is valid. - if (!fastcmp(nsp2, "srb2")) - CONS_Alert(CONS_WARNING, "Invalid namespace '%s', only 'srb2' is supported.\n", nsp2); - Z_Free(nsp2); + // Check if namespace is valid. + tkn = M_GetToken(NULL); + if (!fastcmp(tkn, "srb2")) + CONS_Alert(CONS_WARNING, "Invalid namespace '%s', only 'srb2' is supported.\n", tkn); + Z_Free(tkn); - while (tkn != NULL && M_GetTokenPos() < size) + tkn = M_GetToken(NULL); + while (tkn && M_GetTokenPos() < size) + { + // Avoid anything inside bracketed stuff, only look for external keywords. + // Assuming there's only one level of bracket nesting. + if (fastcmp(tkn, "{")) { - // Avoid anything inside bracketed stuff, only look for external keywords. - // Assuming there's only one level of bracket nesting. - if (fastcmp(tkn, "{")) + do { Z_Free(tkn); tkn = M_GetToken(NULL); - while (!fastcmp(tkn, "}")) + if (!tkn || M_GetTokenPos() >= size) { Z_Free(tkn); - tkn = M_GetToken(NULL); + CONS_Alert(CONS_WARNING, "Opening bracket not closed!\n"); + return false; } - } - // Check for valid fields. - else if (fastcmp(tkn, "thing")) - mapthingsPos[nummapthings++] = M_GetTokenPos(); - else if (fastcmp(tkn, "linedef")) - linesPos[numlines++] = M_GetTokenPos(); - else if (fastcmp(tkn, "sidedef")) - sidesPos[numsides++] = M_GetTokenPos(); - else if (fastcmp(tkn, "vertex")) - vertexesPos[numvertexes++] = M_GetTokenPos(); - else if (fastcmp(tkn, "sector")) - sectorsPos[numsectors++] = M_GetTokenPos(); - else - CONS_Alert(CONS_NOTICE, "Unknown field '%s'.\n", tkn); - - Z_Free(tkn); - tkn = M_GetToken(NULL); + } while (!fastcmp(tkn, "}")); } - } - else - { - CONS_Alert(CONS_WARNING, "No namespace at beginning of lump!\n"); - ret = false; + // Check for valid fields. + else if (fastcmp(tkn, "thing")) + mapthingsPos[nummapthings++] = M_GetTokenPos(); + else if (fastcmp(tkn, "linedef")) + linesPos[numlines++] = M_GetTokenPos(); + else if (fastcmp(tkn, "sidedef")) + sidesPos[numsides++] = M_GetTokenPos(); + else if (fastcmp(tkn, "vertex")) + vertexesPos[numvertexes++] = M_GetTokenPos(); + else if (fastcmp(tkn, "sector")) + sectorsPos[numsectors++] = M_GetTokenPos(); + else + CONS_Alert(CONS_NOTICE, "Unknown field '%s'.\n", tkn); + + Z_Free(tkn); + tkn = M_GetToken(NULL); } - Z_Free(nsp1); - return ret; + Z_Free(tkn); + return true; } static char* dat; @@ -1593,21 +1601,12 @@ static void P_LoadTextmap (void) static void P_LoadMapData(const virtres_t *virt) { - virtlump_t* virtvertexes = NULL, * virtsectors = NULL, * virtsidedefs = NULL, * virtlinedefs = NULL, * virtthings = NULL; - virtlump_t* textmap = vres_Find(virt, "TEXTMAP"); + virtlump_t *virtvertexes = NULL, *virtsectors = NULL, *virtsidedefs = NULL, *virtlinedefs = NULL, *virtthings = NULL; + virtlump_t *textmap = vres_Find(virt, "TEXTMAP"); // Count map data. - if (textmap) - { - nummapthings = 0; - numlines = 0; - numsides = 0; - numvertexes = 0; - numsectors = 0; - - // Count how many entries for each type we got in textmap. + if (textmap) // Count how many entries for each type we got in textmap. TextmapCount(textmap->data, textmap->size); - } else { virtthings = vres_Find(virt, "THINGS"); @@ -2659,7 +2658,7 @@ static INT32 P_MakeBufferMD5(const char *buffer, size_t len, void *resblock) static void P_MakeMapMD5(virtres_t *virt, void *dest) { - virtlump_t* textmap = vres_Find(virt, "TEXTMAP"); + virtlump_t *textmap = vres_Find(virt, "TEXTMAP"); unsigned char resmd5[16]; if (textmap) From c6c00aa7d5e5ba923b28c3fa8ad53fb5eed501ad Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 30 Dec 2019 13:38:52 +0100 Subject: [PATCH 33/70] Tweak TextmapCount()'s bracket detection to account for multiple levels, if that ever happens. --- src/p_setup.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index ccb528687..55f0b4f3e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1249,6 +1249,7 @@ UINT32 sectorsPos[UINT16_MAX]; static boolean TextmapCount(UINT8 *data, size_t size) { char *tkn = M_GetToken((char *)data); + UINT8 brackets = 0; nummapthings = 0; numlines = 0; @@ -1275,21 +1276,13 @@ static boolean TextmapCount(UINT8 *data, size_t size) while (tkn && M_GetTokenPos() < size) { // Avoid anything inside bracketed stuff, only look for external keywords. - // Assuming there's only one level of bracket nesting. - if (fastcmp(tkn, "{")) + if (brackets) { - do - { - Z_Free(tkn); - tkn = M_GetToken(NULL); - if (!tkn || M_GetTokenPos() >= size) - { - Z_Free(tkn); - CONS_Alert(CONS_WARNING, "Opening bracket not closed!\n"); - return false; - } - } while (!fastcmp(tkn, "}")); + if (fastcmp(tkn, "}")) + brackets--; } + else if (fastcmp(tkn, "{")) + brackets++; // Check for valid fields. else if (fastcmp(tkn, "thing")) mapthingsPos[nummapthings++] = M_GetTokenPos(); From ea87af007678a8ca516437b4bd713d9242240eaa Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 30 Dec 2019 14:33:41 +0100 Subject: [PATCH 34/70] Refactor TextmapParse --- src/p_setup.c | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 55f0b4f3e..16cb785ab 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1455,33 +1455,35 @@ static void TextmapThing(UINT32 i, char *param) */ static void TextmapParse(UINT32 dataPos, size_t num, void (*parser)(UINT32, char *)) { - char *open; + char *tkn; M_SetTokenPos(dataPos); - open = M_GetToken(NULL); - if (fastcmp(open, "{")) + tkn = M_GetToken(NULL); + if (!fastcmp(tkn, "{")) { - char *tkn = M_GetToken(NULL); - while (!fastcmp(tkn, "}")) - { - dat = NULL; - parser(num, tkn); - if (dat) - Z_Free(dat); - - Z_Free(tkn); - tkn = M_GetToken(NULL); - } Z_Free(tkn); - } - else CONS_Alert(CONS_WARNING, "Invalid UDMF data capsule!\n"); - Z_Free(open); + return; + } + + Z_Free(tkn); + tkn = M_GetToken(NULL); + while (!fastcmp(tkn, "}")) + { + dat = NULL; + parser(num, tkn); + if (dat) + Z_Free(dat); + + Z_Free(tkn); + tkn = M_GetToken(NULL); + } + Z_Free(tkn); } /** Provides a fix to the flat alignment coordinate transform from standard Textmaps. */ -static void TextmapFixFlatOffsets (sector_t* sec) +static void TextmapFixFlatOffsets(sector_t *sec) { if (sec->floorpic_angle) { @@ -1510,7 +1512,7 @@ static void TextmapFixFlatOffsets (sector_t* sec) /** Loads the textmap data, after obtaining the elements count and allocating their respective space. */ -static void P_LoadTextmap (void) +static void P_LoadTextmap(void) { UINT32 i; From 7ae2143c9102c798c7db9d2583aadbc3b77f2631 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 30 Dec 2019 14:42:41 +0100 Subject: [PATCH 35/70] Add a disclaimer when loading textmaps/UDMF. --- src/p_setup.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_setup.c b/src/p_setup.c index 55f0b4f3e..839e583c8 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1520,6 +1520,8 @@ static void P_LoadTextmap (void) side_t *sd; mapthing_t *mt; + CONS_Alert(CONS_NOTICE, "UDMF support is still a work-in-progress; its specs and features are prone to change until it is fully implemented.\n"); + /// Given the UDMF specs, some fields are given a default value. /// If an element's field has a default value set, it is ommited /// from the textmap, and therefore we have to account for it by From f9d6e26558aa6fd4439edfcb5380691b0074c495 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 30 Dec 2019 14:45:39 +0100 Subject: [PATCH 36/70] Replace INT16_MAX with LUMPERROR in lump check. --- src/p_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index 839e583c8..73c3b44f6 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3536,7 +3536,7 @@ boolean P_LoadLevel(boolean fromnetsave) // internal game map maplumpname = G_BuildMapName(gamemap); lastloadedmaplumpnum = W_CheckNumForName(maplumpname); - if (lastloadedmaplumpnum == INT16_MAX) + if (lastloadedmaplumpnum == LUMPERROR) I_Error("Map %s not found.\n", maplumpname); R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette); From 4a5498473c3ff07feb45006943e59ec0b504282a Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 30 Dec 2019 14:47:48 +0100 Subject: [PATCH 37/70] Make P_LoadMapData() a return a boolean as well as P_LoadMapFromFile(); if they fail to load, they return false, and thus P_SetupLevel() will also return false. TextmapCount() also now returns false if brackets are left open inside a textmap. --- src/p_setup.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 73c3b44f6..f9ca4dcf0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1261,7 +1261,7 @@ static boolean TextmapCount(UINT8 *data, size_t size) if (!fastcmp(tkn, "namespace")) { Z_Free(tkn); - CONS_Alert(CONS_WARNING, "No namespace at beginning of lump!\n"); + CONS_Alert(CONS_ERROR, "No namespace at beginning of lump!\n"); return false; } Z_Free(tkn); @@ -1302,6 +1302,13 @@ static boolean TextmapCount(UINT8 *data, size_t size) } Z_Free(tkn); + + if (brackets) + { + CONS_Alert(CONS_ERROR, "Unclosed brackets detected in textmap lump.\n"); + return false; + } + return true; } @@ -1594,14 +1601,17 @@ static void P_LoadTextmap (void) } } -static void P_LoadMapData(const virtres_t *virt) +static boolean P_LoadMapData(const virtres_t *virt) { virtlump_t *virtvertexes = NULL, *virtsectors = NULL, *virtsidedefs = NULL, *virtlinedefs = NULL, *virtthings = NULL; virtlump_t *textmap = vres_Find(virt, "TEXTMAP"); // Count map data. if (textmap) // Count how many entries for each type we got in textmap. - TextmapCount(textmap->data, textmap->size); + { + if (!TextmapCount(textmap->data, textmap->size)) + return false; + } else { virtthings = vres_Find(virt, "THINGS"); @@ -1684,6 +1694,8 @@ static void P_LoadMapData(const virtres_t *virt) memcpy(spawnsectors, sectors, numsectors * sizeof (*sectors)); memcpy(spawnlines, lines, numlines * sizeof (*lines)); memcpy(spawnsides, sides, numsides * sizeof (*sides)); + + return true; } static void P_InitializeSubsector(subsector_t *ss) @@ -2685,11 +2697,12 @@ static void P_MakeMapMD5(virtres_t *virt, void *dest) M_Memcpy(dest, &resmd5, 16); } -static void P_LoadMapFromFile(void) +static boolean P_LoadMapFromFile(void) { virtres_t *virt = vres_GetMap(lastloadedmaplumpnum); - P_LoadMapData(virt); + if (!P_LoadMapData(virt)) + return false; P_LoadMapBSP(virt); P_LoadMapLUT(virt); @@ -2701,6 +2714,7 @@ static void P_LoadMapFromFile(void) P_MakeMapMD5(virt, &mapmd5); vres_Free(virt); + return true; } // @@ -3549,8 +3563,8 @@ boolean P_LoadLevel(boolean fromnetsave) P_MapStart(); - if (lastloadedmaplumpnum) - P_LoadMapFromFile(); + if (!P_LoadMapFromFile()) + return false; // init gravity, tag lists, // anything that P_ResetDynamicSlopes/P_LoadThings needs to know From 72bb67320969b17d116c18392a2781751d19af58 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 30 Dec 2019 16:28:22 +0100 Subject: [PATCH 38/70] Some minor refactoring of textmap loading code --- src/p_setup.c | 54 +++++++++++++++------------------------------------ 1 file changed, 16 insertions(+), 38 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 78792f306..4d4eaff6d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1314,12 +1314,7 @@ static boolean TextmapCount(UINT8 *data, size_t size) static char* dat; -/** Auxiliary function for TextmapParse. - * - * \param Vertex number. - * \param Parameter string. - */ -static void TextmapVertex(UINT32 i, char *param) +static void ParseTextmapVertexParameter(UINT32 i, char *param) { if (fastcmp(param, "x")) vertexes[i].x = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); @@ -1327,12 +1322,7 @@ static void TextmapVertex(UINT32 i, char *param) vertexes[i].y = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); } -/** Auxiliary function for TextmapParse. - * - * \param Sector number. - * \param Parameter string. - */ -static void TextmapSector(UINT32 i, char *param) +static void ParseTextmapSectorParameter(UINT32 i, char *param) { if (fastcmp(param, "heightfloor")) sectors[i].floorheight = atol(dat = M_GetToken(NULL)) << FRACBITS; @@ -1350,12 +1340,7 @@ static void TextmapSector(UINT32 i, char *param) sectors[i].tag = atol(dat = M_GetToken(NULL)); } -/** Auxiliary function for TextmapParse. - * - * \param Side number. - * \param Parameter string. - */ -static void TextmapSide(UINT32 i, char *param) +static void ParseTextmapSidedefParameter(UINT32 i, char *param) { if (fastcmp(param, "offsetx")) sides[i].textureoffset = atol(dat = M_GetToken(NULL))<floorpic_angle>>ANGLETOFINESHIFT); fixed_t xoffs = sec->floor_xoffs; fixed_t yoffs = sec->floor_yoffs; - #define MAXFLATSIZE (2048<floor_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); sec->floor_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); - #undef MAXFLATSIZE } if (sec->ceilingpic_angle) @@ -1510,13 +1488,13 @@ static void TextmapFixFlatOffsets(sector_t *sec) fixed_t ps = FINESINE (sec->ceilingpic_angle>>ANGLETOFINESHIFT); fixed_t xoffs = sec->ceiling_xoffs; fixed_t yoffs = sec->ceiling_yoffs; - #define MAXFLATSIZE (2048<ceiling_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); sec->ceiling_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); - #undef MAXFLATSIZE } } +#undef MAXFLATSIZE + /** Loads the textmap data, after obtaining the elements count and allocating their respective space. */ static void P_LoadTextmap(void) @@ -1532,7 +1510,7 @@ static void P_LoadTextmap(void) CONS_Alert(CONS_NOTICE, "UDMF support is still a work-in-progress; its specs and features are prone to change until it is fully implemented.\n"); /// Given the UDMF specs, some fields are given a default value. - /// If an element's field has a default value set, it is ommited + /// If an element's field has a default value set, it is omitted /// from the textmap, and therefore we have to account for it by /// preemptively setting that value beforehand. @@ -1541,7 +1519,7 @@ static void P_LoadTextmap(void) // Defaults. vt->z = 0; - TextmapParse(vertexesPos[i], i, TextmapVertex); + TextmapParse(vertexesPos[i], i, ParseTextmapVertexParameter); } for (i = 0, sc = sectors; i < numsectors; i++, sc++) @@ -1561,7 +1539,7 @@ static void P_LoadTextmap(void) sc->floor_xoffs = sc->floor_yoffs = sc->ceiling_xoffs = sc->ceiling_yoffs = 0; sc->floorpic_angle = sc->ceilingpic_angle = 0; - TextmapParse(sectorsPos[i], i, TextmapSector); + TextmapParse(sectorsPos[i], i, ParseTextmapSectorParameter); P_InitializeSector(sc); TextmapFixFlatOffsets(sc); @@ -1574,7 +1552,7 @@ static void P_LoadTextmap(void) ld->special = 0; ld->sidenum[1] = 0xffff; - TextmapParse(linesPos[i], i, TextmapLine); + TextmapParse(linesPos[i], i, ParseTextmapLinedefParameter); P_InitializeLinedef(ld); } @@ -1590,7 +1568,7 @@ static void P_LoadTextmap(void) sd->bottomtexture = R_TextureNumForName("-"); sd->repeatcnt = 0; - TextmapParse(sidesPos[i], i, TextmapSide); + TextmapParse(sidesPos[i], i, ParseTextmapSidedefParameter); } for (i = 0, mt = mapthings; i < nummapthings; i++, mt++) @@ -1599,7 +1577,7 @@ static void P_LoadTextmap(void) mt->z = 0; mt->angle = 0; - TextmapParse(mapthingsPos[i], i, TextmapThing); + TextmapParse(mapthingsPos[i], i, ParseTextmapThingParameter); } } From 05a97530c18a5f8e87fc47d27187b6a3a3542eb5 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 30 Dec 2019 17:28:10 +0100 Subject: [PATCH 39/70] Add support for flat offset and rotation fields in UDMF --- src/p_setup.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 4d4eaff6d..e4b73570f 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1338,6 +1338,18 @@ static void ParseTextmapSectorParameter(UINT32 i, char *param) sectors[i].special = atol(dat = M_GetToken(NULL)); else if (fastcmp(param, "id")) sectors[i].tag = atol(dat = M_GetToken(NULL)); + else if (fastcmp(param, "xpanningfloor")) + sectors[i].floor_xoffs = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + else if (fastcmp(param, "ypanningfloor")) + sectors[i].floor_yoffs = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + else if (fastcmp(param, "xpanningceiling")) + sectors[i].ceiling_xoffs = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + else if (fastcmp(param, "ypanningceiling")) + sectors[i].ceiling_yoffs = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + else if (fastcmp(param, "rotationfloor")) + sectors[i].floorpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL)))); + else if (fastcmp(param, "rotationceiling")) + sectors[i].ceilingpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL)))); } static void ParseTextmapSidedefParameter(UINT32 i, char *param) @@ -1536,12 +1548,8 @@ static void P_LoadTextmap(void) sc->special = 0; sc->tag = 0; - sc->floor_xoffs = sc->floor_yoffs = sc->ceiling_xoffs = sc->ceiling_yoffs = 0; - sc->floorpic_angle = sc->ceilingpic_angle = 0; - - TextmapParse(sectorsPos[i], i, ParseTextmapSectorParameter); - P_InitializeSector(sc); + TextmapParse(sectorsPos[i], i, ParseTextmapSectorParameter); TextmapFixFlatOffsets(sc); } From 013f1f70d91dff68e496e481357dfa1d9f9b426f Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 30 Dec 2019 21:23:00 +0100 Subject: [PATCH 40/70] -Set defaults for vertex and mapthing fields in textmap -Fix P_InitializeSector being called too early (band-aid fix for now, will reorganize this properly later) --- src/p_setup.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index e4b73570f..a48cfe909 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -865,11 +865,6 @@ static void P_InitializeSector(sector_t *ss) ss->lightingdata = NULL; ss->fadecolormapdata = NULL; - ss->floor_xoffs = ss->floor_yoffs = 0; - ss->ceiling_xoffs = ss->ceiling_yoffs = 0; - - ss->floorpic_angle = ss->ceilingpic_angle = 0; - ss->heightsec = -1; ss->camsec = -1; @@ -945,6 +940,11 @@ static void P_LoadSectors(UINT8 *data) ss->special = SHORT(ms->special); ss->tag = SHORT(ms->tag); + ss->floor_xoffs = ss->floor_yoffs = 0; + ss->ceiling_xoffs = ss->ceiling_yoffs = 0; + + ss->floorpic_angle = ss->ceilingpic_angle = 0; + P_InitializeSector(ss); } } @@ -1235,6 +1235,8 @@ static void P_LoadThings(UINT8 *data) mt->z = mt->options; // NiGHTS Hoops use the full flags bits to set the height. else mt->z = mt->options >> ZSHIFT; + + mt->mobj = NULL; } } @@ -1529,7 +1531,7 @@ static void P_LoadTextmap(void) for (i = 0, vt = vertexes; i < numvertexes; i++, vt++) { // Defaults. - vt->z = 0; + vt->x = vt->y = vt->z = 0; TextmapParse(vertexesPos[i], i, ParseTextmapVertexParameter); } @@ -1548,8 +1550,13 @@ static void P_LoadTextmap(void) sc->special = 0; sc->tag = 0; - P_InitializeSector(sc); + sc->floor_xoffs = sc->floor_yoffs = 0; + sc->ceiling_xoffs = sc->ceiling_yoffs = 0; + + sc->floorpic_angle = sc->ceilingpic_angle = 0; + TextmapParse(sectorsPos[i], i, ParseTextmapSectorParameter); + P_InitializeSector(sc); TextmapFixFlatOffsets(sc); } @@ -1582,8 +1589,13 @@ static void P_LoadTextmap(void) for (i = 0, mt = mapthings; i < nummapthings; i++, mt++) { // Defaults. - mt->z = 0; + mt->x = mt->y = 0; mt->angle = 0; + mt->type = 0; + mt->options = 0; + mt->z = 0; + mt->extrainfo = 0; + mt->mobj = NULL; TextmapParse(mapthingsPos[i], i, ParseTextmapThingParameter); } From 47b096a35748cc0ef20819daabdf561c011c9c25 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 31 Dec 2019 00:38:09 -0300 Subject: [PATCH 41/70] Disable Minecart Spawners for players already riding a minecart --- src/p_inter.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 70fb01fd0..4804905f5 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1807,23 +1807,27 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; case MT_MINECARTSPAWNER: - if (!player->bot && (special->fuse < TICRATE || player->powers[pw_carry] != CR_MINECART)) - { - mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); - P_SetTarget(&mcart->target, toucher); - mcart->angle = toucher->angle = player->drawangle = special->angle; - mcart->friction = FRACUNIT; + if (player->bot) + return; + if (special->fuse > TICRATE) + return; + if (player->powers[pw_carry] == CR_MINECART) + return; + + mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); + P_SetTarget(&mcart->target, toucher); + mcart->angle = toucher->angle = player->drawangle = special->angle; + mcart->friction = FRACUNIT; - P_ResetPlayer(player); - player->pflags |= PF_JUMPDOWN; - player->powers[pw_carry] = CR_MINECART; - player->pflags &= ~PF_APPLYAUTOBRAKE; - P_SetTarget(&toucher->tracer, mcart); - toucher->momx = toucher->momy = toucher->momz = 0; + P_ResetPlayer(player); + player->pflags |= PF_JUMPDOWN; + player->powers[pw_carry] = CR_MINECART; + player->pflags &= ~PF_APPLYAUTOBRAKE; + P_SetTarget(&toucher->tracer, mcart); + toucher->momx = toucher->momy = toucher->momz = 0; - special->fuse = 3*TICRATE; - special->flags2 |= MF2_DONTDRAW; - } + special->fuse = 3*TICRATE; + special->flags2 |= MF2_DONTDRAW; return; case MT_MINECARTEND: From 2d0cdbe34f5cdccc1395df84a66085f4b7e6bbe2 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 31 Dec 2019 01:20:11 -0300 Subject: [PATCH 42/70] Appease the C90 entity --- src/p_inter.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 4804905f5..b28b98758 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1813,21 +1813,23 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; if (player->powers[pw_carry] == CR_MINECART) return; - - mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); - P_SetTarget(&mcart->target, toucher); - mcart->angle = toucher->angle = player->drawangle = special->angle; - mcart->friction = FRACUNIT; + else + { + mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); + P_SetTarget(&mcart->target, toucher); + mcart->angle = toucher->angle = player->drawangle = special->angle; + mcart->friction = FRACUNIT; - P_ResetPlayer(player); - player->pflags |= PF_JUMPDOWN; - player->powers[pw_carry] = CR_MINECART; - player->pflags &= ~PF_APPLYAUTOBRAKE; - P_SetTarget(&toucher->tracer, mcart); - toucher->momx = toucher->momy = toucher->momz = 0; + P_ResetPlayer(player); + player->pflags |= PF_JUMPDOWN; + player->powers[pw_carry] = CR_MINECART; + player->pflags &= ~PF_APPLYAUTOBRAKE; + P_SetTarget(&toucher->tracer, mcart); + toucher->momx = toucher->momy = toucher->momz = 0; - special->fuse = 3*TICRATE; - special->flags2 |= MF2_DONTDRAW; + special->fuse = 3*TICRATE; + special->flags2 |= MF2_DONTDRAW; + } return; case MT_MINECARTEND: From b68a629a7118cfeb39caea8c10443933c16dcd7e Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 31 Dec 2019 01:48:50 -0300 Subject: [PATCH 43/70] Small --- src/p_inter.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index b28b98758..67d5a8a3f 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1807,13 +1807,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; case MT_MINECARTSPAWNER: - if (player->bot) - return; - if (special->fuse > TICRATE) - return; - if (player->powers[pw_carry] == CR_MINECART) - return; - else + if (!player->bot && special->fuse <= TICRATE && player->powers[pw_carry] != CR_MINECART) { mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); P_SetTarget(&mcart->target, toucher); From 281f30c4fd8f6ae2630df8570d81a6780666a714 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 22:18:55 -0800 Subject: [PATCH 44/70] Replace gametype with gametypename in SERVERINFO PACKETVERSION 1 --- src/d_clisrv.c | 14 +++++++------- src/d_clisrv.h | 4 ++-- src/m_menu.c | 18 ++++++++++++------ 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index af2be129f..302294557 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1293,7 +1293,8 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers(); netbuffer->u.serverinfo.maxplayer = (UINT8)cv_maxplayers.value; - netbuffer->u.serverinfo.gametype = (UINT8)gametype; + strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[gametype], + sizeof netbuffer->u.serverinfo.gametypename); netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame; netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled(); netbuffer->u.serverinfo.isdedicated = (UINT8)dedicated; @@ -2122,13 +2123,10 @@ static void CL_ConnectToServer(boolean viams) if (i != -1) { - UINT16 num = serverlist[i].info.gametype; - const char *gametypestr = NULL; + char *gametypestr = serverlist[i].info.gametypename; CONS_Printf(M_GetText("Connecting to: %s\n"), serverlist[i].info.servername); - if (num < gametypecount) - gametypestr = Gametype_Names[num]; - if (gametypestr) - CONS_Printf(M_GetText("Gametype: %s\n"), gametypestr); + gametypestr[sizeof serverlist[i].info.gametypename - 1] = '\0'; + CONS_Printf(M_GetText("Gametype: %s\n"), gametypestr); CONS_Printf(M_GetText("Version: %d.%d.%u\n"), serverlist[i].info.version/100, serverlist[i].info.version%100, serverlist[i].info.subversion); } @@ -3656,6 +3654,8 @@ static void HandleServerInfo(SINT8 node) netbuffer->u.serverinfo.servername[MAXSERVERNAME-1] = 0; netbuffer->u.serverinfo.application [sizeof netbuffer->u.serverinfo.application - 1] = '\0'; + netbuffer->u.serverinfo.gametypename + [sizeof netbuffer->u.serverinfo.gametypename - 1] = '\0'; SL_InsertServer(&netbuffer->u.serverinfo, node); } diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 49f8afc76..c797e5ca8 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -27,7 +27,7 @@ This version is independent of the mod name, and standard version and subversion. It should only account for the basic fields of the packet, and change infrequently. */ -#define PACKETVERSION 0 +#define PACKETVERSION 1 // Network play related stuff. // There is a data struct that stores network @@ -361,7 +361,7 @@ typedef struct UINT8 subversion; UINT8 numberofplayer; UINT8 maxplayer; - UINT8 gametype; + char gametypename[24]; UINT8 modifiedgame; UINT8 cheatsenabled; UINT8 isdedicated; diff --git a/src/m_menu.c b/src/m_menu.c index 6ef9a5e19..a199b0ae3 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -9971,7 +9971,7 @@ static void M_DrawRoomMenu(void) static void M_DrawConnectMenu(void) { UINT16 i; - const char *gt = "Unknown"; + char *gt; INT32 numPages = (serverlistcount+(SERVERS_PER_PAGE-1))/SERVERS_PER_PAGE; for (i = FIRSTSERVERLINE; i < min(localservercount, SERVERS_PER_PAGE)+FIRSTSERVERLINE; i++) @@ -10015,9 +10015,7 @@ static void M_DrawConnectMenu(void) V_DrawSmallString(currentMenu->x, S_LINEY(i)+8, globalflags, va("Ping: %u", (UINT32)LONG(serverlist[slindex].info.time))); - gt = "Unknown"; - if (serverlist[slindex].info.gametype < gametypecount) - gt = Gametype_Names[serverlist[slindex].info.gametype]; + gt = serverlist[slindex].info.gametypename; V_DrawSmallString(currentMenu->x+46,S_LINEY(i)+8, globalflags, va("Players: %02d/%02d", serverlist[slindex].info.numberofplayer, serverlist[slindex].info.maxplayer)); @@ -10063,7 +10061,15 @@ SERVER_LIST_ENTRY_COMPARATOR(time) SERVER_LIST_ENTRY_COMPARATOR(numberofplayer) SERVER_LIST_ENTRY_COMPARATOR_REVERSE(numberofplayer) SERVER_LIST_ENTRY_COMPARATOR_REVERSE(maxplayer) -SERVER_LIST_ENTRY_COMPARATOR(gametype) + +static int ServerListEntryComparator_gametypename(const void *entry1, const void *entry2) +{ + const serverelem_t *sa = (const serverelem_t*)entry1, *sb = (const serverelem_t*)entry2; + int c; + if (( c = strcasecmp(sa->info.gametypename, sb->info.gametypename) )) + return c; + return strcmp(sa->info.servername, sb->info.servername); \ +} // Special one for modified state. static int ServerListEntryComparator_modified(const void *entry1, const void *entry2) @@ -10103,7 +10109,7 @@ void M_SortServerList(void) qsort(serverlist, serverlistcount, sizeof(serverelem_t), ServerListEntryComparator_maxplayer_reverse); break; case 5: // Gametype. - qsort(serverlist, serverlistcount, sizeof(serverelem_t), ServerListEntryComparator_gametype); + qsort(serverlist, serverlistcount, sizeof(serverelem_t), ServerListEntryComparator_gametypename); break; } #endif From b4ebb01e2d9d080f66416bb36588c5b377495e41 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 22:23:19 -0800 Subject: [PATCH 45/70] Truncate gametype name in server list if it's too long --- src/m_menu.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index a199b0ae3..282e2fe1b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -10020,7 +10020,12 @@ static void M_DrawConnectMenu(void) V_DrawSmallString(currentMenu->x+46,S_LINEY(i)+8, globalflags, va("Players: %02d/%02d", serverlist[slindex].info.numberofplayer, serverlist[slindex].info.maxplayer)); - V_DrawSmallString(currentMenu->x+112, S_LINEY(i)+8, globalflags, va("Gametype: %s", gt)); + if (strlen(gt) > 11) + gt = va("Gametype: %.11s...", gt); + else + gt = va("Gametype: %s", gt); + + V_DrawSmallString(currentMenu->x+112, S_LINEY(i)+8, globalflags, gt); MP_ConnectMenu[i+FIRSTSERVERLINE].status = IT_STRING | IT_CALL; } From d3c56cd80754ea289c0c9ce6f25179388e05656a Mon Sep 17 00:00:00 2001 From: lachwright Date: Tue, 31 Dec 2019 16:48:29 +0800 Subject: [PATCH 46/70] Remove flight indicator when AI Tails is taken over by second player --- src/b_bot.c | 48 +++++++++++++++++++++++++++--------------------- src/b_bot.h | 1 + src/g_game.c | 1 + 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/b_bot.c b/src/b_bot.c index dfb5ee1cf..dba156b27 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -335,27 +335,6 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) jump_last = jump; spin_last = spin; - // ******** - // Thinkfly overlay - if (thinkfly) - { - if (!tails->hnext) - { - P_SetTarget(&tails->hnext, P_SpawnMobjFromMobj(tails, 0, 0, 0, MT_OVERLAY)); - if (tails->hnext) - { - P_SetTarget(&tails->hnext->target, tails); - P_SetTarget(&tails->hnext->hprev, tails); - P_SetMobjState(tails->hnext, S_FLIGHTINDICATOR); - } - } - } - else if (tails->hnext && tails->hnext->type == MT_OVERLAY && tails->hnext->state == states+S_FLIGHTINDICATOR) - { - P_RemoveMobj(tails->hnext); - P_SetTarget(&tails->hnext, NULL); - } - // Turn the virtual keypresses into ticcmd_t. B_KeysToTiccmd(tails, cmd, forward, backward, left, right, false, false, jump, spin); @@ -565,3 +544,30 @@ void B_RespawnBot(INT32 playernum) P_SetScale(tails, sonic->scale); tails->destscale = sonic->destscale; } + +void B_HandleFlightIndicator(player_t *player) +{ + mobj_t *tails = player->mo + + if (!tails) + return; + + if (thinkfly && player->bot == 1) + { + if (!tails->hnext) + { + P_SetTarget(&tails->hnext, P_SpawnMobjFromMobj(tails, 0, 0, 0, MT_OVERLAY)); + if (tails->hnext) + { + P_SetTarget(&tails->hnext->target, tails); + P_SetTarget(&tails->hnext->hprev, tails); + P_SetMobjState(tails->hnext, S_FLIGHTINDICATOR); + } + } + } + else if (tails->hnext && tails->hnext->type == MT_OVERLAY && tails->hnext->state == states+S_FLIGHTINDICATOR) + { + P_RemoveMobj(tails->hnext); + P_SetTarget(&tails->hnext, NULL); + } +} diff --git a/src/b_bot.h b/src/b_bot.h index b42577c5c..54ef300a3 100644 --- a/src/b_bot.h +++ b/src/b_bot.h @@ -15,3 +15,4 @@ void B_KeysToTiccmd(mobj_t *mo, ticcmd_t *cmd, boolean forward, boolean backward boolean B_CheckRespawn(player_t *player); void B_MoveBlocked(player_t *player); void B_RespawnBot(INT32 playernum); +void B_HandleFlightIndicator(player_t *player); diff --git a/src/g_game.c b/src/g_game.c index 144975177..79ea2c70b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1718,6 +1718,7 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver B_BuildTiccmd(player, cmd); } + B_HandleFlightIndicator(player); } if (cv_analog2.value) { From 1a78b3548c29b1814c48c4538b20f71e8379087b Mon Sep 17 00:00:00 2001 From: lachwright Date: Tue, 31 Dec 2019 16:54:52 +0800 Subject: [PATCH 47/70] Remove flight indicator on death as well --- src/b_bot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/b_bot.c b/src/b_bot.c index dba156b27..64cb00e7e 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -552,7 +552,7 @@ void B_HandleFlightIndicator(player_t *player) if (!tails) return; - if (thinkfly && player->bot == 1) + if (thinkfly && player->bot == 1 && tails->health) { if (!tails->hnext) { From 342d80198c20717863268ae7754f15abbc8b0961 Mon Sep 17 00:00:00 2001 From: lachwright Date: Tue, 31 Dec 2019 16:55:36 +0800 Subject: [PATCH 48/70] Add missed semicolon, oops --- src/b_bot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/b_bot.c b/src/b_bot.c index 64cb00e7e..51dc4d2f2 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -547,7 +547,7 @@ void B_RespawnBot(INT32 playernum) void B_HandleFlightIndicator(player_t *player) { - mobj_t *tails = player->mo + mobj_t *tails = player->mo; if (!tails) return; From 10b71d40b8fb8c3220ef0b1f0e6ff05f718a8ba5 Mon Sep 17 00:00:00 2001 From: lachwright Date: Tue, 31 Dec 2019 17:26:35 +0800 Subject: [PATCH 49/70] Make Metal Sonic's jet fume opaque when re-emerging from water --- src/p_user.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index 02dd77668..bc4589751 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11250,7 +11250,10 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume) if (panim == PA_WALK) { if (stat != fume->info->spawnstate) + { + fume->threshold = 0; P_SetMobjState(fume, fume->info->spawnstate); + } return; } } @@ -11281,6 +11284,12 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume) if (underwater) { fume->frame = (fume->frame & FF_FRAMEMASK) | FF_ANIMATE | (P_RandomRange(0, 9) * FF_TRANS10); + fume->threshold = 1; + } + else if (fume->threshold) + { + fume->frame = (fume->frame & FF_FRAMEMASK) | fume->state->frame; + fume->threshold = 0; } } From e5e96cb2717ca470e969e24f5d576c4f420a8e18 Mon Sep 17 00:00:00 2001 From: lachwright Date: Tue, 31 Dec 2019 18:06:40 +0800 Subject: [PATCH 50/70] Make elemental crop circle flames obey player gravity --- src/p_user.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_user.c b/src/p_user.c index 02dd77668..36bc0a2fc 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7786,6 +7786,7 @@ void P_ElementalFire(player_t *player, boolean cropcircle) flame->fuse = TICRATE*7; // takes about an extra second to hit the ground flame->destscale = player->mo->scale; P_SetScale(flame, player->mo->scale); + flame->flags2 = (flame->flags2 & ~MF2_OBJECTFLIP)|(player->mo->flags2 & MF2_OBJECTFLIP); flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); P_InstaThrust(flame, flame->angle, FixedMul(3*FRACUNIT, flame->scale)); P_SetObjectMomZ(flame, 3*FRACUNIT, false); From 79f18a3c19232c4b6e231adcbb8d38c14f1a6bef Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 31 Dec 2019 11:19:54 -0300 Subject: [PATCH 51/70] Got rid of the uhh --- src/p_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_inter.c b/src/p_inter.c index 67d5a8a3f..ff68cdf69 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1808,7 +1808,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_MINECARTSPAWNER: if (!player->bot && special->fuse <= TICRATE && player->powers[pw_carry] != CR_MINECART) - { + { mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); P_SetTarget(&mcart->target, toucher); mcart->angle = toucher->angle = player->drawangle = special->angle; From cd1cc9a222efee42628976136173f09af7f88357 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 31 Dec 2019 14:00:25 -0300 Subject: [PATCH 52/70] Fix desynch --- src/p_setup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_setup.c b/src/p_setup.c index 5a7a5cb93..366fc5372 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3016,6 +3016,7 @@ boolean P_LoadLevel(boolean fromnetsave) // This is needed. Don't touch. maptol = mapheaderinfo[gamemap-1]->typeoflevel; + gametyperules = gametypedefaultrules[gametype]; CON_Drawer(); // let the user know what we are going to do I_FinishUpdate(); // page flip or blit buffer From 1c048275da96aa07b244e6295485fe4ac0b9d558 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 31 Dec 2019 14:37:45 -0300 Subject: [PATCH 53/70] **NEW!** hook_SeenPlayer --- src/lua_hook.h | 4 ++++ src/lua_hooklib.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++- src/p_map.c | 11 ++++++++--- 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 68efbce93..24e61c20c 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -53,6 +53,7 @@ enum hook { hook_IntermissionThinker, hook_TeamSwitch, hook_ViewpointSwitch, + hook_SeenPlayer, hook_MAX // last hook }; @@ -97,5 +98,8 @@ void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting void LUAh_IntermissionThinker(void); // Hook for Y_Ticker boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble); // Hook for team switching in... uh.... UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced); // Hook for spy mode +#ifdef SEENAMES +boolean LUAh_SeenPlayer(player_t *player, player_t *seenplayer); // Hook for MT_NAMECHECK +#endif #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 91b4c6992..fc9d74f08 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -64,6 +64,7 @@ const char *const hookNames[hook_MAX+1] = { "IntermissionThinker", "TeamSwitch", "ViewpointSwitch", + "SeenPlayer", NULL }; @@ -207,6 +208,7 @@ static int lib_addHook(lua_State *L) case hook_PlayerCanDamage: case hook_TeamSwitch: case hook_ViewpointSwitch: + case hook_SeenPlayer: case hook_ShieldSpawn: case hook_ShieldSpecial: lastp = &playerhooks; @@ -1412,7 +1414,7 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean return 0; lua_settop(gL, 0); - hud_running = true; + hud_running = true; // local hook for (hookp = playerhooks; hookp; hookp = hookp->next) { @@ -1453,4 +1455,49 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean return canSwitchView; } +// Hook for MT_NAMECHECK +#ifdef SEENAMES +boolean LUAh_SeenPlayer(player_t *player, player_t *seenplayer) +{ + hook_p hookp; + boolean hasSeenPlayer = true; + if (!gL || !(hooksAvailable[hook_SeenPlayer/8] & (1<<(hook_SeenPlayer%8)))) + return 0; + + lua_settop(gL, 0); + hud_running = true; // local hook + + for (hookp = playerhooks; hookp; hookp = hookp->next) + { + if (hookp->type != hook_SeenPlayer) + continue; + + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, player, META_PLAYER); + LUA_PushUserdata(gL, seenplayer, META_PLAYER); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -3); + lua_pushvalue(gL, -3); + if (lua_pcall(gL, 2, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (!lua_isnil(gL, -1) && !lua_toboolean(gL, -1)) + hasSeenPlayer = false; // Hasn't seen player + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + hud_running = false; + + return hasSeenPlayer; +} +#endif // SEENAMES + #endif diff --git a/src/p_map.c b/src/p_map.c index 25da9c58d..4a965998e 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -745,9 +745,8 @@ static boolean PIT_CheckThing(mobj_t *thing) // So that NOTHING ELSE can see MT_NAMECHECK because it is client-side. if (tmthing->type == MT_NAMECHECK) { - // Ignore things that aren't players, ignore spectators, ignore yourself. - // (also don't bother to check that tmthing->target->player is non-NULL because we're not actually using it here.) - if (!thing->player || thing->player->spectator || (tmthing->target && thing->player == tmthing->target->player)) + // Ignore things that aren't players, ignore spectators, ignore yourself. + if (!thing->player || !(tmthing->target && tmthing->target->player) || thing->player->spectator || (tmthing->target && thing->player == tmthing->target->player)) return true; // Now check that you actually hit them. @@ -760,6 +759,12 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->z + tmthing->height < thing->z) return true; // underneath +#ifdef HAVE_BLUA + // REX HAS SEEN YOU + if (!LUAh_SeenPlayer(tmthing->target->player, thing->player)) + return false; +#endif + seenplayer = thing->player; return false; } From 6e330348bcc0ec895ca32e70d6d9a1d3c4d4948c Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 31 Dec 2019 19:38:11 -0300 Subject: [PATCH 54/70] Fix MP Special Stages crashing if a player is being carried when it ends --- src/p_user.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index ea42a2c36..292bad2af 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -347,6 +347,11 @@ void P_GiveEmerald(boolean spawnObj) continue; P_SetTarget(&emmo->target, players[i].mo); P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); + + // Make sure we're not being carried before our tracer is changed + if (players[i].powers[pw_carry] != CR_NONE) + players[i].powers[pw_carry] = CR_NONE; + P_SetTarget(&players[i].mo->tracer, emmo); if (pnum == 255) From 83467a7b3d584b72329e57d23638e61f6019bbbb Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 31 Dec 2019 20:13:16 -0300 Subject: [PATCH 55/70] The dumbass forgot NiGHTS mode is also a carry power --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 292bad2af..f8d1dbbc1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -349,7 +349,7 @@ void P_GiveEmerald(boolean spawnObj) P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); // Make sure we're not being carried before our tracer is changed - if (players[i].powers[pw_carry] != CR_NONE) + if (players[i].powers[pw_carry] == CR_PLAYER) players[i].powers[pw_carry] = CR_NONE; P_SetTarget(&players[i].mo->tracer, emmo); From caf47019cee70fabab2530969fcabf5c41c05ee5 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 31 Dec 2019 20:20:30 -0300 Subject: [PATCH 56/70] Or is it better like this? --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index f8d1dbbc1..586c8b022 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -349,7 +349,7 @@ void P_GiveEmerald(boolean spawnObj) P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); // Make sure we're not being carried before our tracer is changed - if (players[i].powers[pw_carry] == CR_PLAYER) + if (players[i].powers[pw_carry] != CR_NIGHTSMODE) players[i].powers[pw_carry] = CR_NONE; P_SetTarget(&players[i].mo->tracer, emmo); From 24d68ba07e862ce4b36633d416b00868c72b6607 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 1 Jan 2020 13:40:17 +0100 Subject: [PATCH 57/70] P_LoadTextmap: Set defaults for all linedef and sidedef fields that UDMF is allowed to set --- src/p_setup.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index a48cfe909..e71d6094f 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1563,8 +1563,11 @@ static void P_LoadTextmap(void) for (i = 0, ld = lines; i < numlines; i++, ld++) { // Defaults. - ld->tag = 0; + ld->v1 = ld->v2 = NULL; + ld->flags = 0; ld->special = 0; + ld->tag = 0; + ld->sidenum[0] = 0xffff; ld->sidenum[1] = 0xffff; TextmapParse(linesPos[i], i, ParseTextmapLinedefParameter); @@ -1575,12 +1578,12 @@ static void P_LoadTextmap(void) for (i = 0, sd = sides; i < numsides; i++, sd++) { // Defaults. - sd->rowoffset = 0; sd->textureoffset = 0; - + sd->rowoffset = 0; sd->toptexture = R_TextureNumForName("-"); sd->midtexture = R_TextureNumForName("-"); sd->bottomtexture = R_TextureNumForName("-"); + sd->sector = NULL; sd->repeatcnt = 0; TextmapParse(sidesPos[i], i, ParseTextmapSidedefParameter); From b59532bccaa332182b56087d6a3ca1e2fe1455a2 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 1 Jan 2020 14:13:24 +0100 Subject: [PATCH 58/70] Setup repeatcnt in P_LoadSidedefs instead of P_ProcessLinedefsWithSidedefs, since UDMF can set it directly --- src/p_setup.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index e71d6094f..d00eebfc8 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1014,13 +1014,11 @@ static void P_InitializeLinedef(line_t *ld) { sides[ld->sidenum[0]].special = ld->special; sides[ld->sidenum[0]].line = ld; - } if (ld->sidenum[1] != 0xffff) { sides[ld->sidenum[1]].special = ld->special; sides[ld->sidenum[1]].line = ld; - } } @@ -1053,10 +1051,30 @@ static void P_LoadSidedefs(UINT8 *data) for (i = 0; i < numsides; i++, sd++, msd++) { + INT16 textureoffset = SHORT(msd->textureoffset); UINT16 sector_num; - boolean isfrontside = !sd->line || sd->line->sidenum[0] == i; + boolean isfrontside; - sd->textureoffset = SHORT(msd->textureoffset)<line) + { + CONS_Debug(DBG_SETUP, "P_LoadSidedefs: Sidedef %s is not used by any linedef\n", sizeu1((size_t)(sd - sides))); + sd->line = &lines[0]; + } + + isfrontside = sd->line->sidenum[0] == i; + + // Repeat count for midtexture + if (((sd->line->flags & (ML_TWOSIDED|ML_EFFECT5)) == (ML_TWOSIDED|ML_EFFECT5)) + && !(sd->special >= 300 && sd->special < 500)) // exempt linedef exec specials + { + sd->repeatcnt = (INT16)(((unsigned)textureoffset) >> 12); + sd->textureoffset = (((unsigned)textureoffset) & 2047) << FRACBITS; + } + else + { + sd->repeatcnt = 0; + sd->textureoffset = textureoffset << FRACBITS; + } sd->rowoffset = SHORT(msd->rowoffset)<frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0; - // Repeat count for midtexture - if ((ld->flags & ML_EFFECT5) && (ld->sidenum[1] != 0xffff) - && !(ld->special >= 300 && ld->special < 500)) // exempt linedef exec specials - { - sides[ld->sidenum[0]].repeatcnt = (INT16)(((unsigned)sides[ld->sidenum[0]].textureoffset >> FRACBITS) >> 12); - sides[ld->sidenum[0]].textureoffset = (((unsigned)sides[ld->sidenum[0]].textureoffset >> FRACBITS) & 2047) << FRACBITS; - sides[ld->sidenum[1]].repeatcnt = (INT16)(((unsigned)sides[ld->sidenum[1]].textureoffset >> FRACBITS) >> 12); - sides[ld->sidenum[1]].textureoffset = (((unsigned)sides[ld->sidenum[1]].textureoffset >> FRACBITS) & 2047) << FRACBITS; - } - // Compile linedef 'text' from both sidedefs 'text' for appropriate specials. switch(ld->special) { From fe198b8a324e9cadee99ffcccf69b4102a4c3609 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 1 Jan 2020 14:27:01 +0100 Subject: [PATCH 59/70] Check if certain mandatory linedef and sidedef fields are set, and use fallback values if not --- src/p_setup.c | 70 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 16 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index d00eebfc8..c915000d9 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1022,6 +1022,26 @@ static void P_InitializeLinedef(line_t *ld) } } +static void P_SetLinedefV1(size_t i, UINT16 vertex_num) +{ + if (vertex_num >= numvertexes) + { + CONS_Debug(DBG_SETUP, "P_SetLinedefV1: linedef %s has out-of-range v1 num %u\n", sizeu1(i), vertex_num); + vertex_num = 0; + } + lines[i].v1 = &vertexes[vertex_num]; +} + +static void P_SetLinedefV2(size_t i, UINT16 vertex_num) +{ + if (vertex_num >= numvertexes) + { + CONS_Debug(DBG_SETUP, "P_SetLinedefV2: linedef %s has out-of-range v2 num %u\n", sizeu1(i), vertex_num); + vertex_num = 0; + } + lines[i].v2 = &vertexes[vertex_num]; +} + static void P_LoadLinedefs(UINT8 *data) { maplinedef_t *mld = (maplinedef_t *)data; @@ -1033,8 +1053,8 @@ static void P_LoadLinedefs(UINT8 *data) ld->flags = SHORT(mld->flags); ld->special = SHORT(mld->special); ld->tag = SHORT(mld->tag); - ld->v1 = &vertexes[SHORT(mld->v1)]; - ld->v2 = &vertexes[SHORT(mld->v2)]; + P_SetLinedefV1(i, SHORT(mld->v1)); + P_SetLinedefV2(i, SHORT(mld->v2)); ld->sidenum[0] = SHORT(mld->sidenum[0]); ld->sidenum[1] = SHORT(mld->sidenum[1]); @@ -1043,6 +1063,17 @@ static void P_LoadLinedefs(UINT8 *data) } } +static void P_SetSidedefSector(size_t i, UINT16 sector_num) +{ + // cph 2006/09/30 - catch out-of-range sector numbers; use sector 0 instead + if (sector_num >= numsectors) + { + CONS_Debug(DBG_SETUP, "P_SetSidedefSector: sidedef %s has out-of-range sector num %u\n", sizeu1(i), sector_num); + sector_num = 0; + } + sides[i].sector = §ors[sector_num]; +} + static void P_LoadSidedefs(UINT8 *data) { mapsidedef_t *msd = (mapsidedef_t*)data; @@ -1052,12 +1083,11 @@ static void P_LoadSidedefs(UINT8 *data) for (i = 0; i < numsides; i++, sd++, msd++) { INT16 textureoffset = SHORT(msd->textureoffset); - UINT16 sector_num; boolean isfrontside; if (!sd->line) { - CONS_Debug(DBG_SETUP, "P_LoadSidedefs: Sidedef %s is not used by any linedef\n", sizeu1((size_t)(sd - sides))); + CONS_Debug(DBG_SETUP, "P_LoadSidedefs: Sidedef %s is not used by any linedef\n", sizeu1(i)); sd->line = &lines[0]; } @@ -1077,14 +1107,7 @@ static void P_LoadSidedefs(UINT8 *data) } sd->rowoffset = SHORT(msd->rowoffset)<sector); - if (sector_num >= numsectors) - { - CONS_Debug(DBG_SETUP, "P_LoadSidedefs: sidedef %s has out-of-range sector num %u\n", sizeu1(i), sector_num); - sector_num = 0; - } - sd->sector = §ors[sector_num]; + P_SetSidedefSector(i, SHORT(msd->sector)); sd->colormap_data = NULL; @@ -1385,7 +1408,7 @@ static void ParseTextmapSidedefParameter(UINT32 i, char *param) else if (fastcmp(param, "texturemiddle")) sides[i].midtexture = R_TextureNumForName(dat = M_GetToken(NULL)); else if (fastcmp(param, "sector")) - sides[i].sector = §ors[atol(dat = M_GetToken(NULL))]; + P_SetSidedefSector(i, atol(dat = M_GetToken(NULL))); else if (fastcmp(param, "repeatcnt")) sides[i].repeatcnt = atol(dat = M_GetToken(NULL)); } @@ -1397,9 +1420,9 @@ static void ParseTextmapLinedefParameter(UINT32 i, char *param) else if (fastcmp(param, "special")) lines[i].special = atol(dat = M_GetToken(NULL)); else if (fastcmp(param, "v1")) - lines[i].v1 = &vertexes[atol(dat = M_GetToken(NULL))]; + P_SetLinedefV1(i, atol(dat = M_GetToken(NULL))); else if (fastcmp(param, "v2")) - lines[i].v2 = &vertexes[atol(dat = M_GetToken(NULL))]; + P_SetLinedefV2(i, atol(dat = M_GetToken(NULL))); else if (fastcmp(param, "sidefront")) lines[i].sidenum[0] = atol(dat = M_GetToken(NULL)); else if (fastcmp(param, "sideback")) @@ -1589,7 +1612,16 @@ static void P_LoadTextmap(void) ld->sidenum[1] = 0xffff; TextmapParse(linesPos[i], i, ParseTextmapLinedefParameter); - + if (!ld->v1) + { + CONS_Debug(DBG_SETUP, "P_LoadTextmap: linedef %s has no v1 set; defaulting to 0\n", sizeu1(i)); + ld->v1 = &vertexes[0]; + } + if (!ld->v2) + { + CONS_Debug(DBG_SETUP, "P_LoadTextmap: linedef %s has no v2 set; defaulting to 0\n", sizeu1(i)); + ld->v2 = &vertexes[0]; + } P_InitializeLinedef(ld); } @@ -1605,6 +1637,12 @@ static void P_LoadTextmap(void) sd->repeatcnt = 0; TextmapParse(sidesPos[i], i, ParseTextmapSidedefParameter); + + if (!sd->sector) + { + CONS_Debug(DBG_SETUP, "P_LoadTextmap: sidedef %s has no sector set; defaulting to 0\n", sizeu1(i)); + sd->sector = §ors[0]; + } } for (i = 0, mt = mapthings; i < nummapthings; i++, mt++) From a41c6405591fd6ba8bd3f4081620be321f3dfc06 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 1 Jan 2020 15:10:41 +0100 Subject: [PATCH 60/70] Move shared parts of sidedef initialization into P_InitializeSidedef --- src/p_setup.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index c915000d9..e2ae29cf7 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1074,6 +1074,19 @@ static void P_SetSidedefSector(size_t i, UINT16 sector_num) sides[i].sector = §ors[sector_num]; } +static void P_InitializeSidedef(side_t *sd) +{ + if (!sd->line) + { + CONS_Debug(DBG_SETUP, "P_LoadSidedefs: Sidedef %s is not used by any linedef\n", sizeu1(i)); + sd->line = &lines[0]; + sd->special = sd->line->special; + } + + sd->text = NULL; + sd->colormap_data = NULL; +} + static void P_LoadSidedefs(UINT8 *data) { mapsidedef_t *msd = (mapsidedef_t*)data; @@ -1085,11 +1098,7 @@ static void P_LoadSidedefs(UINT8 *data) INT16 textureoffset = SHORT(msd->textureoffset); boolean isfrontside; - if (!sd->line) - { - CONS_Debug(DBG_SETUP, "P_LoadSidedefs: Sidedef %s is not used by any linedef\n", sizeu1(i)); - sd->line = &lines[0]; - } + P_InitializeSidedef(sd); isfrontside = sd->line->sidenum[0] == i; @@ -1109,8 +1118,6 @@ static void P_LoadSidedefs(UINT8 *data) P_SetSidedefSector(i, SHORT(msd->sector)); - sd->colormap_data = NULL; - // Special info stored in texture fields! switch (sd->special) { @@ -1643,6 +1650,7 @@ static void P_LoadTextmap(void) CONS_Debug(DBG_SETUP, "P_LoadTextmap: sidedef %s has no sector set; defaulting to 0\n", sizeu1(i)); sd->sector = §ors[0]; } + P_InitializeSidedef(sd); } for (i = 0, mt = mapthings; i < nummapthings; i++, mt++) From 6724b11c368ced28b65315942de1bd5b6003df98 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 1 Jan 2020 15:11:39 +0100 Subject: [PATCH 61/70] Whoops --- src/p_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index e2ae29cf7..f72e25da0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1078,7 +1078,7 @@ static void P_InitializeSidedef(side_t *sd) { if (!sd->line) { - CONS_Debug(DBG_SETUP, "P_LoadSidedefs: Sidedef %s is not used by any linedef\n", sizeu1(i)); + CONS_Debug(DBG_SETUP, "P_LoadSidedefs: Sidedef %s is not used by any linedef\n", sizeu1((size_t)(sd - sides))); sd->line = &lines[0]; sd->special = sd->line->special; } From 9cda82d896a47179f307c0177525e390494c9219 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 1 Jan 2020 15:52:59 +0100 Subject: [PATCH 62/70] Rework textmap parser to always read a parameter's value, even if it doesn't recognize the parameter --- src/p_setup.c | 151 +++++++++++++++++++++++++------------------------- 1 file changed, 75 insertions(+), 76 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index f72e25da0..dc115ed19 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1362,135 +1362,133 @@ static boolean TextmapCount(UINT8 *data, size_t size) return true; } -static char* dat; - -static void ParseTextmapVertexParameter(UINT32 i, char *param) +static void ParseTextmapVertexParameter(UINT32 i, char *param, char *val) { if (fastcmp(param, "x")) - vertexes[i].x = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + vertexes[i].x = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "y")) - vertexes[i].y = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + vertexes[i].y = FLOAT_TO_FIXED(atof(val)); } -static void ParseTextmapSectorParameter(UINT32 i, char *param) +static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val) { if (fastcmp(param, "heightfloor")) - sectors[i].floorheight = atol(dat = M_GetToken(NULL)) << FRACBITS; + sectors[i].floorheight = atol(val) << FRACBITS; else if (fastcmp(param, "heightceiling")) - sectors[i].ceilingheight = atol(dat = M_GetToken(NULL)) << FRACBITS; + sectors[i].ceilingheight = atol(val) << FRACBITS; if (fastcmp(param, "texturefloor")) - sectors[i].floorpic = P_AddLevelFlat(dat = M_GetToken(NULL), foundflats); + sectors[i].floorpic = P_AddLevelFlat(val, foundflats); else if (fastcmp(param, "textureceiling")) - sectors[i].ceilingpic = P_AddLevelFlat(dat = M_GetToken(NULL), foundflats); + sectors[i].ceilingpic = P_AddLevelFlat(val, foundflats); else if (fastcmp(param, "lightlevel")) - sectors[i].lightlevel = atol(dat = M_GetToken(NULL)); + sectors[i].lightlevel = atol(val); else if (fastcmp(param, "special")) - sectors[i].special = atol(dat = M_GetToken(NULL)); + sectors[i].special = atol(val); else if (fastcmp(param, "id")) - sectors[i].tag = atol(dat = M_GetToken(NULL)); + sectors[i].tag = atol(val); else if (fastcmp(param, "xpanningfloor")) - sectors[i].floor_xoffs = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + sectors[i].floor_xoffs = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "ypanningfloor")) - sectors[i].floor_yoffs = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + sectors[i].floor_yoffs = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "xpanningceiling")) - sectors[i].ceiling_xoffs = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + sectors[i].ceiling_xoffs = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "ypanningceiling")) - sectors[i].ceiling_yoffs = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + sectors[i].ceiling_yoffs = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "rotationfloor")) - sectors[i].floorpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL)))); + sectors[i].floorpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(val))); else if (fastcmp(param, "rotationceiling")) - sectors[i].ceilingpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL)))); + sectors[i].ceilingpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(val))); } -static void ParseTextmapSidedefParameter(UINT32 i, char *param) +static void ParseTextmapSidedefParameter(UINT32 i, char *param, char *val) { if (fastcmp(param, "offsetx")) - sides[i].textureoffset = atol(dat = M_GetToken(NULL))< Date: Wed, 1 Jan 2020 16:01:07 +0100 Subject: [PATCH 63/70] Move MAXFLATSIZE define to p_spec.h so p_spec.c doesn't have to redefine it --- src/p_setup.c | 4 ---- src/p_spec.c | 3 --- src/p_spec.h | 3 +++ 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index dc115ed19..8b82e8c69 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1527,8 +1527,6 @@ static void TextmapParse(UINT32 dataPos, size_t num, void (*parser)(UINT32, char } } -#define MAXFLATSIZE (2048<> ((j-1)*4))&15) +// This must be updated whenever we up the max flat size - quicker to assume rather than figuring out the sqrt of the specific flat's filesize. +#define MAXFLATSIZE (2048< Date: Wed, 1 Jan 2020 23:49:29 +0800 Subject: [PATCH 64/70] Allow 6-letter character names to be drawn with the thick font --- src/st_stuff.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/st_stuff.c b/src/st_stuff.c index 9c4f0abd5..ea868b5a5 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -939,6 +939,8 @@ static void ST_drawLivesArea(void) v_colmap |= (V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER); if (strlen(skins[stplyr->skin].hudname) <= 5) V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname); + else if (V_StringWidth(skins[stplyr->skin].hudname, v_colmap) <= 48) + V_DrawString(hudinfo[HUD_LIVES].x+18, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname); else if (V_ThinStringWidth(skins[stplyr->skin].hudname, v_colmap) <= 40) V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname); else From 35ff383a4a7ce23039422c356e7073204f3fc8f8 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 1 Jan 2020 15:17:29 -0300 Subject: [PATCH 65/70] Rename ``seenplayer`` to ``seenfriend`` --- src/lua_hook.h | 2 +- src/lua_hooklib.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 24e61c20c..023090897 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -99,7 +99,7 @@ void LUAh_IntermissionThinker(void); // Hook for Y_Ticker boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble); // Hook for team switching in... uh.... UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced); // Hook for spy mode #ifdef SEENAMES -boolean LUAh_SeenPlayer(player_t *player, player_t *seenplayer); // Hook for MT_NAMECHECK +boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend); // Hook for MT_NAMECHECK #endif #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index fc9d74f08..5faa625b3 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1457,7 +1457,7 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean // Hook for MT_NAMECHECK #ifdef SEENAMES -boolean LUAh_SeenPlayer(player_t *player, player_t *seenplayer) +boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend) { hook_p hookp; boolean hasSeenPlayer = true; @@ -1475,7 +1475,7 @@ boolean LUAh_SeenPlayer(player_t *player, player_t *seenplayer) if (lua_gettop(gL) == 0) { LUA_PushUserdata(gL, player, META_PLAYER); - LUA_PushUserdata(gL, seenplayer, META_PLAYER); + LUA_PushUserdata(gL, seenfriend, META_PLAYER); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); From 2da9c3cf8199ac0ef0206354bbcd84789cf9b00c Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 1 Jan 2020 23:52:30 +0100 Subject: [PATCH 66/70] P_LoadTextmap: Bail out if certain mandatory fields are not set --- src/p_setup.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 8b82e8c69..de6503dca 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1574,9 +1574,15 @@ static void P_LoadTextmap(void) for (i = 0, vt = vertexes; i < numvertexes; i++, vt++) { // Defaults. - vt->x = vt->y = vt->z = 0; + vt->x = vt->y = INT32_MAX; + vt->z = 0; TextmapParse(vertexesPos[i], i, ParseTextmapVertexParameter); + + if (vt->x == INT32_MAX) + I_Error("P_LoadTextmap: vertex %s has no x value set!\n", sizeu1(i)); + if (vt->y == INT32_MAX) + I_Error("P_LoadTextmap: vertex %s has no y value set!\n", sizeu1(i)); } for (i = 0, sc = sectors; i < numsectors; i++, sc++) @@ -1614,16 +1620,14 @@ static void P_LoadTextmap(void) ld->sidenum[1] = 0xffff; TextmapParse(linesPos[i], i, ParseTextmapLinedefParameter); + if (!ld->v1) - { - CONS_Debug(DBG_SETUP, "P_LoadTextmap: linedef %s has no v1 set; defaulting to 0\n", sizeu1(i)); - ld->v1 = &vertexes[0]; - } + I_Error("P_LoadTextmap: linedef %s has no v1 value set!\n", sizeu1(i)); if (!ld->v2) - { - CONS_Debug(DBG_SETUP, "P_LoadTextmap: linedef %s has no v2 set; defaulting to 0\n", sizeu1(i)); - ld->v2 = &vertexes[0]; - } + I_Error("P_LoadTextmap: linedef %s has no v2 value set!\n", sizeu1(i)); + if (ld->sidenum[0] == 0xffff) + I_Error("P_LoadTextmap: linedef %s has no sidefront value set!\n", sizeu1(i)); + P_InitializeLinedef(ld); } @@ -1641,10 +1645,8 @@ static void P_LoadTextmap(void) TextmapParse(sidesPos[i], i, ParseTextmapSidedefParameter); if (!sd->sector) - { - CONS_Debug(DBG_SETUP, "P_LoadTextmap: sidedef %s has no sector set; defaulting to 0\n", sizeu1(i)); - sd->sector = §ors[0]; - } + I_Error("P_LoadTextmap: sidedef %s has no sector value set!\n", sizeu1(i)); + P_InitializeSidedef(sd); } From 02acf6222be72d9c594f55792ad6324221e4bc52 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Thu, 2 Jan 2020 00:32:29 +0100 Subject: [PATCH 67/70] P_LoadExtendedSubsectorsAndSegs: Slightly simplify the seg vertex reading code --- src/p_setup.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index de6503dca..d83b7adaa 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2027,13 +2027,8 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype for (m = 0; m < subsectors[i].numlines; m++, k++) { UINT16 linenum; - UINT32 vert = READUINT32((*data)); - segs[k].v1 = &vertexes[vert]; - if (m == 0) - segs[k + subsectors[i].numlines - 1].v2 = &vertexes[vert]; - else - segs[k - 1].v2 = segs[k].v1; + segs[k - 1 + ((m == 0) ? 0 : subsectors[i].numlines)].v2 = segs[k].v1 = &vertexes[READUINT32((*data))]; (*data) += 4; // partner, can be ignored by software renderer if (nodetype == NT_XGL3) From 5ba179ad7c53a82cdb5810c1f292d2a0e00ed2b1 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Thu, 2 Jan 2020 09:51:07 +0100 Subject: [PATCH 68/70] Fix two bugs in extended segs loading, and add some error checking while I'm at it --- src/p_setup.c | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index d83b7adaa..4de5fedc8 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1840,10 +1840,13 @@ static inline float P_SegLengthFloat(seg_t *seg) static void P_InitializeSeg(seg_t *seg) { - seg->sidedef = &sides[seg->linedef->sidenum[seg->side]]; + if (seg->linedef) + { + seg->sidedef = &sides[seg->linedef->sidenum[seg->side]]; - seg->frontsector = seg->sidedef->sector; - seg->backsector = (seg->linedef->flags & ML_TWOSIDED) ? sides[seg->linedef->sidenum[seg->side ^ 1]].sector : NULL; + seg->frontsector = seg->sidedef->sector; + seg->backsector = (seg->linedef->flags & ML_TWOSIDED) ? sides[seg->linedef->sidenum[seg->side ^ 1]].sector : NULL; + } #ifdef HWRENDER seg->pv1 = seg->pv2 = NULL; @@ -2026,15 +2029,21 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype case NT_XGL3: for (m = 0; m < subsectors[i].numlines; m++, k++) { + UINT32 vertexnum = READUINT32((*data)); UINT16 linenum; - segs[k - 1 + ((m == 0) ? 0 : subsectors[i].numlines)].v2 = segs[k].v1 = &vertexes[READUINT32((*data))]; + if (vertexnum >= numvertexes) + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %d in subsector %d has invalid vertex %d!\n", k, m, vertexnum); - (*data) += 4; // partner, can be ignored by software renderer + segs[k - 1 + ((m == 0) ? subsectors[i].numlines : 0)].v2 = segs[k].v1 = &vertexes[vertexnum]; + + READUINT32((*data)); // partner, can be ignored by software renderer if (nodetype == NT_XGL3) - (*data) += 2; // Line number is 32-bit in XGL3, but we're limited to 16 bits. + READUINT16((*data)); // Line number is 32-bit in XGL3, but we're limited to 16 bits. linenum = READUINT16((*data)); + if (linenum != 0xFFFF && linenum >= numlines) + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %d in subsector %d has invalid linedef %d!\n", k, m, linenum); segs[k].glseg = (linenum == 0xFFFF); segs[k].linedef = (linenum == 0xFFFF) ? NULL : &lines[linenum]; segs[k].side = READUINT8((*data)); @@ -2044,9 +2053,20 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype case NT_XNOD: for (m = 0; m < subsectors[i].numlines; m++, k++) { - segs[k].v1 = &vertexes[READUINT32((*data))]; - segs[k].v2 = &vertexes[READUINT32((*data))]; - segs[k].linedef = &lines[READUINT16((*data))]; + UINT32 v1num = READUINT32((*data)); + UINT32 v2num = READUINT32((*data)); + UINT16 linenum = READUINT16((*data)); + + if (v1num >= numvertexes) + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %d in subsector %d has invalid v1 %d!\n", k, m, v1num); + if (v2num >= numvertexes) + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %d in subsector %d has invalid v2 %d!\n", k, m, v2num); + if (linenum >= numlines) + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %d in subsector %d has invalid linedef %d!\n", k, m, linenum); + + segs[k].v1 = &vertexes[v1num]; + segs[k].v2 = &vertexes[v2num]; + segs[k].linedef = &lines[linenum]; segs[k].side = READUINT8((*data)); segs[k].glseg = false; } @@ -2063,7 +2083,8 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype vertex_t *v2 = seg->v2; P_InitializeSeg(seg); seg->angle = R_PointToAngle2(v1->x, v1->y, v2->x, v2->y); - seg->offset = FixedHypot(v1->x - seg->linedef->v1->x, v1->y - seg->linedef->v1->y); + if (seg->linedef) + segs[i].offset = FixedHypot(v1->x - seg->linedef->v1->x, v1->y - seg->linedef->v1->y); } return true; From dc0c17dbb85ebd06cf0e659ac33cc7ff2add7cc7 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Thu, 2 Jan 2020 22:28:32 +0100 Subject: [PATCH 69/70] P_LoadExtendedSubsectorsAndSegs: Print size_t with %s --- src/p_setup.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 4de5fedc8..e3a7e1e58 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2033,7 +2033,7 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype UINT16 linenum; if (vertexnum >= numvertexes) - I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %d in subsector %d has invalid vertex %d!\n", k, m, vertexnum); + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %d has invalid vertex %d!\n", sizeu1(k), m, vertexnum); segs[k - 1 + ((m == 0) ? subsectors[i].numlines : 0)].v2 = segs[k].v1 = &vertexes[vertexnum]; @@ -2043,7 +2043,7 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype linenum = READUINT16((*data)); if (linenum != 0xFFFF && linenum >= numlines) - I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %d in subsector %d has invalid linedef %d!\n", k, m, linenum); + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %d has invalid linedef %d!\n", sizeu1(k), m, linenum); segs[k].glseg = (linenum == 0xFFFF); segs[k].linedef = (linenum == 0xFFFF) ? NULL : &lines[linenum]; segs[k].side = READUINT8((*data)); @@ -2058,11 +2058,11 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype UINT16 linenum = READUINT16((*data)); if (v1num >= numvertexes) - I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %d in subsector %d has invalid v1 %d!\n", k, m, v1num); + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %d has invalid v1 %d!\n", sizeu1(k), m, v1num); if (v2num >= numvertexes) - I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %d in subsector %d has invalid v2 %d!\n", k, m, v2num); + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %d has invalid v2 %d!\n", sizeu1(k), m, v2num); if (linenum >= numlines) - I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %d in subsector %d has invalid linedef %d!\n", k, m, linenum); + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %d has invalid linedef %d!\n", sizeu1(k), m, linenum); segs[k].v1 = &vertexes[v1num]; segs[k].v2 = &vertexes[v2num]; From 26bb0b3c67d6e05d4b3ccc54891d10e348bdcc04 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 3 Jan 2020 21:50:27 +0100 Subject: [PATCH 70/70] Compressing sidedefs can break both special effects and netgame syncing, so let's get rid of it --- src/p_setup.c | 65 --------------------------------------------------- 1 file changed, 65 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index dcb2a0ae4..bd1c53104 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2548,69 +2548,6 @@ static void P_ProcessLinedefsWithSidedefs(void) } } -static void P_CompressSidedefs(void) -{ - side_t *newsides; - size_t numnewsides = 0; - size_t z; - size_t i; - - for (i = 0; i < numsides; i++) - { - size_t j, k; - line_t *ld; - - if (!sides[i].sector) - continue; - - for (k = numlines, ld = lines; k--; ld++) - { - if (ld->sidenum[0] == i) - ld->sidenum[0] = (UINT16)numnewsides; - - if (ld->sidenum[1] == i) - ld->sidenum[1] = (UINT16)numnewsides; - } - - for (j = i + 1; j < numsides; j++) - { - if (!sides[j].sector) - continue; - - if (!memcmp(&sides[i], &sides[j], sizeof(side_t))) - { - // Find the linedefs that belong to this one - for (k = numlines, ld = lines; k--; ld++) - { - if (ld->sidenum[0] == j) - ld->sidenum[0] = (UINT16)numnewsides; - - if (ld->sidenum[1] == j) - ld->sidenum[1] = (UINT16)numnewsides; - } - sides[j].sector = NULL; // Flag for deletion - } - } - numnewsides++; - } - - // We're loading crap into this block anyhow, so no point in zeroing it out. - newsides = Z_Malloc(numnewsides*sizeof(*newsides), PU_LEVEL, NULL); - - // Copy the sides to their new block of memory. - for (i = 0, z = 0; i < numsides; i++) - { - if (sides[i].sector) - M_Memcpy(&newsides[z++], &sides[i], sizeof(side_t)); - } - - CONS_Debug(DBG_SETUP, "P_CompressSidedefs: Old sides is %s, new sides is %s\n", sizeu1(numsides), sizeu1(numnewsides)); - - Z_Free(sides); - sides = newsides; - numsides = numnewsides; -} - // // P_LinkMapData // Builds sector line lists and subsector sector numbers. @@ -2777,8 +2714,6 @@ static boolean P_LoadMapFromFile(void) P_LoadMapLUT(virt); P_ProcessLinedefsWithSidedefs(); - if (M_CheckParm("-compress")) - P_CompressSidedefs(); P_LinkMapData(); P_MakeMapMD5(virt, &mapmd5);