From 84cde74bdaa77ee9e819f1427fb0c25460d52a97 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 23 Feb 2020 16:38:32 -0300 Subject: [PATCH 01/27] Award pink shields in friendly gametypes --- 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 a24f9bf03..cc8d5db6b 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3158,7 +3158,7 @@ static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *sou // In COOP/RACE, you can't hurt other players unless cv_friendlyfire is on if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && (G_PlatformGametype())) { - if (gametype == GT_COOP && inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) // co-op only + if ((gametyperules & GTR_FRIENDLY) && inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) // co-op only { if (player->revitem != MT_LHRT && player->spinitem != MT_LHRT && player->thokitem != MT_LHRT) // Healers do not get to heal other healers. { From 220cf7bd891b55b73147486a3ed708b4afede75a Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 23 Feb 2020 16:40:16 -0300 Subject: [PATCH 02/27] Don't reset player between maps in campaign gametypes --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 08192bfb8..c1e5a519c 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3856,7 +3856,7 @@ static void G_DoWorldDone(void) { if (server) { - if (gametype == GT_COOP) + if (gametyperules & GTR_CAMPAIGN) // don't reset player between maps D_MapChange(nextmap+1, gametype, ultimatemode, false, 0, false, false); else From 1d5f9ed292addb8cffa1271562923c153476f73c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 23 Feb 2020 16:40:52 -0300 Subject: [PATCH 03/27] Always allow skin switching in friendly gametypes --- src/d_netcmd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index c25929929..6e8e67fc4 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1158,7 +1158,7 @@ UINT8 CanChangeSkin(INT32 playernum) // Server has skin change restrictions. if (cv_restrictskinchange.value) { - if (gametype == GT_COOP) + if (gametyperules & GTR_FRIENDLY) return true; // Can change skin during initial countdown. @@ -3753,11 +3753,11 @@ static void ExitMove_OnChange(void) { if (players[i].mo->target && players[i].mo->target->type == MT_SIGN) P_SetTarget(&players[i].mo->target, NULL); - + if (players[i].pflags & PF_FINISHED) P_GiveFinishFlags(&players[i]); } - + CONS_Printf(M_GetText("Players can now move after completing the level.\n")); } else From 4d94689af7b234a4c6ea2ea73c170811d561fa43 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 23 Feb 2020 16:41:39 -0300 Subject: [PATCH 04/27] Scan for emeralds in gametypes with Emerald Hunt --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index c1e5a519c..d66af417c 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2611,7 +2611,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0); } - if (gametype == GT_COOP) + if (gametyperules & GTR_EMERALDHUNT) P_FindEmerald(); // scan for emeralds to hunt for // If NiGHTS, find lowest mare to start with. From 990df8e8c049dbae47d09c39470f4eaf3d4fa103 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 23 Feb 2020 16:45:01 -0300 Subject: [PATCH 05/27] Consider Co-Op here as any campaign gametype --- 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 6e8e67fc4..c44a14f8b 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1737,7 +1737,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese } CONS_Debug(DBG_GAMELOGIC, "Map change: mapnum=%d gametype=%d ultmode=%d resetplayers=%d delay=%d skipprecutscene=%d\n", mapnum, newgametype, pultmode, resetplayers, delay, skipprecutscene); - if ((netgame || multiplayer) && !((gametype == newgametype) && (newgametype == GT_COOP))) + if ((netgame || multiplayer) && !((gametype == newgametype) && (gametypedefaultrules[newgametype] & GTR_CAMPAIGN))) FLS = false; if (delay != 2) From 1b9a6fed3e5133ce2b04276a0663ee893af4f69d Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 23 Feb 2020 16:46:45 -0300 Subject: [PATCH 06/27] Same here --- 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 c44a14f8b..3c17987e1 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1979,7 +1979,7 @@ static void Command_Map_f(void) fromlevelselect = ( netgame || multiplayer ) && newgametype == gametype && - newgametype == GT_COOP; + gametypedefaultrules[newgametype] & GTR_CAMPAIGN; } } From 8efba0e367e2c401fee49a2a8cd0ec8176a17272 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 23 Feb 2020 16:50:36 -0300 Subject: [PATCH 07/27] Allow countdown time-up in any campaign gametype --- src/g_game.c | 2 +- src/p_tick.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index d66af417c..265fb115f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2899,7 +2899,7 @@ void G_DoReborn(INT32 playernum) return; } - if (countdowntimeup || (!(netgame || multiplayer) && gametype == GT_COOP)) + if (countdowntimeup || (!(netgame || multiplayer) && (gametyperules & GTR_CAMPAIGN))) resetlevel = true; else if ((G_GametypeUsesCoopLives() || G_GametypeUsesCoopStarposts()) && (netgame || multiplayer) && !G_IsSpecialStage(gamemap)) { diff --git a/src/p_tick.c b/src/p_tick.c index 1d421ad37..39a2fc6f6 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -698,7 +698,7 @@ void P_Ticker(boolean run) if (run) { - if (countdowntimer && G_PlatformGametype() && (gametype == GT_COOP || leveltime >= 4*TICRATE) && !stoppedclock && --countdowntimer <= 0) + if (countdowntimer && G_PlatformGametype() && ((gametyperules & GTR_CAMPAIGN) || leveltime >= 4*TICRATE) && !stoppedclock && --countdowntimer <= 0) { countdowntimer = 0; countdowntimeup = true; From 48a9ea8d0ea7b1ab1d49c14841fe5c1190b8cd61 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 23 Feb 2020 17:02:50 -0300 Subject: [PATCH 08/27] Turn players IT if they join the game after the hide time in tag gametypes Except in gametypes with hide time stasis, because they can't change team. --- src/d_netcmd.c | 2 +- src/g_game.c | 2 +- src/p_inter.c | 2 +- src/p_user.c | 6 +++--- src/st_stuff.c | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 3c17987e1..a77ea0dd5 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2775,7 +2775,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) players[playernum].spectator = false; //If joining after hidetime in normal tag, default to being IT. - if (gametype == GT_TAG && (leveltime > (hidetime * TICRATE))) + if (((gametyperules & (GTR_TAG|GTR_HIDEFROZEN)) == GTR_TAG) && (leveltime > (hidetime * TICRATE))) { NetPacket.packet.newteam = 1; //minor hack, causes the "is it" message to be printed later. players[playernum].pflags |= PF_TAGIT; //make the player IT. diff --git a/src/g_game.c b/src/g_game.c index 265fb115f..47226931a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3221,7 +3221,7 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = // Tag GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|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_OVERTIME|GTR_STARTCOUNTDOWN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_STARTCOUNTDOWN|GTR_HIDEFROZEN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, // CTF GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_POWERSTONES|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, diff --git a/src/p_inter.c b/src/p_inter.c index cc8d5db6b..800f07d83 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2285,7 +2285,7 @@ void P_CheckSurvivors(void) if (!taggers) //If there are no taggers, pick a survivor at random to be it. { // Exception for hide and seek. If a round has started and the IT player leaves, end the round. - if (gametype == GT_HIDEANDSEEK && (leveltime >= (hidetime * TICRATE))) + if ((gametyperules & GTR_HIDEFROZEN) && (leveltime >= (hidetime * TICRATE))) { CONS_Printf(M_GetText("The IT player has left the game.\n")); if (server) diff --git a/src/p_user.c b/src/p_user.c index 880d932af..a481969cf 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -392,7 +392,7 @@ void P_GiveFinishFlags(player_t *player) mobj_t* flag = P_SpawnMobjFromMobj(player->mo, xoffs, yoffs, 0, MT_FINISHFLAG); flag->angle = angle; angle += FixedAngle(120*FRACUNIT); - + P_SetTarget(&flag->target, player->mo); } } @@ -3679,7 +3679,7 @@ static boolean PIT_CheckSolidsTeeter(mobj_t *thing) if (thing == teeterer) return true; - if (thing->player && cv_tailspickup.value && gametype != GT_HIDEANDSEEK) + if (thing->player && cv_tailspickup.value && !(gametyperules & GTR_HIDEFROZEN)) return true; blockdist = teeterer->radius + thing->radius; @@ -8034,7 +8034,7 @@ static void P_MovePlayer(player_t *player) if (player->pflags & PF_TAGIT) forcestasis = true; } - else if (gametype == GT_HIDEANDSEEK) + else if (gametyperules & GTR_HIDEFROZEN) { if (!(player->pflags & PF_TAGIT)) { diff --git a/src/st_stuff.c b/src/st_stuff.c index 4864f2af6..1e792db79 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1444,7 +1444,7 @@ static void ST_drawPowerupHUD(void) if (stplyr->spectator || stplyr->playerstate != PST_LIVE) return; - + // --------- // Finish icon // --------- @@ -2363,12 +2363,12 @@ static void ST_drawTextHUD(void) textHUDdraw(M_GetText("\x82""You are blindfolded!")) textHUDdraw(M_GetText("Waiting for players to hide...")) } - else if (gametype == GT_HIDEANDSEEK) + else if (gametyperules & GTR_HIDEFROZEN) textHUDdraw(M_GetText("Hide before time runs out!")) else textHUDdraw(M_GetText("Flee before you are hunted!")) } - else if (gametype == GT_HIDEANDSEEK && !(stplyr->pflags & PF_TAGIT)) + else if ((gametyperules & GTR_HIDEFROZEN) && !(stplyr->pflags & PF_TAGIT)) { if (!splitscreen && !donef12) { From 7a34372885be5d11a50556e670f8e0832b040faf Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 23 Feb 2020 19:23:00 -0300 Subject: [PATCH 09/27] Let spectators decide where they spawn Also fixes some issues with tag gametypes --- src/g_game.c | 49 +++++++++++++++++++++++++++++++++++++------------ src/p_inter.c | 4 ++-- src/p_user.c | 5 +++-- src/st_stuff.c | 2 +- 4 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 47226931a..c8b4757e3 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2781,6 +2781,26 @@ mapthing_t *G_FindCoopStart(INT32 playernum) return NULL; } +// Find a Co-op start, or fallback into other types of starts. +static inline mapthing_t *G_FindCoopStartOrFallback(INT32 playernum) +{ + mapthing_t *spawnpoint = NULL; + if (!(spawnpoint = G_FindCoopStart(playernum)) // find a Co-op start + && !(spawnpoint = G_FindMatchStart(playernum))) // find a DM start + spawnpoint = G_FindCTFStart(playernum); // fallback + return spawnpoint; +} + +// Find a Match start, or fallback into other types of starts. +static inline mapthing_t *G_FindMatchStartOrFallback(INT32 playernum) +{ + mapthing_t *spawnpoint = NULL; + if (!(spawnpoint = G_FindMatchStart(playernum)) // find a DM start + && !(spawnpoint = G_FindCTFStart(playernum))) // find a CTF start + spawnpoint = G_FindCoopStart(playernum); // fallback + return spawnpoint; +} + mapthing_t *G_FindMapStart(INT32 playernum) { mapthing_t *spawnpoint; @@ -2788,9 +2808,22 @@ mapthing_t *G_FindMapStart(INT32 playernum) if (!playeringame[playernum]) return NULL; + // -- Spectators -- + // Order in platform gametypes: Coop->DM->CTF + // And, with deathmatch starts: DM->CTF->Coop + if (players[playernum].spectator) + { + // In platform gametypes, spawn in Co-op starts first + // Overriden by GTR_DEATHMATCHSTARTS. + if (G_PlatformGametype() && !(gametyperules & GTR_DEATHMATCHSTARTS)) + spawnpoint = G_FindCoopStartOrFallback(playernum); + else + spawnpoint = G_FindMatchStartOrFallback(playernum); + } + // -- CTF -- // Order: CTF->DM->Coop - if ((gametyperules & (GTR_TEAMFLAGS|GTR_TEAMS)) && players[playernum].ctfteam) + else if ((gametyperules & (GTR_TEAMFLAGS|GTR_TEAMS)) && players[playernum].ctfteam) { if (!(spawnpoint = G_FindCTFStart(playernum)) // find a CTF start && !(spawnpoint = G_FindMatchStart(playernum))) // find a DM start @@ -2799,21 +2832,13 @@ mapthing_t *G_FindMapStart(INT32 playernum) // -- DM/Tag/CTF-spectator/etc -- // Order: DM->CTF->Coop - 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 - spawnpoint = G_FindCoopStart(playernum); // fallback - } + else if (G_TagGametype() ? (!(players[playernum].pflags & PF_TAGIT)) : (gametyperules & GTR_DEATHMATCHSTARTS)) + spawnpoint = G_FindMatchStartOrFallback(playernum); // -- Other game modes -- // Order: Coop->DM->CTF else - { - if (!(spawnpoint = G_FindCoopStart(playernum)) // find a Co-op start - && !(spawnpoint = G_FindMatchStart(playernum))) // find a DM start - spawnpoint = G_FindCTFStart(playernum); // fallback - } + spawnpoint = G_FindCoopStartOrFallback(playernum); //No spawns found. ANYWHERE. if (!spawnpoint) diff --git a/src/p_inter.c b/src/p_inter.c index 800f07d83..b30921d01 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2603,7 +2603,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget // allow them to try again, rather than sitting the whole thing out. if (leveltime >= hidetime * TICRATE) { - if (gametype == GT_TAG)//suiciding in survivor makes you IT. + if (!(gametyperules & GTR_HIDEFROZEN))//suiciding in survivor makes you IT. { target->player->pflags |= PF_TAGIT; CONS_Printf(M_GetText("%s is now IT!\n"), player_names[target->player-players]); // Tell everyone who is it! @@ -3097,7 +3097,7 @@ static boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, IN P_AddPlayerScore(source->player, 100); //award points to tagger. P_HitDeathMessages(player, inflictor, source, 0); - if (gametype == GT_TAG) //survivor + if (!(gametyperules & GTR_HIDEFROZEN)) //survivor { player->pflags |= PF_TAGIT; //in survivor, the player becomes IT and helps hunt down the survivors. CONS_Printf(M_GetText("%s is now IT!\n"), player_names[player-players]); // Tell everyone who is it! diff --git a/src/p_user.c b/src/p_user.c index a481969cf..83f69a4d9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1048,7 +1048,8 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) // Point penalty for hitting a hazard during tag. // Discourages players from intentionally hurting themselves to avoid being tagged. - if (gametype == GT_TAG && (!(player->pflags & PF_GAMETYPEOVER) && !(player->pflags & PF_TAGIT))) + if (((gametyperules & (GTR_TAG|GTR_HIDEFROZEN)) == GTR_TAG) + && (!(player->pflags & PF_GAMETYPEOVER) && !(player->pflags & PF_TAGIT))) { if (player->score >= 50) player->score -= 50; @@ -10681,7 +10682,7 @@ boolean P_SpectatorJoinGame(player_t *player) player->spectator = player->outofcoop = false; player->playerstate = PST_REBORN; - if (gametype == GT_TAG) + if ((gametyperules & (GTR_TAG|GTR_HIDEFROZEN)) == GTR_TAG) { //Make joining players "it" after hidetime. if (leveltime > (hidetime * TICRATE)) diff --git a/src/st_stuff.c b/src/st_stuff.c index 1e792db79..cb5c0fbc1 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2368,7 +2368,7 @@ static void ST_drawTextHUD(void) else textHUDdraw(M_GetText("Flee before you are hunted!")) } - else if ((gametyperules & GTR_HIDEFROZEN) && !(stplyr->pflags & PF_TAGIT)) + else if (gametype == GT_HIDEANDSEEK && !(stplyr->pflags & PF_TAGIT)) { if (!splitscreen && !donef12) { From 604c05801a88b21f6d2af29cefb66d0572d7c179 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 28 Feb 2020 23:21:27 -0300 Subject: [PATCH 10/27] Fix homing ring using the wrong team gametype rule --- src/p_enemy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 5d067ebc3..26edff35f 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4986,7 +4986,7 @@ void A_ThrownRing(mobj_t *actor) continue; // Don't home in on teammates. - if ((gametyperules & GTR_TEAMFLAGS) + if ((gametyperules & GTR_TEAMS) && actor->target->player->ctfteam == player->ctfteam) continue; } From 895c226548acbb034a2607f2d62bf39c64adadfd Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 28 Feb 2020 23:25:25 -0300 Subject: [PATCH 11/27] Fix incorrect team gametype rule being used in A_OldRingExplode --- src/p_enemy.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 26edff35f..ec21eb299 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -6601,7 +6601,7 @@ void A_OldRingExplode(mobj_t *actor) { if (changecolor) { - if (!(gametyperules & GTR_TEAMFLAGS)) + if (!(gametyperules & GTR_TEAMS)) mo->color = actor->target->color; //copy color else if (actor->target->player->ctfteam == 2) mo->color = skincolor_bluering; @@ -6617,7 +6617,7 @@ void A_OldRingExplode(mobj_t *actor) { if (changecolor) { - if (!(gametyperules & GTR_TEAMFLAGS)) + if (!(gametyperules & GTR_TEAMS)) mo->color = actor->target->color; //copy color else if (actor->target->player->ctfteam == 2) mo->color = skincolor_bluering; @@ -6632,7 +6632,7 @@ void A_OldRingExplode(mobj_t *actor) { if (changecolor) { - if (!(gametyperules & GTR_TEAMFLAGS)) + if (!(gametyperules & GTR_TEAMS)) mo->color = actor->target->color; //copy color else if (actor->target->player->ctfteam == 2) mo->color = skincolor_bluering; From 33f58f006d032301123a51005a2886f3b7872588 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 28 Feb 2020 23:41:10 -0300 Subject: [PATCH 12/27] Score adding and stealing should check the gametype's rules. --- 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 83f69a4d9..f9dbd5823 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1437,7 +1437,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) } // In team match, all awarded points are incremented to the team's running score. - if (gametype == GT_TEAMMATCH) + if ((gametyperules & (GTR_TEAMS|GTR_TEAMFLAGS)) == GTR_TEAMS) { if (player->ctfteam == 1) redscore += amount; @@ -1471,7 +1471,7 @@ void P_StealPlayerScore(player_t *player, UINT32 amount) if (stolen > 0) { // In team match, all stolen points are removed from the enemy team's running score. - if (gametype == GT_TEAMMATCH) + if ((gametyperules & (GTR_TEAMS|GTR_TEAMFLAGS)) == GTR_TEAMS) { if (player->ctfteam == 1) bluescore -= amount; From d5f6e5fcc6e4d0a9039b01bd83daaa728b8a5f66 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 28 Feb 2020 23:47:38 -0300 Subject: [PATCH 13/27] Race is Competition without the lives --- src/d_netcmd.c | 4 ++-- src/p_setup.c | 2 +- src/p_spec.c | 4 ++-- src/st_stuff.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index a77ea0dd5..60f03f137 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3629,7 +3629,7 @@ static void PointLimit_OnChange(void) static void NumLaps_OnChange(void) { // Just don't be verbose - if (gametype == GT_RACE) + if ((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE) CONS_Printf(M_GetText("Number of laps set to %d\n"), cv_numlaps.value); } @@ -4608,7 +4608,7 @@ static void Command_ShowTime_f(void) static void BaseNumLaps_OnChange(void) { - if (gametype == GT_RACE) + if ((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE) { if (cv_basenumlaps.value) CONS_Printf(M_GetText("Number of laps will be changed to map defaults next round.\n")); diff --git a/src/p_setup.c b/src/p_setup.c index 7b4c6773b..1bb67c9b8 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3374,7 +3374,7 @@ static void P_InitGametype(void) if (G_TagGametype()) P_InitTagGametype(); - else if (gametype == GT_RACE && server) + else if (((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE) && server) CV_StealthSetValue(&cv_numlaps, (cv_basenumlaps.value) ? cv_basenumlaps.value diff --git a/src/p_spec.c b/src/p_spec.c index d9bbab246..15c88927e 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4991,7 +4991,7 @@ DoneSection2: break; case 10: // Finish Line - if (gametype == GT_RACE && !player->exiting) + if (((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE) && !player->exiting) { if (player->starpostnum == numstarposts) // Must have touched all the starposts { @@ -6483,7 +6483,7 @@ void P_SpawnSpecials(boolean fromnetsave) switch(GETSECSPECIAL(sector->special, 4)) { case 10: // Circuit finish line - if (gametype == GT_RACE) + if ((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE) circuitmap = true; break; } diff --git a/src/st_stuff.c b/src/st_stuff.c index cb5c0fbc1..6bc5b452c 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2688,7 +2688,7 @@ static void ST_overlayDrawer(void) && (netgame || multiplayer) && (cv_cooplives.value == 0)) ; - else if ((G_GametypeUsesLives() || gametype == GT_RACE) && stplyr->lives <= 0 && !(hu_showscores && (netgame || multiplayer))) + else if ((G_GametypeUsesLives() || ((gametyperules & (GTR_RACE|GTR_LIVES)) == GTR_RACE)) && stplyr->lives <= 0 && !(hu_showscores && (netgame || multiplayer))) { INT32 i = MAXPLAYERS; INT32 deadtimer = stplyr->spectator ? TICRATE : (stplyr->deadtimer-(TICRATE<<1)); From d8311634874e5098452331d88980f8e7fbf7bffb Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 28 Feb 2020 23:52:33 -0300 Subject: [PATCH 14/27] Consider hide-and-seek as GTR_HIDEFROZEN --- src/g_game.c | 2 +- src/p_map.c | 2 +- src/st_stuff.c | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index c8b4757e3..33edae9bc 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2085,7 +2085,7 @@ boolean G_Responder(event_t *ev) && players[displayplayer].ctfteam != players[consoleplayer].ctfteam) continue; } - else if (gametype == GT_HIDEANDSEEK) + else if (gametyperules & GTR_HIDEFROZEN) { if (players[consoleplayer].pflags & PF_TAGIT) continue; diff --git a/src/p_map.c b/src/p_map.c index 966684818..15bd1111e 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1613,7 +1613,7 @@ static boolean PIT_CheckThing(mobj_t *thing) } // Force solid players in hide and seek to avoid corner stacking. - if (cv_tailspickup.value && gametype != GT_HIDEANDSEEK) + if (cv_tailspickup.value && !(gametyperules & GTR_HIDEFROZEN)) { if (tmthing->player && thing->player) { diff --git a/src/st_stuff.c b/src/st_stuff.c index 6bc5b452c..49f586976 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2368,15 +2368,14 @@ static void ST_drawTextHUD(void) else textHUDdraw(M_GetText("Flee before you are hunted!")) } - else if (gametype == GT_HIDEANDSEEK && !(stplyr->pflags & PF_TAGIT)) + else if ((gametyperules & GTR_HIDEFROZEN) && !(stplyr->pflags & PF_TAGIT)) { if (!splitscreen && !donef12) { textHUDdraw(M_GetText("\x82""VIEWPOINT:""\x80 Switch view")) donef12 = true; } - if (gametyperules & GTR_HIDEFROZEN) - textHUDdraw(M_GetText("You cannot move while hiding.")) + textHUDdraw(M_GetText("You cannot move while hiding.")) } } From 9d0e3465f94415f4d0f8d75b62d71947f220b777 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 29 Feb 2020 00:57:22 -0300 Subject: [PATCH 15/27] G_CoopGametype, for all the GT_COOP cases --- src/d_netcmd.c | 2 +- src/g_game.c | 12 +++++++++++- src/g_game.h | 1 + src/hu_stuff.c | 2 +- src/lua_baselib.c | 9 +++++++++ src/p_inter.c | 6 +++--- src/p_mobj.c | 10 +++++----- src/p_spec.c | 8 ++++---- src/p_user.c | 36 ++++++++++++++++++------------------ src/st_stuff.c | 10 +++++----- 10 files changed, 58 insertions(+), 38 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 60f03f137..ed612aaef 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3743,7 +3743,7 @@ static void ExitMove_OnChange(void) { UINT8 i; - if (!(netgame || multiplayer) || gametype != GT_COOP) + if (!(netgame || multiplayer) || !G_CoopGametype()) return; if (cv_exitmove.value) diff --git a/src/g_game.c b/src/g_game.c index 33edae9bc..f0ca101fa 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3131,7 +3131,7 @@ void G_AddPlayer(INT32 playernum) p->height = mobjinfo[MT_PLAYER].height; - if (G_GametypeUsesLives() || ((netgame || multiplayer) && gametype == GT_COOP)) + if (G_GametypeUsesLives() || ((netgame || multiplayer) && (gametyperules & GTR_FRIENDLY))) p->lives = cv_startinglives.value; if ((countplayers && !notexiting) || G_IsSpecialStage(gamemap)) @@ -3591,6 +3591,16 @@ boolean G_PlatformGametype(void) return (!(gametyperules & GTR_RINGSLINGER)); } +// +// G_CoopGametype +// +// Returns true if a gametype is a Co-op gametype. +// +boolean G_CoopGametype(void) +{ + return ((gametyperules & (GTR_FRIENDLY|GTR_CAMPAIGN)) == (GTR_FRIENDLY|GTR_CAMPAIGN)); +} + // // G_TagGametype // diff --git a/src/g_game.h b/src/g_game.h index c4c40d84b..bb68ddb20 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -253,6 +253,7 @@ boolean G_GametypeHasTeams(void); boolean G_GametypeHasSpectators(void); boolean G_RingSlingerGametype(void); boolean G_PlatformGametype(void); +boolean G_CoopGametype(void); boolean G_TagGametype(void); boolean G_CompetitionGametype(void); boolean G_EnoughPlayersFinished(void); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 74b68ce69..b31f023d6 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2175,7 +2175,7 @@ void HU_Drawer(void) if (LUA_HudEnabled(hud_rankings)) #endif HU_DrawRankings(); - if (gametype == GT_COOP) + if (gametyperules & GTR_CAMPAIGN) HU_DrawNetplayCoopOverlay(); } else diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 03f142446..b42586834 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2937,6 +2937,14 @@ static int lib_gPlatformGametype(lua_State *L) return 1; } +static int lib_gCoopGametype(lua_State *L) +{ + //HUDSAFE + INLEVEL + lua_pushboolean(L, G_CoopGametype()); + return 1; +} + static int lib_gTagGametype(lua_State *L) { //HUDSAFE @@ -3209,6 +3217,7 @@ static luaL_Reg lib[] = { {"G_GametypeHasSpectators",lib_gGametypeHasSpectators}, {"G_RingSlingerGametype",lib_gRingSlingerGametype}, {"G_PlatformGametype",lib_gPlatformGametype}, + {"G_CoopGametype",lib_gCoopGametype}, {"G_TagGametype",lib_gTagGametype}, {"G_CompetitionGametype",lib_gCompetitionGametype}, {"G_TicsToHours",lib_gTicsToHours}, diff --git a/src/p_inter.c b/src/p_inter.c index b30921d01..851229f9a 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2525,7 +2525,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } P_RestoreMusic(target->player); - if (gametype != GT_COOP) + if (!G_CoopGametype()) { HU_SetCEchoFlags(0); HU_SetCEchoDuration(5); @@ -3257,7 +3257,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) } // If the player was super, tell them he/she ain't so super nomore. - if (gametype != GT_COOP && player->powers[pw_super]) + if (!G_CoopGametype() && player->powers[pw_super]) { S_StartSound(NULL, sfx_s3k66); //let all players hear it. HU_SetCEchoFlags(0); @@ -3627,7 +3627,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (source == target) return false; // Don't hit yourself with your own paraloop, baka if (source && source->player && !(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) - && (gametype == GT_COOP + && ((gametyperules & GTR_FRIENDLY) || (G_GametypeHasTeams() && player->ctfteam == source->player->ctfteam))) return false; // Don't run eachother over in special stages and team games and such } diff --git a/src/p_mobj.c b/src/p_mobj.c index 2bb2cc028..ab9793229 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11440,7 +11440,7 @@ void P_SpawnPlayer(INT32 playernum) if (!G_GametypeHasSpectators()) { p->spectator = p->outofcoop = - (((multiplayer || netgame) && gametype == GT_COOP) // only question status in coop + (((multiplayer || netgame) && G_CoopGametype()) // only question status in coop && ((leveltime > 0 && ((G_IsSpecialStage(gamemap)) // late join special stage || (cv_coopstarposts.value == 2 && (p->jointime < 1 || p->outofcoop)))) // late join or die in new coop @@ -11594,7 +11594,7 @@ void P_AfterPlayerSpawn(INT32 playernum) if (CheckForReverseGravity) P_CheckGravity(mobj, false); - + if (p->pflags & PF_FINISHED) P_GiveFinishFlags(p); } @@ -11918,7 +11918,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) case MT_EMERALD5: case MT_EMERALD6: case MT_EMERALD7: - if (gametype != GT_COOP) // Don't place emeralds in non-coop modes + if (!G_CoopGametype()) // Don't place emeralds in non-coop modes return false; if (metalrecording) @@ -11938,7 +11938,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) runemeraldmanager = true; break; case MT_ROSY: - if (!(gametype == GT_COOP || (mthing->options & MTF_EXTRA))) + if (!(G_CoopGametype() || (mthing->options & MTF_EXTRA))) return false; // she doesn't hang out here if (!mariomode && !(netgame || multiplayer) && players[consoleplayer].skin == 3) @@ -12053,7 +12053,7 @@ static mobjtype_t P_GetMobjtypeSubstitute(mapthing_t *mthing, mobjtype_t i) } } // Set powerup boxes to user settings for other netplay modes - else if (gametype != GT_COOP) + else if (!G_CoopGametype()) { switch (cv_matchboxes.value) { diff --git a/src/p_spec.c b/src/p_spec.c index 15c88927e..f4057fba5 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4100,7 +4100,7 @@ void P_SetupSignExit(player_t *player) if (!numfound && !(player->mo->target && player->mo->target->type == MT_SIGN) - && !(gametype == GT_COOP && (netgame || multiplayer) && cv_exitmove.value)) + && !(G_CoopGametype() && (netgame || multiplayer) && cv_exitmove.value)) P_SetTarget(&player->mo->target, thing); if (thing->state != &states[thing->info->spawnstate]) @@ -4131,7 +4131,7 @@ void P_SetupSignExit(player_t *player) if (!numfound && !(player->mo->target && player->mo->target->type == MT_SIGN) - && !(gametype == GT_COOP && (netgame || multiplayer) && cv_exitmove.value)) + && !(G_CoopGametype() && (netgame || multiplayer) && cv_exitmove.value)) P_SetTarget(&player->mo->target, thing); if (thing->state != &states[thing->info->spawnstate]) @@ -4486,7 +4486,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers continue; if (players[i].bot) continue; - if (gametype == GT_COOP && players[i].lives <= 0) + if (G_CoopGametype() && players[i].lives <= 0) continue; if (roversector) { @@ -4717,7 +4717,7 @@ DoneSection2: // FOF custom exits not to work. lineindex = P_FindSpecialLineFromTag(2, sector->tag, -1); - if (gametype == GT_COOP && lineindex != -1) // Custom exit! + if (G_CoopGametype() && lineindex != -1) // Custom exit! { // Special goodies with the block monsters flag depending on emeralds collected if ((lines[lineindex].flags & ML_BLOCKMONSTERS) && ALL7EMERALDS(emeralds)) diff --git a/src/p_user.c b/src/p_user.c index f9dbd5823..33329a929 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1351,7 +1351,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) player->powers[pw_sneakers] = 0; } - if (gametype != GT_COOP) + if (!G_CoopGametype()) { HU_SetCEchoFlags(0); HU_SetCEchoDuration(5); @@ -1418,7 +1418,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) } } - if (gametype == GT_COOP) + if (G_CoopGametype()) return; } @@ -4305,7 +4305,7 @@ static void P_DoSuperStuff(player_t *player) G_GhostAddColor(GHC_NORMAL); } - if (gametype != GT_COOP) + if (!G_CoopGametype()) { HU_SetCEchoFlags(0); HU_SetCEchoDuration(5); @@ -4355,14 +4355,14 @@ static void P_DoSuperStuff(player_t *player) G_GhostAddColor(GHC_NORMAL); } - if (gametype != GT_COOP) + if (!G_CoopGametype()) player->powers[pw_flashing] = flashingtics-1; if (player->mo->sprite2 & FF_SPR2SUPER) P_SetPlayerMobjState(player->mo, player->mo->state-states); // Inform the netgame that the champion has fallen in the heat of battle. - if (gametype != GT_COOP) + if (!G_CoopGametype()) { S_StartSound(NULL, sfx_s3k66); //let all players hear it. HU_SetCEchoFlags(0); @@ -9639,7 +9639,7 @@ static void P_DeathThink(player_t *player) } if ((cv_cooplives.value != 1) - && (gametype == GT_COOP) + && (G_GametypeUsesCoopLives()) && (netgame || multiplayer) && (player->lives <= 0)) { @@ -9721,17 +9721,17 @@ static void P_DeathThink(player_t *player) countdown2 = 1*TICRATE; } } - //else if (gametype == GT_COOP) -- moved to G_DoReborn + //else if (G_CoopGametype()) -- moved to G_DoReborn } - if (gametype == GT_COOP && (multiplayer || netgame) && (player->lives <= 0) && (player->deadtimer >= 8*TICRATE || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))) + if (G_CoopGametype() && (multiplayer || netgame) && (player->lives <= 0) && (player->deadtimer >= 8*TICRATE || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))) { //player->spectator = true; player->outofcoop = true; player->playerstate = PST_REBORN; } - if ((gametyperules & GTR_RACE) || (gametype == GT_COOP && (multiplayer || netgame))) + if ((gametyperules & GTR_RACE) || (G_CoopGametype() && (multiplayer || netgame))) { // Keep time rolling in race mode if (!(countdown2 && !countdown) && !player->exiting && !(player->pflags & PF_GAMETYPEOVER) && !stoppedclock) @@ -9748,7 +9748,7 @@ static void P_DeathThink(player_t *player) } // Return to level music - if (gametype != GT_COOP && player->lives <= 0 && player->deadtimer == gameovertics) + if (!G_CoopGametype() && player->lives <= 0 && player->deadtimer == gameovertics) P_RestoreMultiMusic(player); } @@ -9925,7 +9925,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (player->exiting) { if (mo->target && mo->target->type == MT_SIGN && mo->target->spawnpoint - && !(gametype == GT_COOP && (netgame || multiplayer) && cv_exitmove.value) + && !(G_CoopGametype() && (netgame || multiplayer) && cv_exitmove.value) && !(twodlevel || (mo->flags2 & MF2_TWOD))) sign = mo->target; else if ((player->powers[pw_carry] == CR_NIGHTSMODE) @@ -10594,7 +10594,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall boolean P_SpectatorJoinGame(player_t *player) { - if (gametype != GT_COOP && !cv_allowteamchange.value) + if (!G_CoopGametype() && !cv_allowteamchange.value) { if (P_IsLocalPlayer(player)) CONS_Printf(M_GetText("Server does not allow team change.\n")); @@ -10705,7 +10705,7 @@ boolean P_SpectatorJoinGame(player_t *player) displayplayer = consoleplayer; } - if (gametype != GT_COOP) + if (!G_CoopGametype()) CONS_Printf(M_GetText("%s entered the game.\n"), player_names[player-players]); return true; // no more player->mo, cannot continue. } @@ -11753,7 +11753,7 @@ void P_PlayerThink(player_t *player) // so we can fade music if (!exitfadestarted && player->exiting > 0 && player->exiting <= 1*TICRATE && - (!multiplayer || gametype == GT_COOP ? !mapheaderinfo[gamemap-1]->musinterfadeout : true) && + (!multiplayer || G_CoopGametype() ? !mapheaderinfo[gamemap-1]->musinterfadeout : true) && // don't fade if we're fading during intermission. follows Y_StartIntermission intertype = int_coop ((gametyperules & GTR_RACE) ? countdown2 == 0 : true) && // don't fade on timeout player->lives > 0 && // don't fade on game over (competition) @@ -11826,7 +11826,7 @@ void P_PlayerThink(player_t *player) if (player->pflags & PF_FINISHED) { - if ((gametype == GT_COOP && cv_exitmove.value) && !G_EnoughPlayersFinished()) + if ((G_CoopGametype() && cv_exitmove.value) && !G_EnoughPlayersFinished()) player->exiting = 0; else P_DoPlayerExit(player); @@ -11864,10 +11864,10 @@ void P_PlayerThink(player_t *player) // Make sure spectators always have a score and ring count of 0. if (player->spectator) { - if (gametype != GT_COOP) + if (!(gametyperules & GTR_CAMPAIGN)) player->score = 0; } - else if ((netgame || multiplayer) && player->lives <= 0 && gametype != GT_COOP) + else if ((netgame || multiplayer) && player->lives <= 0 && !G_CoopGametype()) { // Outside of Co-Op, replenish a user's lives if they are depleted. // of course, this is just a cheap hack, meh... @@ -12732,7 +12732,7 @@ void P_PlayerAfterThink(player_t *player) player->mo->momz = tails->momz; } - if (gametype == GT_COOP && (!tails->player || tails->player->bot != 1)) + if (G_CoopGametype() && (!tails->player || tails->player->bot != 1)) { player->mo->angle = tails->angle; diff --git a/src/st_stuff.c b/src/st_stuff.c index 49f586976..89ce1d6d7 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2239,7 +2239,7 @@ static void ST_drawTextHUD(void) if (F_GetPromptHideHud(y)) return; - if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE)) + if (stplyr->spectator && (!G_CoopGametype() || stplyr->playerstate == PST_LIVE)) textHUDdraw(M_GetText("\x86""Spectator mode:")) if (circuitmap) @@ -2250,7 +2250,7 @@ static void ST_drawTextHUD(void) textHUDdraw(va("Lap:""\x82 %u/%d", stplyr->laps+1, cv_numlaps.value)) } - if (gametype != GT_COOP && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1))) + if (!G_CoopGametype() && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1))) { if (!splitscreen && !donef12) { @@ -2267,7 +2267,7 @@ static void ST_drawTextHUD(void) else textHUDdraw(M_GetText("\x82""JUMP:""\x80 Respawn")) } - else if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE)) + else if (stplyr->spectator && (!G_CoopGametype() || stplyr->playerstate == PST_LIVE)) { if (!splitscreen && !donef12) { @@ -2314,7 +2314,7 @@ static void ST_drawTextHUD(void) textHUDdraw(M_GetText("\x82""FIRE:""\x80 Enter game")) } - if (gametype == GT_COOP && (!stplyr->spectator || (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap))) && (stplyr->exiting || (stplyr->pflags & PF_FINISHED))) + if (G_CoopGametype() && (!stplyr->spectator || (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap))) && (stplyr->exiting || (stplyr->pflags & PF_FINISHED))) { UINT8 numneeded = (G_IsSpecialStage(gamemap) ? 4 : cv_playersforexit.value); if (numneeded) @@ -2683,7 +2683,7 @@ static void ST_overlayDrawer(void) } // GAME OVER hud - if ((gametype == GT_COOP) + if (G_GametypeUsesCoopLives() && (netgame || multiplayer) && (cv_cooplives.value == 0)) ; From ea756fd557d3155d5307ae17267d0fd6943493e8 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 29 Feb 2020 01:51:45 -0300 Subject: [PATCH 16/27] Make exitmove friendly, don't start empty intermission screens --- src/d_netcmd.c | 2 +- src/g_game.c | 7 ++++-- src/p_spec.c | 4 ++-- src/p_user.c | 4 ++-- src/y_inter.c | 63 +++++++++++++++++++++++++------------------------- src/y_inter.h | 4 ++++ 6 files changed, 45 insertions(+), 39 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index ed612aaef..196d67a60 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3743,7 +3743,7 @@ static void ExitMove_OnChange(void) { UINT8 i; - if (!(netgame || multiplayer) || !G_CoopGametype()) + if (!(netgame || multiplayer) || !(gametyperules & GTR_FRIENDLY)) return; if (cv_exitmove.value) diff --git a/src/g_game.c b/src/g_game.c index f0ca101fa..5c7b5fbcb 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3180,7 +3180,7 @@ void G_ExitLevel(void) CV_SetValue(&cv_teamscramble, cv_scrambleonchange.value); } - if (!(gametyperules & GTR_CAMPAIGN)) + if (!(gametyperules & (GTR_FRIENDLY|GTR_CAMPAIGN))) CONS_Printf(M_GetText("The round has ended.\n")); // Remove CEcho text on round end. @@ -3840,7 +3840,10 @@ static void G_DoCompleted(void) if (nextmap < NUMMAPS && !mapheaderinfo[nextmap]) P_AllocMapHeader(nextmap); - if ((skipstats && !modeattacking) || (spec && modeattacking && stagefailed)) + // If the current gametype has no intermission screen set, then don't start it. + Y_DetermineIntermissionType(); + + if ((skipstats && !modeattacking) || (spec && modeattacking && stagefailed) || (intertype == int_none)) { G_UpdateVisited(); G_AfterIntermission(); diff --git a/src/p_spec.c b/src/p_spec.c index f4057fba5..30379fcb7 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4100,7 +4100,7 @@ void P_SetupSignExit(player_t *player) if (!numfound && !(player->mo->target && player->mo->target->type == MT_SIGN) - && !(G_CoopGametype() && (netgame || multiplayer) && cv_exitmove.value)) + && !((gametyperules & GTR_FRIENDLY) && (netgame || multiplayer) && cv_exitmove.value)) P_SetTarget(&player->mo->target, thing); if (thing->state != &states[thing->info->spawnstate]) @@ -4131,7 +4131,7 @@ void P_SetupSignExit(player_t *player) if (!numfound && !(player->mo->target && player->mo->target->type == MT_SIGN) - && !(G_CoopGametype() && (netgame || multiplayer) && cv_exitmove.value)) + && !((gametyperules & GTR_FRIENDLY) && (netgame || multiplayer) && cv_exitmove.value)) P_SetTarget(&player->mo->target, thing); if (thing->state != &states[thing->info->spawnstate]) diff --git a/src/p_user.c b/src/p_user.c index 33329a929..d90300e01 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9925,7 +9925,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (player->exiting) { if (mo->target && mo->target->type == MT_SIGN && mo->target->spawnpoint - && !(G_CoopGametype() && (netgame || multiplayer) && cv_exitmove.value) + && !((gametyperules & GTR_FRIENDLY) && (netgame || multiplayer) && cv_exitmove.value) && !(twodlevel || (mo->flags2 & MF2_TWOD))) sign = mo->target; else if ((player->powers[pw_carry] == CR_NIGHTSMODE) @@ -11826,7 +11826,7 @@ void P_PlayerThink(player_t *player) if (player->pflags & PF_FINISHED) { - if ((G_CoopGametype() && cv_exitmove.value) && !G_EnoughPlayersFinished()) + if (((gametyperules & GTR_FRIENDLY) && cv_exitmove.value) && !G_EnoughPlayersFinished()) player->exiting = 0; else P_DoPlayerExit(player); diff --git a/src/y_inter.c b/src/y_inter.c index 36cb64d06..701739ad1 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -229,8 +229,7 @@ static void Y_IntermissionTokenDrawer(void) // // Y_ConsiderScreenBuffer // -// Can we copy the current screen -// to a buffer? +// Can we copy the current screen to a buffer? // void Y_ConsiderScreenBuffer(void) { @@ -256,9 +255,7 @@ void Y_ConsiderScreenBuffer(void) // // Y_RescaleScreenBuffer // -// Write the rescaled source picture, -// to the destination picture that -// has the current screen's resolutions. +// Write the rescaled source picture, to the destination picture that has the current screen's resolutions. // static void Y_RescaleScreenBuffer(void) { @@ -328,14 +325,6 @@ void Y_IntermissionDrawer(void) if (rendermode == render_none) return; - if (intertype == int_none) - { -#ifdef HAVE_BLUA - LUAh_IntermissionHUD(); -#endif - return; - } - if (!usebuffer) // Lactozilla: Renderer switching if (needpatchrecache) @@ -1196,6 +1185,34 @@ void Y_Ticker(void) } } +// +// Y_DetermineIntermissionType +// +// Determines the intermission type from the current gametype. +// +void Y_DetermineIntermissionType(void) +{ + // set to int_none initially + intertype = int_none; + + if (intermissiontypes[gametype] != int_none) + intertype = intermissiontypes[gametype]; + else if (gametype == GT_COOP) + intertype = (G_IsSpecialStage(gamemap)) ? int_spec : int_coop; + else if (gametype == GT_TEAMMATCH) + intertype = int_teammatch; + else if (gametype == GT_MATCH + || gametype == GT_TAG + || gametype == GT_HIDEANDSEEK) + intertype = int_match; + else if (gametype == GT_RACE) + intertype = int_race; + else if (gametype == GT_COMPETITION) + intertype = int_comp; + else if (gametype == GT_CTF) + intertype = int_ctf; +} + // // Y_StartIntermission // @@ -1217,12 +1234,11 @@ void Y_StartIntermission(void) if (!multiplayer) { timer = 0; - intertype = (G_IsSpecialStage(gamemap)) ? int_spec : int_coop; } else { - if (cv_inttime.value == 0 && gametype == GT_COOP) + if (cv_inttime.value == 0 && ((intertype == int_coop) || (intertype == int_spec))) timer = 0; else { @@ -1231,23 +1247,6 @@ void Y_StartIntermission(void) if (!timer) timer = 1; } - - if (intermissiontypes[gametype] != int_none) - intertype = intermissiontypes[gametype]; - else if (gametype == GT_COOP) - intertype = (G_IsSpecialStage(gamemap)) ? int_spec : int_coop; - else if (gametype == GT_TEAMMATCH) - intertype = int_teammatch; - else if (gametype == GT_MATCH - || gametype == GT_TAG - || gametype == GT_HIDEANDSEEK) - intertype = int_match; - else if (gametype == GT_RACE) - intertype = int_race; - else if (gametype == GT_COMPETITION) - intertype = int_comp; - else if (gametype == GT_CTF) - intertype = int_ctf; } // We couldn't display the intermission even if we wanted to. diff --git a/src/y_inter.h b/src/y_inter.h index 855844fcc..859144b1d 100644 --- a/src/y_inter.h +++ b/src/y_inter.h @@ -13,11 +13,15 @@ extern boolean usebuffer; void Y_IntermissionDrawer(void); void Y_Ticker(void); + void Y_StartIntermission(void); void Y_EndIntermission(void); + void Y_ConsiderScreenBuffer(void); void Y_CleanupScreenBuffer(void); +void Y_DetermineIntermissionType(void); + typedef enum { int_none, From db82a4a01bf388ab9a37dd5116061491653678c1 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 9 May 2020 17:26:27 -0300 Subject: [PATCH 17/27] Avoid a crash --- src/y_inter.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index c3a80007b..8240ce0fb 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -323,7 +323,6 @@ void Y_IntermissionDrawer(void) if (rendermode == render_none) return; - if (!usebuffer) // Lactozilla: Renderer switching if (needpatchrecache) { @@ -364,11 +363,11 @@ void Y_IntermissionDrawer(void) { if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx == 400) V_DrawScaledPatch(0, 0, V_SNAPTOLEFT, widebgpatch); - else + else if (bgpatch) V_DrawScaledPatch(0, 0, 0, bgpatch); } } - else + else if (bgtile) V_DrawPatchFill(bgtile); LUAh_IntermissionHUD(); From aab378fe1a2c7fd8e8f4b7734aff6100f422eb83 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 17 Jun 2020 14:19:19 -0400 Subject: [PATCH 18/27] Reduce code duplication by creating get_zlib_error function Reduce calls to gme_set_equalizer in I_LoadSong by moving it to I_PlaySong Return false if it fails to decompress VGZ data in some form. --- src/sdl/mixer_sound.c | 126 +++++++++++------------------------------- 1 file changed, 33 insertions(+), 93 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 5a086880a..c5b1455a2 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -219,6 +219,28 @@ static void var_cleanup(void) internal_volume = 100; } + +static const char* get_zlib_error(int zErr) +{ + switch (zErr) + { + case Z_ERRNO: + return "Z_ERRNO"; + case Z_STREAM_ERROR: + return "Z_STREAM_ERROR"; + case Z_DATA_ERROR: + return "Z_DATA_ERROR"; + case Z_MEM_ERROR: + return "Z_MEM_ERROR"; + case Z_BUF_ERROR: + return "Z_BUF_ERROR"; + case Z_VERSION_ERROR: + return "Z_VERSION_ERROR"; + default: + return "unknown error"; + } +} + /// ------------------------ /// Audio System /// ------------------------ @@ -498,51 +520,11 @@ void *I_GetSfx(sfxinfo_t *sfx) } } else - { - const char *errorType; - switch (zErr) - { - case Z_ERRNO: - errorType = "Z_ERRNO"; break; - case Z_STREAM_ERROR: - errorType = "Z_STREAM_ERROR"; break; - case Z_DATA_ERROR: - errorType = "Z_DATA_ERROR"; break; - case Z_MEM_ERROR: - errorType = "Z_MEM_ERROR"; break; - case Z_BUF_ERROR: - errorType = "Z_BUF_ERROR"; break; - case Z_VERSION_ERROR: - errorType = "Z_VERSION_ERROR"; break; - default: - errorType = "unknown error"; - } - CONS_Alert(CONS_ERROR,"Encountered %s when running inflate: %s\n", errorType, stream.msg); - } + CONS_Alert(CONS_ERROR,"Encountered %s when running inflate: %s\n", get_zlib_error(zErr), stream.msg); (void)inflateEnd(&stream); } else // Hold up, zlib's got a problem - { - const char *errorType; - switch (zErr) - { - case Z_ERRNO: - errorType = "Z_ERRNO"; break; - case Z_STREAM_ERROR: - errorType = "Z_STREAM_ERROR"; break; - case Z_DATA_ERROR: - errorType = "Z_DATA_ERROR"; break; - case Z_MEM_ERROR: - errorType = "Z_MEM_ERROR"; break; - case Z_BUF_ERROR: - errorType = "Z_BUF_ERROR"; break; - case Z_VERSION_ERROR: - errorType = "Z_VERSION_ERROR"; break; - default: - errorType = "unknown error"; - } - CONS_Alert(CONS_ERROR,"Encountered %s when running inflateInit: %s\n", errorType, stream.msg); - } + CONS_Alert(CONS_ERROR,"Encountered %s when running inflateInit: %s\n", get_zlib_error(zErr), stream.msg); Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up #else return NULL; // No zlib support @@ -1175,77 +1157,33 @@ boolean I_LoadSong(char *data, size_t len) if (zErr == Z_OK) // We're good to go { zErr = inflate(&stream, Z_FINISH); - if (zErr == Z_STREAM_END) { + if (zErr == Z_STREAM_END) + { // Run GME on new data if (!gme_open_data(inflatedData, inflatedLen, &gme, 44100)) { - gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; gme_start_track(gme, 0); current_track = 0; - gme_set_equalizer(gme, &eq); Mix_HookMusic(mix_gme, gme); Z_Free(inflatedData); // GME supposedly makes a copy for itself, so we don't need this lying around return true; } } else - { - const char *errorType; - switch (zErr) - { - case Z_ERRNO: - errorType = "Z_ERRNO"; break; - case Z_STREAM_ERROR: - errorType = "Z_STREAM_ERROR"; break; - case Z_DATA_ERROR: - errorType = "Z_DATA_ERROR"; break; - case Z_MEM_ERROR: - errorType = "Z_MEM_ERROR"; break; - case Z_BUF_ERROR: - errorType = "Z_BUF_ERROR"; break; - case Z_VERSION_ERROR: - errorType = "Z_VERSION_ERROR"; break; - default: - errorType = "unknown error"; - } - CONS_Alert(CONS_ERROR,"Encountered %s when running inflate: %s\n", errorType, stream.msg); - } + CONS_Alert(CONS_ERROR, "Encountered %s when running inflate: %s\n", get_zlib_error(zErr), stream.msg); (void)inflateEnd(&stream); } else // Hold up, zlib's got a problem - { - const char *errorType; - switch (zErr) - { - case Z_ERRNO: - errorType = "Z_ERRNO"; break; - case Z_STREAM_ERROR: - errorType = "Z_STREAM_ERROR"; break; - case Z_DATA_ERROR: - errorType = "Z_DATA_ERROR"; break; - case Z_MEM_ERROR: - errorType = "Z_MEM_ERROR"; break; - case Z_BUF_ERROR: - errorType = "Z_BUF_ERROR"; break; - case Z_VERSION_ERROR: - errorType = "Z_VERSION_ERROR"; break; - default: - errorType = "unknown error"; - } - CONS_Alert(CONS_ERROR,"Encountered %s when running inflateInit: %s\n", errorType, stream.msg); - } + CONS_Alert(CONS_ERROR, "Encountered %s when running inflateInit: %s\n", get_zlib_error(zErr), stream.msg); Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up + return false; #else - CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n"); - return true; + CONS_Alert(CONS_ERROR, "Cannot decompress VGZ; no zlib support\n"); + return false; #endif } else if (!gme_open_data(data, len, &gme, 44100)) - { - gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; - gme_set_equalizer(gme, &eq); return true; - } #endif #ifdef HAVE_MIXERX @@ -1360,6 +1298,8 @@ boolean I_PlaySong(boolean looping) #ifdef HAVE_LIBGME if (gme) { + gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; + gme_set_equalizer(gme, &eq); gme_start_track(gme, 0); current_track = 0; Mix_HookMusic(mix_gme, gme); From 26a2677863bdb30d21cfcce4ad16e529e2e6df8a Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 17 Jun 2020 14:31:49 -0400 Subject: [PATCH 19/27] Fix VGZ sometimes causing SRB2 to crash by not playing the song early in I_LoadSong --- src/sdl/mixer_sound.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index c5b1455a2..c512c7ac5 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -1162,9 +1162,6 @@ boolean I_LoadSong(char *data, size_t len) // Run GME on new data if (!gme_open_data(inflatedData, inflatedLen, &gme, 44100)) { - gme_start_track(gme, 0); - current_track = 0; - Mix_HookMusic(mix_gme, gme); Z_Free(inflatedData); // GME supposedly makes a copy for itself, so we don't need this lying around return true; } From 55bace797f1f58d18fbdc51a662a16a4d6494182 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 17 Jun 2020 14:50:22 -0400 Subject: [PATCH 20/27] Use SAMPLERATE for consistency with the rest of the code --- src/sdl/mixer_sound.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index c512c7ac5..ef34b266d 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -497,7 +497,7 @@ void *I_GetSfx(sfxinfo_t *sfx) zErr = inflate(&stream, Z_FINISH); if (zErr == Z_STREAM_END) { // Run GME on new data - if (!gme_open_data(inflatedData, inflatedLen, &emu, 44100)) + if (!gme_open_data(inflatedData, inflatedLen, &emu, SAMPLERATE)) { short *mem; UINT32 len; @@ -531,7 +531,7 @@ void *I_GetSfx(sfxinfo_t *sfx) #endif } // Try to read it as a GME sound - else if (!gme_open_data(lump, sfx->length, &emu, 44100)) + else if (!gme_open_data(lump, sfx->length, &emu, SAMPLERATE)) { short *mem; UINT32 len; @@ -1160,7 +1160,7 @@ boolean I_LoadSong(char *data, size_t len) if (zErr == Z_STREAM_END) { // Run GME on new data - if (!gme_open_data(inflatedData, inflatedLen, &gme, 44100)) + if (!gme_open_data(inflatedData, inflatedLen, &gme, SAMPLERATE)) { Z_Free(inflatedData); // GME supposedly makes a copy for itself, so we don't need this lying around return true; @@ -1179,7 +1179,7 @@ boolean I_LoadSong(char *data, size_t len) return false; #endif } - else if (!gme_open_data(data, len, &gme, 44100)) + else if (!gme_open_data(data, len, &gme, SAMPLERATE)) return true; #endif From b6ea242ba3a979a400d9c6f628ea53d26718f99d Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Thu, 18 Jun 2020 19:40:14 +0300 Subject: [PATCH 21/27] Faster and more correct OGL transparent surface sorting --- src/hardware/hw_main.c | 172 +++++++++++++++++------------------------ 1 file changed, 71 insertions(+), 101 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 3163b701a..97e0d46ed 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4400,28 +4400,66 @@ void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polyse numpolyplanes++; } +// putting sortindex and sortnode here so the comparator function can see them +gr_drawnode_t *sortnode; +size_t *sortindex; + +static int CompareDrawNodes(const void *p1, const void *p2) +{ + size_t n1 = *(const size_t*)p1; + size_t n2 = *(const size_t*)p2; + INT32 v1 = 0; + INT32 v2 = 0; + INT32 diff; + if (sortnode[n1].plane) + v1 = sortnode[n1].plane->drawcount; + else if (sortnode[n1].polyplane) + v1 = sortnode[n1].polyplane->drawcount; + else if (sortnode[n1].wall) + v1 = sortnode[n1].wall->drawcount; + else I_Error("CompareDrawNodes: n1 unknown"); + + if (sortnode[n2].plane) + v2 = sortnode[n2].plane->drawcount; + else if (sortnode[n2].polyplane) + v2 = sortnode[n2].polyplane->drawcount; + else if (sortnode[n2].wall) + v2 = sortnode[n2].wall->drawcount; + else I_Error("CompareDrawNodes: n2 unknown"); + + diff = v2 - v1; + if (diff == 0) I_Error("CompareDrawNodes: diff is zero"); + return diff; +} + +static int CompareDrawNodePlanes(const void *p1, const void *p2) +{ + size_t n1 = *(const size_t*)p1; + size_t n2 = *(const size_t*)p2; + if (!sortnode[n1].plane) I_Error("CompareDrawNodePlanes: Uh.. This isn't a plane! (n1)"); + if (!sortnode[n2].plane) I_Error("CompareDrawNodePlanes: Uh.. This isn't a plane! (n2)"); + return ABS(sortnode[n2].plane->fixedheight - viewz) - ABS(sortnode[n1].plane->fixedheight - viewz); +} + // // HWR_CreateDrawNodes // Creates and sorts a list of drawnodes for the scene being rendered. static void HWR_CreateDrawNodes(void) { - UINT32 i = 0, p = 0, prev = 0, loop; - const fixed_t pviewz = dup_viewz; + UINT32 i = 0, p = 0; + size_t run_start = 0; // Dump EVERYTHING into a huge drawnode list. Then we'll sort it! // Could this be optimized into _AddTransparentWall/_AddTransparentPlane? // Hell yes! But sort algorithm must be modified to use a linked list. - gr_drawnode_t *sortnode = Z_Calloc((sizeof(planeinfo_t)*numplanes) - + (sizeof(polyplaneinfo_t)*numpolyplanes) - + (sizeof(wallinfo_t)*numwalls) - ,PU_STATIC, NULL); + sortnode = Z_Calloc((sizeof(planeinfo_t)*numplanes) + + (sizeof(polyplaneinfo_t)*numpolyplanes) + + (sizeof(wallinfo_t)*numwalls) + ,PU_STATIC, NULL); // todo: // However, in reality we shouldn't be re-copying and shifting all this information // that is already lying around. This should all be in some sort of linked list or lists. - size_t *sortindex = Z_Calloc(sizeof(size_t) * (numplanes + numpolyplanes + numwalls), PU_STATIC, NULL); - - // If true, swap the draw order. - boolean shift = false; + sortindex = Z_Calloc(sizeof(size_t) * (numplanes + numpolyplanes + numwalls), PU_STATIC, NULL); rs_hw_nodesorttime = I_GetTimeMicros(); @@ -4447,104 +4485,36 @@ static void HWR_CreateDrawNodes(void) // p is the number of stuff to sort - // Add the 3D floors, thicksides, and masked textures... - // Instead of going through drawsegs, we need to iterate - // through the lists of masked textures and - // translucent ffloors being drawn. + // sort the list based on the value of the 'drawcount' member of the drawnodes. + qsort(sortindex, p, sizeof(size_t), CompareDrawNodes); - // This is a bubble sort! Wahoo! - - // Stuff is sorted: - // sortnode[sortindex[0]] = farthest away - // sortnode[sortindex[p-1]] = closest - // "i" should be closer. "prev" should be further. - // The lower drawcount is, the further it is from the screen. - - for (loop = 0; loop < p; loop++) + // an additional pass is needed to correct the order of consecutive planes in the list. + // for each consecutive run of planes in the list, sort that run based on plane height and view height. + while (run_start < p-1)// p-1 because a 1 plane run at the end of the list does not count { - for (i = 1; i < p; i++) + // locate run start + if (sortnode[sortindex[run_start]].plane) { - prev = i-1; - if (sortnode[sortindex[i]].plane) + // found it, now look for run end + size_t run_end;// (inclusive) + for (i = run_start+1; i < p; i++)// size_t and UINT32 being used mixed here... shouldnt break anything though.. { - // What are we comparing it with? - if (sortnode[sortindex[prev]].plane) - { - // Plane (i) is further away than plane (prev) - if (ABS(sortnode[sortindex[i]].plane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].plane->fixedheight - pviewz)) - shift = true; - } - if (sortnode[sortindex[prev]].polyplane) - { - // Plane (i) is further away than polyplane (prev) - if (ABS(sortnode[sortindex[i]].plane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].polyplane->fixedheight - pviewz)) - shift = true; - } - else if (sortnode[sortindex[prev]].wall) - { - // Plane (i) is further than wall (prev) - if (sortnode[sortindex[i]].plane->drawcount > sortnode[sortindex[prev]].wall->drawcount) - shift = true; - } + if (!sortnode[sortindex[i]].plane) break; } - else if (sortnode[sortindex[i]].polyplane) + run_end = i-1; + if (run_end > run_start)// if there are multiple consecutive planes, not just one { - // What are we comparing it with? - if (sortnode[sortindex[prev]].plane) - { - // Plane (i) is further away than plane (prev) - if (ABS(sortnode[sortindex[i]].polyplane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].plane->fixedheight - pviewz)) - shift = true; - } - if (sortnode[sortindex[prev]].polyplane) - { - // Plane (i) is further away than polyplane (prev) - if (ABS(sortnode[sortindex[i]].polyplane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].polyplane->fixedheight - pviewz)) - shift = true; - } - else if (sortnode[sortindex[prev]].wall) - { - // Plane (i) is further than wall (prev) - if (sortnode[sortindex[i]].polyplane->drawcount > sortnode[sortindex[prev]].wall->drawcount) - shift = true; - } + // consecutive run of planes found, now sort it + qsort(sortindex + run_start, run_end - run_start + 1, sizeof(size_t), CompareDrawNodePlanes); } - else if (sortnode[sortindex[i]].wall) - { - // What are we comparing it with? - if (sortnode[sortindex[prev]].plane) - { - // Wall (i) is further than plane(prev) - if (sortnode[sortindex[i]].wall->drawcount > sortnode[sortindex[prev]].plane->drawcount) - shift = true; - } - if (sortnode[sortindex[prev]].polyplane) - { - // Wall (i) is further than polyplane(prev) - if (sortnode[sortindex[i]].wall->drawcount > sortnode[sortindex[prev]].polyplane->drawcount) - shift = true; - } - else if (sortnode[sortindex[prev]].wall) - { - // Wall (i) is further than wall (prev) - if (sortnode[sortindex[i]].wall->drawcount > sortnode[sortindex[prev]].wall->drawcount) - shift = true; - } - } - - if (shift) - { - size_t temp; - - temp = sortindex[prev]; - sortindex[prev] = sortindex[i]; - sortindex[i] = temp; - - shift = false; - } - - } //i++ - } // loop++ + run_start = run_end + 1;// continue looking for runs coming right after this one + } + else + { + // this wasnt the run start, try next one + run_start++; + } + } rs_hw_nodesorttime = I_GetTimeMicros() - rs_hw_nodesorttime; From e1a8ea7663f5a8b070f0c8e51a6fd3db87033f7e Mon Sep 17 00:00:00 2001 From: lachwright Date: Fri, 19 Jun 2020 15:49:24 +0800 Subject: [PATCH 22/27] Fix the Eggman signpost's background color --- src/info.c | 2 +- src/p_enemy.c | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/info.c b/src/info.c index f0272fc79..bb76b538f 100644 --- a/src/info.c +++ b/src/info.c @@ -21691,7 +21691,7 @@ skincolor_t skincolors[MAXSKINCOLORS] = { {"Violet", {0xd0, 0xd1, 0xd2, 0xca, 0xcc, 0xb8, 0xb9, 0xb9, 0xba, 0xa8, 0xa8, 0xa9, 0xa9, 0xfd, 0xfe, 0xfe}, SKINCOLOR_MINT, 6, V_MAGENTAMAP, true}, // SKINCOLOR_VIOLET {"Lilac", {0x00, 0xd0, 0xd1, 0xd2, 0xd3, 0xc1, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc5, 0xc6, 0xc6, 0xfe, 0x1f}, SKINCOLOR_VAPOR, 4, V_ROSYMAP, true}, // SKINCOLOR_LILAC {"Plum", {0xc8, 0xd3, 0xd5, 0xd6, 0xd7, 0xce, 0xcf, 0xb9, 0xb9, 0xba, 0xba, 0xa9, 0xa9, 0xa9, 0xfd, 0xfe}, SKINCOLOR_MINT, 7, V_ROSYMAP, true}, // SKINCOLOR_PLUM - {"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 15, V_MAGENTAMAP, true}, // SKINCOLOR_RASPBERRY + {"Raspberry", {0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xcd, 0xce, 0xb9, 0xb9, 0xba, 0xba, 0xbb, 0xfe, 0xfe}, SKINCOLOR_APPLE, 13, V_MAGENTAMAP, true}, // SKINCOLOR_RASPBERRY {"Rosy", {0xfc, 0xc8, 0xc8, 0xc9, 0xc9, 0xca, 0xca, 0xcb, 0xcb, 0xcc, 0xcc, 0xcd, 0xcd, 0xce, 0xce, 0xcf}, SKINCOLOR_AQUA, 1, V_ROSYMAP, true}, // SKINCOLOR_ROSY // super diff --git a/src/p_enemy.c b/src/p_enemy.c index 578874574..1693d6e55 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5142,12 +5142,10 @@ void A_SignPlayer(mobj_t *actor) ; else if (!skin->sprites[SPR2_SIGN].numframes) signcolor = facecolor; - else if ((actor->target->player->skincolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor? + else if ((facecolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor? signcolor = skin->prefoppositecolor; - else if (actor->target->player->skincolor) // Set the sign to be an appropriate background color for this player's skincolor. - signcolor = skincolors[actor->target->player->skincolor].invcolor; - else - signcolor = SKINCOLOR_NONE; + else if (facecolor) // Set the sign to be an appropriate background color for this player's skincolor. + signcolor = skincolors[facecolor].invcolor; } else if (locvar1 != -3) // set to a defined skin { @@ -5205,12 +5203,12 @@ void A_SignPlayer(mobj_t *actor) } else // Eggman face { - ov->color = SKINCOLOR_NONE; ov->skin = NULL; if ((statenum_t)(ov->state-states) != actor->info->meleestate) P_SetMobjState(ov, actor->info->meleestate); // S_EGGMANSIGN if (!signcolor) signcolor = SKINCOLOR_CARBON; + ov->color = signcolor; } actor->tracer->color = signcolor; From c54cb042ba974f67849a389eb491dd4262239fa6 Mon Sep 17 00:00:00 2001 From: lachwright Date: Fri, 19 Jun 2020 15:59:09 +0800 Subject: [PATCH 23/27] lol should have tested before pushing --- src/p_enemy.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 1693d6e55..a9c160254 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5203,12 +5203,13 @@ void A_SignPlayer(mobj_t *actor) } else // Eggman face { + ov->color = SKINCOLOR_NONE; ov->skin = NULL; if ((statenum_t)(ov->state-states) != actor->info->meleestate) P_SetMobjState(ov, actor->info->meleestate); // S_EGGMANSIGN if (!signcolor) signcolor = SKINCOLOR_CARBON; - ov->color = signcolor; + facecolor = signcolor; } actor->tracer->color = signcolor; From 75da8067dcd0245cc2e2d1c956bf58c74a6f974f Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Fri, 19 Jun 2020 14:32:34 +0300 Subject: [PATCH 24/27] Faster OGL sprite sorting algorithm --- src/hardware/hw_glob.h | 3 - src/hardware/hw_main.c | 170 ++++++++++++++--------------------------- 2 files changed, 56 insertions(+), 117 deletions(-) diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 861c2f382..d8ea7c7a3 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -61,9 +61,6 @@ typedef struct // equivalent of the software renderer's vissprites typedef struct gr_vissprite_s { - // Doubly linked list - struct gr_vissprite_s *prev; - struct gr_vissprite_s *next; float x1, x2; float tz, ty; //lumpnum_t patchlumpnum; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index b89ffe9e6..54f172046 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -4179,96 +4179,45 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) // -------------------------------------------------------------------------- // Sort vissprites by distance // -------------------------------------------------------------------------- -static gr_vissprite_t gr_vsprsortedhead; +gr_vissprite_t* gr_vsprorder[MAXVISSPRITES]; -static void HWR_SortVisSprites(void) +// Note: For more correct transparency the transparent sprites would need to be +// sorted and drawn together with transparent surfaces. +static int CompareVisSprites(const void *p1, const void *p2) { - UINT32 i; - gr_vissprite_t *ds, *dsprev, *dsnext, *dsfirst; - gr_vissprite_t *best = NULL; - gr_vissprite_t unsorted; - float bestdist = 0.0f; - INT32 bestdispoffset = 0; - - if (!gr_visspritecount) - return; - - dsfirst = HWR_GetVisSprite(0); - - for (i = 0, dsnext = dsfirst, ds = NULL; i < gr_visspritecount; i++) - { - dsprev = ds; - ds = dsnext; - if (i < gr_visspritecount - 1) dsnext = HWR_GetVisSprite(i + 1); - - ds->next = dsnext; - ds->prev = dsprev; - } - - // Fix first and last. ds still points to the last one after the loop - dsfirst->prev = &unsorted; - unsorted.next = dsfirst; - if (ds) - ds->next = &unsorted; - unsorted.prev = ds; - - // pull the vissprites out by scale - gr_vsprsortedhead.next = gr_vsprsortedhead.prev = &gr_vsprsortedhead; - for (i = 0; i < gr_visspritecount; i++) - { - best = NULL; - for (ds = unsorted.next; ds != &unsorted; ds = ds->next) - { - if (!best || ds->tz > bestdist) - { - bestdist = ds->tz; - bestdispoffset = ds->dispoffset; - best = ds; - } - // order visprites of same scale by dispoffset, smallest first - else if (fabsf(ds->tz - bestdist) < 1.0E-36f && ds->dispoffset < bestdispoffset) - { - bestdispoffset = ds->dispoffset; - best = ds; - } - } - if (best) - { - best->next->prev = best->prev; - best->prev->next = best->next; - best->next = &gr_vsprsortedhead; - best->prev = gr_vsprsortedhead.prev; - } - gr_vsprsortedhead.prev->next = best; - gr_vsprsortedhead.prev = best; - } - + gr_vissprite_t* spr1 = *(gr_vissprite_t*const*)p1; + gr_vissprite_t* spr2 = *(gr_vissprite_t*const*)p2; + int idiff; + float fdiff; + + // Make transparent sprites last. Comment from the previous sort implementation: // Sryder: Oh boy, while it's nice having ALL the sprites sorted properly, it fails when we bring MD2's into the // mix and they want to be translucent. So let's place all the translucent sprites and MD2's AFTER // everything else, but still ordered of course, the depth buffer can handle the opaque ones plenty fine. // We just need to move all translucent ones to the end in order // TODO: Fully sort all sprites and MD2s with walls and floors, this part will be unnecessary after that - best = gr_vsprsortedhead.next; + int transparency1 = (spr1->mobj->flags2 & MF2_SHADOW) || (spr1->mobj->frame & FF_TRANSMASK); + int transparency2 = (spr2->mobj->flags2 & MF2_SHADOW) || (spr2->mobj->frame & FF_TRANSMASK); + idiff = transparency1 - transparency2; + if (idiff != 0) return idiff; + + fdiff = spr2->tz - spr1->tz; // this order seems correct when checking with apitrace. Back to front. + if (fabsf(fdiff) < 1.0E-36f) + return spr1->dispoffset - spr2->dispoffset; // smallest dispoffset first if sprites are at (almost) same location. + else if (fdiff > 0) + return 1; + else + return -1; +} + +static void HWR_SortVisSprites(void) +{ + UINT32 i; for (i = 0; i < gr_visspritecount; i++) { - if ((best->mobj->flags2 & MF2_SHADOW) || (best->mobj->frame & FF_TRANSMASK)) - { - if (best == gr_vsprsortedhead.next) - { - gr_vsprsortedhead.next = best->next; - } - best->prev->next = best->next; - best->next->prev = best->prev; - best->prev = gr_vsprsortedhead.prev; - gr_vsprsortedhead.prev->next = best; - gr_vsprsortedhead.prev = best; - ds = best; - best = best->next; - ds->next = &gr_vsprsortedhead; - } - else - best = best->next; + gr_vsprorder[i] = HWR_GetVisSprite(i); } + qsort(gr_vsprorder, gr_visspritecount, sizeof(gr_vissprite_t*), CompareVisSprites); } // A drawnode is something that points to a 3D floor, 3D side, or masked @@ -4605,52 +4554,45 @@ static void HWR_CreateDrawNodes(void) // added the stransform so they can be switched as drawing happenes so MD2s and sprites are sorted correctly with each other static void HWR_DrawSprites(void) { - if (gr_visspritecount > 0) + UINT32 i; + HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, cv_grmodellighting.value); + for (i = 0; i < gr_visspritecount; i++) { - gr_vissprite_t *spr; - HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, cv_grmodellighting.value); - - // draw all vissprites back to front - for (spr = gr_vsprsortedhead.next; - spr != &gr_vsprsortedhead; - spr = spr->next) - { + gr_vissprite_t *spr = gr_vsprorder[i]; #ifdef HWPRECIP - if (spr->precip) - HWR_DrawPrecipitationSprite(spr); - else + if (spr->precip) + HWR_DrawPrecipitationSprite(spr); + else #endif + { + if (spr->mobj && spr->mobj->shadowscale && cv_shadow.value) { - if (spr->mobj && spr->mobj->shadowscale && cv_shadow.value) - { - HWR_DrawDropShadow(spr->mobj, spr->mobj->shadowscale); - } + HWR_DrawDropShadow(spr->mobj, spr->mobj->shadowscale); + } - if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) - { - if (!cv_grmodels.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) - HWR_DrawSprite(spr); - else - { - if (!HWR_DrawModel(spr)) - HWR_DrawSprite(spr); - } - } + if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) + { + if (!cv_grmodels.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) + HWR_DrawSprite(spr); else { - if (!cv_grmodels.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) + if (!HWR_DrawModel(spr)) + HWR_DrawSprite(spr); + } + } + else + { + if (!cv_grmodels.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) + HWR_DrawSprite(spr); + else + { + if (!HWR_DrawModel(spr)) HWR_DrawSprite(spr); - else - { - if (!HWR_DrawModel(spr)) - HWR_DrawSprite(spr); - } } } } - - HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, 0); } + HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, 0); } // -------------------------------------------------------------------------- From 20447c68a58baf6acf31021c002dfcfccd0ce651 Mon Sep 17 00:00:00 2001 From: Hannu Hanhi Date: Fri, 19 Jun 2020 16:18:04 +0300 Subject: [PATCH 25/27] Don't repeatedly look for model texture files --- src/hardware/hw_md2.c | 14 ++++++++++++-- src/hardware/hw_md2.h | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 76c7f89b4..68b426f0c 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -375,7 +375,10 @@ static void md2_loadTexture(md2_t *model) #endif grpatch->mipmap->grInfo.format = PCX_Load(filename, &w, &h, grpatch); if (grpatch->mipmap->grInfo.format == 0) + { + model->notexturefile = true; // mark it so its not searched for again repeatedly return; + } grpatch->mipmap->downloaded = 0; grpatch->mipmap->flags = 0; @@ -430,6 +433,7 @@ static void md2_loadBlendTexture(md2_t *model) grpatch->mipmap->grInfo.format = PCX_Load(filename, &w, &h, grpatch); if (grpatch->mipmap->grInfo.format == 0) { + model->noblendfile = true; // mark it so its not searched for again repeatedly Z_Free(filename); return; } @@ -465,6 +469,8 @@ void HWR_InitModels(void) md2_playermodels[s].scale = -1.0f; md2_playermodels[s].model = NULL; md2_playermodels[s].grpatch = NULL; + md2_playermodels[s].notexturefile = false; + md2_playermodels[s].noblendfile = false; md2_playermodels[s].skin = -1; md2_playermodels[s].notfound = true; md2_playermodels[s].error = false; @@ -474,6 +480,8 @@ void HWR_InitModels(void) md2_models[i].scale = -1.0f; md2_models[i].model = NULL; md2_models[i].grpatch = NULL; + md2_models[i].notexturefile = false; + md2_models[i].noblendfile = false; md2_models[i].skin = -1; md2_models[i].notfound = true; md2_models[i].error = false; @@ -1298,12 +1306,14 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) finalscale = md2->scale; //Hurdler: arf, I don't like that implementation at all... too much crappy gpatch = md2->grpatch; - if (!gpatch || !gpatch->mipmap->grInfo.format || !gpatch->mipmap->downloaded) + if (!gpatch || ((!gpatch->mipmap->grInfo.format || !gpatch->mipmap->downloaded) && !md2->notexturefile)) md2_loadTexture(md2); gpatch = md2->grpatch; // Load it again, because it isn't being loaded into gpatch after md2_loadtexture... if ((gpatch && gpatch->mipmap->grInfo.format) // don't load the blend texture if the base texture isn't available - && (!md2->blendgrpatch || !((GLPatch_t *)md2->blendgrpatch)->mipmap->grInfo.format || !((GLPatch_t *)md2->blendgrpatch)->mipmap->downloaded)) + && (!md2->blendgrpatch + || ((!((GLPatch_t *)md2->blendgrpatch)->mipmap->grInfo.format || !((GLPatch_t *)md2->blendgrpatch)->mipmap->downloaded) + && !md2->noblendfile))) md2_loadBlendTexture(md2); if (gpatch && gpatch->mipmap->grInfo.format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture diff --git a/src/hardware/hw_md2.h b/src/hardware/hw_md2.h index faa91caee..42a9d7c63 100644 --- a/src/hardware/hw_md2.h +++ b/src/hardware/hw_md2.h @@ -28,7 +28,9 @@ typedef struct float offset; model_t *model; void *grpatch; + boolean notexturefile; // true if texture file was not found void *blendgrpatch; + boolean noblendfile; // true if blend texture file was not found boolean notfound; INT32 skin; boolean error; From 97ebb50e127a10a46fc65cd4b594010638c77481 Mon Sep 17 00:00:00 2001 From: sphere Date: Sun, 21 Jun 2020 16:01:24 +0200 Subject: [PATCH 26/27] Give ACZ3 boss MF_NOCLIP(HEIGHT) when entering pinch phase, to prevent softlocking. --- src/dehacked.c | 2 ++ src/info.c | 12 +++++++----- src/info.h | 4 +++- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 61775bd56..78120c5c4 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -5756,10 +5756,12 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_FANG_PINCHPATHINGSTART1", "S_FANG_PINCHPATHINGSTART2", "S_FANG_PINCHPATHING", + "S_FANG_PINCHBOUNCE0", "S_FANG_PINCHBOUNCE1", "S_FANG_PINCHBOUNCE2", "S_FANG_PINCHBOUNCE3", "S_FANG_PINCHBOUNCE4", + "S_FANG_PINCHFALL0", "S_FANG_PINCHFALL1", "S_FANG_PINCHFALL2", "S_FANG_PINCHSKID1", diff --git a/src/info.c b/src/info.c index f0272fc79..48c2cd666 100644 --- a/src/info.c +++ b/src/info.c @@ -1430,11 +1430,13 @@ state_t states[NUMSTATES] = {SPR_FANG, 8, 0, {A_PrepareRepeat}, 1, 0, S_FANG_PINCHPATHINGSTART2}, // S_FANG_PINCHPATHINGSTART1 {SPR_FANG, 8, 0, {A_PlayActiveSound}, 0, 0, S_FANG_PINCHPATHING}, // S_FANG_PINCHPATHINGSTART2 - {SPR_FANG, 8, 0, {A_Boss5FindWaypoint}, 1, 0, S_FANG_PINCHBOUNCE1}, // S_FANG_PINCHPATHING + {SPR_FANG, 8, 0, {A_Boss5FindWaypoint}, 1, 0, S_FANG_PINCHBOUNCE0}, // S_FANG_PINCHPATHING + {SPR_FANG, 8, 0, {A_SetObjectFlags}, MF_NOCLIP|MF_NOCLIPHEIGHT, 2, S_FANG_PINCHBOUNCE1}, // S_FANG_PINCHBOUNCE0 {SPR_FANG, 8, 2, {A_Thrust}, 0, 1, S_FANG_PINCHBOUNCE2}, // S_FANG_PINCHBOUNCE1 {SPR_FANG, 9, 2, {NULL}, 0, 0, S_FANG_PINCHBOUNCE3}, // S_FANG_PINCHBOUNCE2 {SPR_FANG, 10, 2, {A_Boss5Jump}, 0, 0, S_FANG_PINCHBOUNCE4}, // S_FANG_PINCHBOUNCE3 - {SPR_FANG, 10, 1, {A_Boss5CheckFalling}, S_FANG_PINCHSKID1, S_FANG_PINCHFALL1, S_FANG_PINCHBOUNCE4}, // S_FANG_PINCHBOUNCE4 + {SPR_FANG, 10, 1, {A_Boss5CheckFalling}, S_FANG_PINCHSKID1, S_FANG_PINCHFALL0, S_FANG_PINCHBOUNCE4}, // S_FANG_PINCHBOUNCE4 + {SPR_FANG, 12, 0, {A_SetObjectFlags}, MF_NOCLIP|MF_NOCLIPHEIGHT, 1, S_FANG_PINCHFALL1}, // S_FANG_PINCHFALL0 {SPR_FANG, 12, 1, {A_Boss5CheckOnGround}, S_FANG_PINCHSKID1, 0, S_FANG_PINCHFALL2}, // S_FANG_PINCHFALL1 {SPR_FANG, 13, 1, {A_Boss5CheckOnGround}, S_FANG_PINCHSKID1, 0, S_FANG_PINCHFALL1}, // S_FANG_PINCHFALL2 {SPR_FANG, 4, 0, {A_PlayAttackSound}, 0, 0, S_FANG_PINCHSKID2}, // S_FANG_PINCHSKID1 @@ -3362,7 +3364,7 @@ state_t states[NUMSTATES] = // CTF Sign {SPR_GFLG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_GOTFLAG - + // Finish flag {SPR_FNSF, FF_TRANS30, -1, {NULL}, 0, 0, S_NULL}, // S_FINISHFLAG @@ -18010,7 +18012,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, - + { // MT_FINISHFLAG -1, // doomednum S_FINISHFLAG, // spawnstate @@ -19855,7 +19857,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags S_NULL // raisestate }, - + { // MT_FLINGNIGHTSSTAR -1, // doomednum S_NIGHTSSTAR, // spawnstate diff --git a/src/info.h b/src/info.h index 79af9bbbb..476ad2b73 100644 --- a/src/info.h +++ b/src/info.h @@ -1608,10 +1608,12 @@ typedef enum state S_FANG_PINCHPATHINGSTART1, S_FANG_PINCHPATHINGSTART2, S_FANG_PINCHPATHING, + S_FANG_PINCHBOUNCE0, S_FANG_PINCHBOUNCE1, S_FANG_PINCHBOUNCE2, S_FANG_PINCHBOUNCE3, S_FANG_PINCHBOUNCE4, + S_FANG_PINCHFALL0, S_FANG_PINCHFALL1, S_FANG_PINCHFALL2, S_FANG_PINCHSKID1, @@ -3498,7 +3500,7 @@ typedef enum state // Got Flag Sign S_GOTFLAG, - + // Finish flag S_FINISHFLAG, From 5d818564270a7dadea8afcc5038b17903f5f9244 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Mon, 22 Jun 2020 21:11:33 +0200 Subject: [PATCH 27/27] Fix missing bruh string in lua side options. This is stupid. --- src/lua_maplib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index ece42b8d3..b7a779ed6 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -139,6 +139,7 @@ static const char *const side_opt[] = { "toptexture", "bottomtexture", "midtexture", + "line", "sector", "special", "repeatcnt",