From 50496970d143a8a6faefa86ffeda518d81970675 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 3 Jul 2017 15:43:29 +0100 Subject: [PATCH] Fix weird visual artifacting caused by restarting the level in co-op, which was a direct result of my code being messy. This is significantly better to deal with, anyways. --- src/d_clisrv.c | 5 ++ src/d_clisrv.h | 1 + src/d_player.h | 1 + src/g_game.c | 195 ++++++++++++++++++------------------------------- src/p_mobj.c | 10 +-- src/p_user.c | 11 ++- 6 files changed, 88 insertions(+), 135 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 6705e6dcd..673b00957 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -891,6 +891,7 @@ static inline void resynch_write_others(resynchend_pak *rst) UINT8 i; rst->ingame = 0; + rst->outofcoop = 0; for (i = 0; i < MAXPLAYERS; ++i) { @@ -907,6 +908,8 @@ static inline void resynch_write_others(resynchend_pak *rst) if (!players[i].spectator) rst->ingame |= (1<outofcoop |= (1<ctfteam[i] = (INT32)LONG(players[i].ctfteam); rst->score[i] = (UINT32)LONG(players[i].score); rst->numboxes[i] = SHORT(players[i].numboxes); @@ -923,11 +926,13 @@ static inline void resynch_read_others(resynchend_pak *p) { UINT8 i; UINT32 loc_ingame = (UINT32)LONG(p->ingame); + UINT32 loc_outofcoop = (UINT32)LONG(p->outofcoop); for (i = 0; i < MAXPLAYERS; ++i) { // We don't care if they're in the game or not, just write all the data. players[i].spectator = !(loc_ingame & (1<ctfteam[i]); // no, 0 does not mean spectator, at least not in Match players[i].score = (UINT32)LONG(p->score[i]); players[i].numboxes = SHORT(p->numboxes[i]); diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 1ca82fdc5..fdee80c5e 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -136,6 +136,7 @@ typedef struct fixed_t flagz[2]; UINT32 ingame; // Spectator bit for each player + UINT32 outofcoop; // outofcoop bit for each player INT32 ctfteam[MAXPLAYERS]; // Which team? (can't be 1 bit, since in regular Match there are no teams) // Resynch game scores and the like all at once diff --git a/src/d_player.h b/src/d_player.h index 4e4a53a08..98af2a267 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -471,6 +471,7 @@ typedef struct player_s angle_t awayviewaiming; // Used for cut-away view boolean spectator; + boolean outofcoop; UINT8 bot; tic_t jointime; // Timer when player joins game to change skin/color diff --git a/src/g_game.c b/src/g_game.c index ec41449d8..b5b0b5f99 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2090,6 +2090,7 @@ void G_PlayerReborn(INT32 player) UINT32 availabilities; tic_t jointime; boolean spectator; + boolean outofcoop; INT16 bot; SINT8 pity; @@ -2100,6 +2101,7 @@ void G_PlayerReborn(INT32 player) exiting = players[player].exiting; jointime = players[player].jointime; spectator = players[player].spectator; + outofcoop = players[player].outofcoop; pflags = (players[player].pflags & (PF_TIMEOVER|PF_FLIPCAM|PF_TAGIT|PF_TAGGED|PF_ANALOGMODE)); // As long as we're not in multiplayer, carry over cheatcodes from map to map @@ -2154,6 +2156,7 @@ void G_PlayerReborn(INT32 player) p->ctfteam = ctfteam; p->jointime = jointime; p->spectator = spectator; + p->outofcoop = outofcoop; // save player config truth reborn p->skincolor = skincolor; @@ -2489,26 +2492,13 @@ void G_ChangePlayerReferences(mobj_t *oldmo, mobj_t *newmo) } } -#ifdef HAVE_BLUA -#define RESETMAP {\ - LUAh_MapChange();\ - G_DoLoadLevel(true);\ - return;\ - } -#else -#define RESETMAP {\ - G_DoLoadLevel(true);\ - return;\ - } -#endif - // // G_DoReborn // void G_DoReborn(INT32 playernum) { player_t *player = &players[playernum]; - boolean starpost = false; + boolean resetlevel = false; if (modeattacking) { @@ -2534,8 +2524,64 @@ void G_DoReborn(INT32 playernum) B_RespawnBot(playernum); if (oldmo) G_ChangePlayerReferences(oldmo, players[playernum].mo); + + return; } - else if (countdowntimeup || (!multiplayer && gametype == GT_COOP)) + + if (countdowntimeup || (!multiplayer && gametype == GT_COOP)) + resetlevel = true; + else if (gametype == GT_COOP && (netgame || multiplayer)) + { + INT32 i; + if (player->lives <= 0) // consider game over first + { + INT32 deadtimercheck = INT32_MAX; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + if (players[i].exiting || players[i].lives > 0) + break; + if (players[i].playerstate == PST_DEAD && players[i].deadtimer < deadtimercheck) + deadtimercheck = players[i].deadtimer; + } + + if (!countdown2 && i == MAXPLAYERS && deadtimercheck >= 8*TICRATE) + { + // They're dead, Jim. + //nextmapoverride = spstage_start; + nextmapoverride = gamemap; + countdown2 = TICRATE; + skipstats = true; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i]) + players[i].score = 0; + } + + //emeralds = 0; + tokenbits = 0; + tokenlist = 0; + token = 0; + } + } + if (cv_coopstarposts.value == 2) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (players[i].playerstate != PST_DEAD && !players[i].spectator && players[i].mo && players[i].mo->health) + break; + } + if (i == MAXPLAYERS) + resetlevel = true; + } + } + + if (resetlevel) { // reload the level from scratch if (countdowntimeup) @@ -2557,9 +2603,6 @@ void G_DoReborn(INT32 playernum) // Do a wipe wipegamestate = -1; - if (player->starposttime) - starpost = true; - if (camera.chase) P_ResetCamera(&players[displayplayer], &camera); if (camera2.chase && splitscreen) @@ -2579,7 +2622,7 @@ void G_DoReborn(INT32 playernum) CON_ClearHUD(); // Starpost support - G_SpawnPlayer(playernum, starpost); + G_SpawnPlayer(playernum, (player->starposttime)); if (botingame) { // Bots respawn next to their master. @@ -2588,123 +2631,25 @@ void G_DoReborn(INT32 playernum) } } else - RESETMAP; + { +#ifdef HAVE_BLUA + LUAh_MapChange(); +#endif + G_DoLoadLevel(true); + return; + } } else { // respawn at the start mobj_t *oldmo = NULL; - if (gametype == GT_COOP && (netgame || multiplayer)) - { - INT32 i; - if (player->lives <= 0) // consider game over first - { - INT32 deadtimercheck = INT32_MAX; - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - if (players[i].exiting || players[i].lives > 0) - break; - if (players[i].playerstate == PST_DEAD && players[i].deadtimer < deadtimercheck) - deadtimercheck = players[i].deadtimer; - } - - if (!countdown2 && i == MAXPLAYERS && deadtimercheck >= 8*TICRATE) - { - // They're dead, Jim. - //nextmapoverride = spstage_start; - nextmapoverride = gamemap; - countdown2 = TICRATE; - skipstats = true; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i]) - players[i].score = 0; - } - - //emeralds = 0; - tokenbits = 0; - tokenlist = 0; - token = 0; - } - } - if (cv_coopstarposts.value == 2) - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - - if (players[i].playerstate != PST_DEAD && !players[i].spectator && players[i].mo && players[i].mo->health) - break; - } - if (i == MAXPLAYERS) - { - if (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD) - { - INT32 j; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - - players[i].playerstate = PST_REBORN; - } - - P_LoadThingsOnly(); - P_ClearStarPost(player->starpostnum); - - // Do a wipe - wipegamestate = -1; - - if (camera.chase) - P_ResetCamera(&players[displayplayer], &camera); - if (camera2.chase && splitscreen) - P_ResetCamera(&players[secondarydisplayplayer], &camera2); - - // clear cmd building stuff - memset(gamekeydown, 0, sizeof (gamekeydown)); - for (j = 0; j < JOYAXISSET; j++) - { - joyxmove[j] = joyymove[j] = 0; - joy2xmove[j] = joy2ymove[j] = 0; - } - mousex = mousey = 0; - mouse2x = mouse2y = 0; - - // clear hud messages remains (usually from game startup) - CON_ClearHUD(); - - // Starpost support - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - - G_SpawnPlayer(i, (players[i].starposttime != 0)); - } - - return; - } - else - RESETMAP; - } - } - } - // Not resetting map, so return to level music if (!countdown2 && player->lives <= 0 && !cv_cooplives.value) // not allowed for life steal because no way to come back from zero group lives without addons, which should call this anyways P_RestoreMultiMusic(player); - if (player->starposttime) - starpost = true; - // first dissasociate the corpse if (player->mo) { @@ -2713,7 +2658,7 @@ void G_DoReborn(INT32 playernum) P_RemoveMobj(player->mo); } - G_SpawnPlayer(playernum, starpost); + G_SpawnPlayer(playernum, (player->starposttime)); if (oldmo) G_ChangePlayerReferences(oldmo, players[playernum].mo); } diff --git a/src/p_mobj.c b/src/p_mobj.c index 3e698990f..5b5fceec3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9099,14 +9099,12 @@ void P_SpawnPlayer(INT32 playernum) // spawn as spectator determination if (!G_GametypeHasSpectators()) { - if (((multiplayer || netgame) && gametype == GT_COOP) // only question status in coop + p->spectator = p->outofcoop = + (((multiplayer || netgame) && gametype == GT_COOP) // only question status in coop && ((leveltime > 0 && ((G_IsSpecialStage(gamemap) && useNightsSS) // late join special stage - || (cv_coopstarposts.value == 2 && (p->jointime < 1 || p->spectator)))) // late join or die in new coop - || ((!cv_cooplives.value || !P_GetLives(p)) && p->lives <= 0))) // game over and can't redistribute lives - p->spectator = true; - else - p->spectator = false; + || (cv_coopstarposts.value == 2 && (p->jointime < 1 || p->outofcoop)))) // late join or die in new coop + || ((!cv_cooplives.value || !P_GetLives(p)) && p->lives <= 0))); // game over and can't redistribute lives } else if (netgame && p->jointime < 1) p->spectator = true; diff --git a/src/p_user.c b/src/p_user.c index 736e514dd..427023048 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8214,7 +8214,8 @@ static void P_ConsiderAllGone(void) if (i == MAXPLAYERS && lastdeadplayer != -1 && deadtimercheck > 2*TICRATE) // the last killed player will reset the level in G_DoReborn { - players[lastdeadplayer].spectator = true; + //players[lastdeadplayer].spectator = true; + players[lastdeadplayer].outofcoop = true; players[lastdeadplayer].playerstate = PST_REBORN; } } @@ -8287,7 +8288,8 @@ static void P_DeathThink(player_t *player) P_ConsiderAllGone(); if ((player->deadtimer > 5*TICRATE) || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE))) { - player->spectator = true; + //player->spectator = true; + player->outofcoop = true; player->playerstate = PST_REBORN; } } @@ -8352,7 +8354,8 @@ static void P_DeathThink(player_t *player) if (gametype == GT_COOP && (player->lives <= 0) && (player->deadtimer >= 8*TICRATE || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))) { - player->spectator = true; + //player->spectator = true; + player->outofcoop = true; player->playerstate = PST_REBORN; } @@ -9099,7 +9102,7 @@ boolean P_SpectatorJoinGame(player_t *player) P_RemoveMobj(player->mo); player->mo = NULL; } - player->spectator = false; + player->spectator = player->outofcoop = false; player->playerstate = PST_REBORN; if (gametype == GT_TAG)