diff --git a/src/g_game.c b/src/g_game.c index fae311694c0caa193b13131f31891a4b46e8df82..877a4c72e0e1d5d014b72110b03eb5b8190c9232 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3330,7 +3330,7 @@ void G_AddPlayer(INT32 playernum) p->lives = cv_startinglives.value; if ((countplayers && !notexiting) || G_IsSpecialStage(gamemap)) - P_DoPlayerExit(p); + P_DoPlayerExit(p, false); } boolean G_EnoughPlayersFinished(void) @@ -3863,12 +3863,13 @@ static INT16 RandMap(UINT32 tolflags, INT16 pprevmap) // // G_UpdateVisited // -static void G_UpdateVisited(gamedata_t *data, player_t *player, boolean silent) +static void G_UpdateVisited(gamedata_t *data, player_t *player, boolean global) { // Update visitation flags? if (!demoplayback && G_CoopGametype() // Campaign mode - && !stagefailed) // Did not fail the stage + && !stagefailed // Did not fail the stage + && (global || player->pflags & PF_FINISHED)) // Actually beat the stage { UINT8 earnedEmblems; UINT16 totalrings = 0; @@ -3906,12 +3907,12 @@ static void G_UpdateVisited(gamedata_t *data, player_t *player, boolean silent) data->mapvisited[gamemap-1] |= MV_ALLEMERALDS; } - if ((earnedEmblems = M_CompletionEmblems(data)) && !silent) + if ((earnedEmblems = M_CompletionEmblems(data)) && !global) { CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)earnedEmblems, earnedEmblems > 1 ? "s" : ""); } - if (silent) + if (global) { M_CheckLevelEmblems(data); } diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 8cb6d185df3910eccf36038ff40f3f9c5670d5c2..063c79dc41b4eb9ebe225bc56399ef76ceaaf4e8 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1546,11 +1546,12 @@ static int lib_pDoPlayerFinish(lua_State *L) static int lib_pDoPlayerExit(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + boolean finishedflag = lua_opttrueboolean(L, 2); NOHUD INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); - P_DoPlayerExit(player); + P_DoPlayerExit(player, finishedflag); return 0; } diff --git a/src/netcode/d_netcmd.c b/src/netcode/d_netcmd.c index 5afa955610a6aee452790fe0ca74b13fc7007d86..12c1b95c6d28ba802155d6230c22905049da6065 100644 --- a/src/netcode/d_netcmd.c +++ b/src/netcode/d_netcmd.c @@ -4035,7 +4035,7 @@ 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) + if (players[i].pflags & PF_FINISHED && !(players[i].exiting)) P_GiveFinishFlags(&players[i]); } diff --git a/src/p_enemy.c b/src/p_enemy.c index 93c828fbecd1394e1adbeac6aa3fd43cc43437b6..e210fe1e3f305b614637260f1933823f603782dc 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3951,7 +3951,7 @@ static void P_DoBossVictory(mobj_t *mo) { if (!playeringame[i]) continue; - P_DoPlayerExit(&players[i]); + P_DoPlayerExit(&players[i], true); } } else @@ -10820,7 +10820,7 @@ void A_ForceWin(mobj_t *actor) { if (!playeringame[i]) continue; - P_DoPlayerExit(&players[i]); + P_DoPlayerExit(&players[i], true); } } diff --git a/src/p_local.h b/src/p_local.h index 4b330184bddd915ea155ca1741b6b03bf80f43d8..84f33e54a85602d383d4d1f8841e612ce25cb52d 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -188,7 +188,7 @@ void P_DoPityCheck(player_t *player); void P_PlayerThink(player_t *player); void P_PlayerAfterThink(player_t *player); void P_DoPlayerFinish(player_t *player); -void P_DoPlayerExit(player_t *player); +void P_DoPlayerExit(player_t *player, boolean finishedflag); void P_NightserizePlayer(player_t *player, INT32 ptime); void P_InstaThrust(mobj_t *mo, angle_t angle, fixed_t move); diff --git a/src/p_mobj.c b/src/p_mobj.c index a81845918b64f5ceb74f41f303c43da579bafc55..03c992092562bf55ad24aa54715ea7a59b2392de 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11715,7 +11715,7 @@ void P_AfterPlayerSpawn(INT32 playernum) if (CheckForReverseGravity) P_CheckGravity(mobj, false); - if (p->pflags & PF_FINISHED) + if (p->pflags & PF_FINISHED && !(p->exiting)) P_GiveFinishFlags(p); } diff --git a/src/p_spec.c b/src/p_spec.c index 28ecc60f4dedb5f67f9aa33e092232eb0b3782f6..49b9309471798bb1085789eb2d7c5b681570b8bd 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3662,7 +3662,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) { if (!playeringame[i]) continue; - P_DoPlayerExit(&players[i]); + P_DoPlayerExit(&players[i], true); } } } @@ -3716,7 +3716,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) { if (!playeringame[i]) continue; - P_DoPlayerExit(&players[i]); + P_DoPlayerExit(&players[i], true); } } } @@ -4477,7 +4477,7 @@ static void P_ProcessEggCapsule(player_t *player, sector_t *sector) { if (!playeringame[i]) continue; - P_DoPlayerExit(&players[i]); + P_DoPlayerExit(&players[i], true); } } @@ -4787,7 +4787,7 @@ static void P_ProcessFinishLine(player_t *player) HU_DoCEcho("FINISHED!"); } - P_DoPlayerExit(player); + P_DoPlayerExit(player, true); } } diff --git a/src/p_user.c b/src/p_user.c index 24e3f8111d64961ad38f9b26801989539c3fd52e..e41f335cc24e9e1636eec304ac83922e4e9abc2f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -892,7 +892,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) players[i].marescore = 0; players[i].spheres = players[i].rings = 0; - P_DoPlayerExit(&players[i]); + P_DoPlayerExit(&players[i], true); } } else if (oldmare != player->mare) @@ -2188,7 +2188,7 @@ void P_DoPlayerFinish(player_t *player) // P_DoPlayerExit // // Player exits the map via sector trigger -void P_DoPlayerExit(player_t *player) +void P_DoPlayerExit(player_t *player, boolean finishedflag) { if (player->exiting) return; @@ -2209,7 +2209,11 @@ void P_DoPlayerExit(player_t *player) player->exiting = (14*TICRATE)/5 + 1; } else + { player->exiting = (14*TICRATE)/5 + 2; // Accidental death safeguard??? + if (finishedflag) + player->pflags |= PF_FINISHED; // Give PF_FINISHED as proof of a true finish + } //player->pflags &= ~PF_GLIDING; if (player->climbing) @@ -11782,7 +11786,7 @@ void P_PlayerThink(player_t *player) if (((gametyperules & GTR_FRIENDLY) && cv_exitmove.value) && !G_EnoughPlayersFinished()) player->exiting = 0; else - P_DoPlayerExit(player); + P_DoPlayerExit(player, false); } // check water content, set stuff in mobj @@ -11831,7 +11835,7 @@ void P_PlayerThink(player_t *player) } // Synchronizes the "real" amount of time spent in the level. - if (!player->exiting && !stoppedclock) + if (!player->exiting && !(player->pflags & PF_FINISHED) && !stoppedclock) { if (gametyperules & GTR_RACE) { diff --git a/src/y_inter.c b/src/y_inter.c index 69dc931ba8cfde0c816baeb8508ce02f758c10bb..453a9c4612a21aa37445e151ac7b47447084ad21 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -2043,7 +2043,7 @@ static void Y_AwardCoopBonuses(void) y_bonus_t localbonuses[4]; // set score/total first - data.coop.total = players[consoleplayer].recordscore; + data.coop.total = (players[consoleplayer].pflags & PF_FINISHED) ? players[consoleplayer].recordscore : 0; data.coop.score = players[consoleplayer].score; data.coop.gotperfbonus = -1; memset(data.coop.bonuses, 0, sizeof(data.coop.bonuses)); @@ -2060,7 +2060,12 @@ static void Y_AwardCoopBonuses(void) for (j = 0; j < 4; ++j) // Set bonuses { - (bonuses_list[bonusnum][j])(&players[i], &localbonuses[j]); + //Set the bonus, but only if we actually finished + if (players[i].pflags & PF_FINISHED) + (bonuses_list[bonusnum][j])(&players[i], &localbonuses[j]); + else + Y_SetNullBonus(&players[i], &localbonuses[j]); + players[i].score += localbonuses[j].points; if (players[i].score > MAXSCORE) players[i].score = MAXSCORE;