From e9a8c2d21ae362ea08b1d26857eaba0201f16675 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Sun, 19 Jan 2020 14:30:05 -0300 Subject: [PATCH 1/9] No more losing lives when finished --- src/p_inter.c | 3 ++- src/st_stuff.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 71dcd70a1..5e1f7345c 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2527,7 +2527,8 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget else if (!target->player->bot && !target->player->spectator && (target->player->lives != INFLIVES) && G_GametypeUsesLives()) { - target->player->lives -= 1; // Lose a life Tails 03-11-2000 + if (!(target->player->pflags & PF_FINISHED)) + target->player->lives -= 1; // Lose a life Tails 03-11-2000 if (target->player->lives <= 0) // Tails 03-14-2000 { diff --git a/src/st_stuff.c b/src/st_stuff.c index 4676506fc..9c9c80164 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -944,7 +944,7 @@ static void ST_drawLivesArea(void) '\x16' | 0x80 | hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, false); else { - if (stplyr->playerstate == PST_DEAD && !(stplyr->spectator) && (livescount || stplyr->deadtimer < (TICRATE<<1))) + if (stplyr->playerstate == PST_DEAD && !(stplyr->spectator) && (livescount || stplyr->deadtimer < (TICRATE<<1)) && !(stplyr->pflags & PF_FINISHED)) livescount++; if (livescount > 99) livescount = 99; From 9e4c519cad14c7d913da97dc3c23788b32729f35 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Sun, 19 Jan 2020 19:02:03 -0300 Subject: [PATCH 2/9] In-map visual indicator --- src/d_netcmd.c | 12 +++++++++--- src/dehacked.c | 4 ++++ src/hardware/hw_light.c | 1 + src/info.c | 33 ++++++++++++++++++++++++++++++++- src/info.h | 5 +++++ src/p_local.h | 1 + src/p_mobj.c | 29 +++++++++++++++++++++++++++++ src/p_user.c | 27 +++++++++++++++++++++++++++ 8 files changed, 108 insertions(+), 4 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index a597bad83..058c95196 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3736,9 +3736,15 @@ static void ExitMove_OnChange(void) if (cv_exitmove.value) { for (i = 0; i < MAXPLAYERS; ++i) - if (playeringame[i] && players[i].mo - && players[i].mo->target && players[i].mo->target->type == MT_SIGN) - P_SetTarget(&players[i].mo->target, NULL); + if (playeringame[i] && players[i].mo) + { + 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 diff --git a/src/dehacked.c b/src/dehacked.c index 082adda24..b85133b79 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7482,6 +7482,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Got Flag Sign "S_GOTFLAG", + + // Finish flag + "S_FINISHFLAG", "S_CORK", "S_LHRT", @@ -8601,6 +8604,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_LOCKONINF", // In-level Target "MT_TAG", // Tag Sign "MT_GOTFLAG", // Got Flag sign + "MT_FINISHFLAG", // Finish flag // Ambient Sounds "MT_AWATERA", // Ambient Water Sound 1 diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 8545a88b3..c5af8d6d3 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -509,6 +509,7 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_LCKN &lspr[NOLIGHT], // SPR_TTAG &lspr[NOLIGHT], // SPR_GFLG + &lspr[NOLIGHT], // SPR_FNSF &lspr[NOLIGHT], // SPR_CORK &lspr[NOLIGHT], // SPR_LHRT diff --git a/src/info.c b/src/info.c index de6ff475c..2947cd624 100644 --- a/src/info.c +++ b/src/info.c @@ -407,6 +407,7 @@ char sprnames[NUMSPRITES + 1][5] = "LCKN", // Target "TTAG", // Tag Sign "GFLG", // Got Flag sign + "FNSF", // Finish flag "CORK", "LHRT", @@ -3348,7 +3349,10 @@ state_t states[NUMSTATES] = {SPR_TTAG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_TTAG // CTF Sign - {SPR_GFLG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_GOTFLAG + {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 {SPR_CORK, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CORK {SPR_LHRT, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_LHRT @@ -17994,6 +17998,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, + + { // MT_FINISHFLAG + -1, // doomednum + S_FINISHFLAG, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 4*FRACUNIT, // speed + 8*FRACUNIT, // radius + 8*FRACUNIT, // height + 1, // display offset + 16, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + S_NULL // raisestate + }, // ambient water 1a (large) { // MT_AWATERA diff --git a/src/info.h b/src/info.h index 628335635..b2754fd51 100644 --- a/src/info.h +++ b/src/info.h @@ -670,6 +670,7 @@ typedef enum sprite SPR_LCKN, // Target SPR_TTAG, // Tag Sign SPR_GFLG, // Got Flag sign + SPR_FNSF, // Finish flag SPR_CORK, SPR_LHRT, @@ -3484,6 +3485,9 @@ typedef enum state // Got Flag Sign S_GOTFLAG, + + // Finish flag + S_FINISHFLAG, S_CORK, S_LHRT, @@ -4625,6 +4629,7 @@ typedef enum mobj_type MT_LOCKONINF, // In-level Target MT_TAG, // Tag Sign MT_GOTFLAG, // Got Flag sign + MT_FINISHFLAG, // Finish flag // Ambient Sounds MT_AWATERA, // Ambient Water Sound 1 diff --git a/src/p_local.h b/src/p_local.h index a5f3d313c..888fba5ce 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -159,6 +159,7 @@ void P_GivePlayerLives(player_t *player, INT32 numlives); void P_GiveCoopLives(player_t *player, INT32 numlives, boolean sound); UINT8 P_GetNextEmerald(void); void P_GiveEmerald(boolean spawnObj); +void P_GiveFinishFlags(player_t *player); #if 0 void P_ResetScore(player_t *player); #else diff --git a/src/p_mobj.c b/src/p_mobj.c index a8599ceb5..f53f2a7d5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8006,6 +8006,32 @@ static void P_MobjSceneryThink(mobj_t *mobj) if (strength < 10) mobj->frame |= ((10 - strength) << (FF_TRANSSHIFT)); } + case MT_FINISHFLAG: + { + if (!mobj->target || mobj->target->player->playerstate == PST_DEAD || !cv_exitmove.value) + { + P_RemoveMobj(mobj); + return; + } + + if (!camera.chase) + mobj->flags2 |= MF2_DONTDRAW; + else + mobj->flags2 &= ~MF2_DONTDRAW; + + fixed_t radius = FixedMul(10*mobj->info->speed, mobj->target->scale); + mobj->angle += FixedAngle(mobj->info->speed); + angle_t fa = mobj->angle >> ANGLETOFINESHIFT; + + P_UnsetThingPosition(mobj); + + mobj->x = mobj->target->x + FixedMul(FINECOSINE(fa),radius); + mobj->y = mobj->target->y + FixedMul(FINESINE(fa),radius); + mobj->z = mobj->target->z + mobj->target->height/2; + + P_SetThingPosition(mobj); + P_SetScale(mobj, mobj->target->scale); + } /* FALLTHRU */ default: if (mobj->fuse) @@ -11512,6 +11538,9 @@ void P_AfterPlayerSpawn(INT32 playernum) if (CheckForReverseGravity) P_CheckGravity(mobj, false); + + if (p->pflags & PF_FINISHED) + P_GiveFinishFlags(p); } // spawn it at a playerspawn mapthing diff --git a/src/p_user.c b/src/p_user.c index a1df8a58b..38f7f2719 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -370,6 +370,32 @@ void P_GiveEmerald(boolean spawnObj) } } +// +// P_GiveFinishFlags +// +// Give the player visual indicators +// that they've finished the map. +// +void P_GiveFinishFlags(player_t *player) +{ + if (!player->mo) + return; + + angle_t angle = FixedAngle(player->mo->angle << FRACBITS); + + for (UINT8 i = 0; i < 3; i++) + { + angle_t fa = (angle >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t xoffs = FINECOSINE(fa); + fixed_t yoffs = FINESINE(fa); + 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); + } +} + #if 0 // // P_ResetScore @@ -2171,6 +2197,7 @@ void P_DoPlayerFinish(player_t *player) return; player->pflags |= PF_FINISHED; + P_GiveFinishFlags(player); if (netgame) CONS_Printf(M_GetText("%s has completed the level.\n"), player_names[player-players]); From db22d503a4e6931a4773146ca95d9f3e11f58504 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Sun, 19 Jan 2020 21:55:08 -0300 Subject: [PATCH 3/9] HUD visual indicator + property fix --- src/info.c | 2 +- src/st_stuff.c | 24 +++++++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/info.c b/src/info.c index 2947cd624..1ca68eda6 100644 --- a/src/info.c +++ b/src/info.c @@ -18022,7 +18022,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 16, // mass 0, // damage sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, diff --git a/src/st_stuff.c b/src/st_stuff.c index 9c9c80164..d7e050b5b 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -128,6 +128,7 @@ static patch_t *minus5sec; static patch_t *minicaps; static patch_t *gotrflag; static patch_t *gotbflag; +static patch_t *fnshico; static boolean facefreed[MAXPLAYERS]; @@ -310,6 +311,7 @@ void ST_LoadGraphics(void) bmatcico = W_CachePatchName("BMATCICO", PU_HUDGFX); gotrflag = W_CachePatchName("GOTRFLAG", PU_HUDGFX); gotbflag = W_CachePatchName("GOTBFLAG", PU_HUDGFX); + fnshico = W_CachePatchName("FNSHICO", PU_HUDGFX); nonicon = W_CachePatchName("NONICON", PU_HUDGFX); nonicon2 = W_CachePatchName("NONICON2", PU_HUDGFX); @@ -1432,7 +1434,7 @@ static void ST_drawPowerupHUD(void) UINT16 invulntime = 0; INT32 offs = hudinfo[HUD_POWERUPS].x; const UINT8 q = ((splitscreen && stplyr == &players[secondarydisplayplayer]) ? 1 : 0); - static INT32 flagoffs[2] = {0, 0}, shieldoffs[2] = {0, 0}; + static INT32 flagoffs[2] = {0, 0}, shieldoffs[2] = {0, 0}, finishoffs[2] = {0, 0}; #define ICONSEP (16+4) // matches weapon rings HUD if (F_GetPromptHideHud(hudinfo[HUD_POWERUPS].y)) @@ -1440,6 +1442,26 @@ static void ST_drawPowerupHUD(void) if (stplyr->spectator || stplyr->playerstate != PST_LIVE) return; + +// --------- +// Finish icon +// --------- + + // Let's have a power-like icon to represent finishing the level! + if (stplyr->pflags & PF_FINISHED && cv_exitmove.value) + { + finishoffs[q] = ICONSEP; + V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, fnshico); + } + else if (finishoffs[q]) + { + if (finishoffs[q] > 1) + finishoffs[q] = 2*finishoffs[q]/3; + else + finishoffs[q] = 0; + } + + offs -= finishoffs[q]; // ------- // Shields From 697dbd58e737a2c1e9aea896724e0954a58bf280 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Sun, 19 Jan 2020 21:56:53 -0300 Subject: [PATCH 4/9] Turn cv_exitmove on by default --- 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 058c95196..36db4008c 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -370,7 +370,7 @@ consvar_t cv_advancemap = {"advancemap", "Next", CV_NETVAR, advancemap_cons_t, N static CV_PossibleValue_t playersforexit_cons_t[] = {{0, "One"}, {1, "1/4"}, {2, "Half"}, {3, "3/4"}, {4, "All"}, {0, NULL}}; consvar_t cv_playersforexit = {"playersforexit", "All", CV_NETVAR, playersforexit_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_exitmove = {"exitmove", "Off", CV_NETVAR|CV_CALL, CV_OnOff, ExitMove_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_exitmove = {"exitmove", "On", CV_NETVAR|CV_CALL, CV_OnOff, ExitMove_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_runscripts = {"runscripts", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; From fed000b724296fbd3c5b771c0e2a2a182e975d4f Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Sun, 19 Jan 2020 23:18:49 -0300 Subject: [PATCH 5/9] Remove Tails pick-up lock --- src/p_map.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index 40fee7b46..3f0ea61ee 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -591,9 +591,12 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) if (!(tails->pflags & PF_CANCARRY)) return; - + +#if 0 + // To prevent finished players from being thrown into pits. Not that it matters much if (sonic->pflags & PF_FINISHED) return; +#endif if ((sonic->mo->eflags & MFE_VERTICALFLIP) != (tails->mo->eflags & MFE_VERTICALFLIP)) return; // Both should be in same gravity From 431206ebee42371edb72d0b45de25177d4938f47 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Mon, 20 Jan 2020 10:04:44 -0300 Subject: [PATCH 6/9] Die --- src/p_map.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 3f0ea61ee..1c2b4808b 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -591,12 +591,6 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) if (!(tails->pflags & PF_CANCARRY)) return; - -#if 0 - // To prevent finished players from being thrown into pits. Not that it matters much - if (sonic->pflags & PF_FINISHED) - return; -#endif if ((sonic->mo->eflags & MFE_VERTICALFLIP) != (tails->mo->eflags & MFE_VERTICALFLIP)) return; // Both should be in same gravity From c76a8e8a58fbd89813b8c5940dbb972dca4cf429 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 18 Feb 2020 22:19:09 -0300 Subject: [PATCH 7/9] Standards --- src/p_mobj.c | 57 ++++++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index f53f2a7d5..299083b03 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7996,6 +7996,37 @@ static void P_MobjSceneryThink(mobj_t *mobj) mobj->frame = (mobj->frame & ~FF_TRANSMASK) | ((10 - (mobj->fuse*2)) << (FF_TRANSSHIFT)); } break; + case MT_FINISHFLAG: + { + if (!mobj->target || mobj->target->player->playerstate == PST_DEAD || !cv_exitmove.value) + { + P_RemoveMobj(mobj); + return; + } + + if (!camera.chase) + mobj->flags2 |= MF2_DONTDRAW; + else + mobj->flags2 &= ~MF2_DONTDRAW; + + P_UnsetThingPosition(mobj); + { + fixed_t radius = FixedMul(10*mobj->info->speed, mobj->target->scale); + angle_t fa; + + mobj->angle += FixedAngle(mobj->info->speed); + + fa = mobj->angle >> ANGLETOFINESHIFT; + + mobj->x = mobj->target->x + FixedMul(FINECOSINE(fa),radius); + mobj->y = mobj->target->y + FixedMul(FINESINE(fa),radius); + mobj->z = mobj->target->z + mobj->target->height/2; + } + P_SetThingPosition(mobj); + + P_SetScale(mobj, mobj->target->scale); + } + break; case MT_VWREF: case MT_VWREB: { @@ -8006,32 +8037,6 @@ static void P_MobjSceneryThink(mobj_t *mobj) if (strength < 10) mobj->frame |= ((10 - strength) << (FF_TRANSSHIFT)); } - case MT_FINISHFLAG: - { - if (!mobj->target || mobj->target->player->playerstate == PST_DEAD || !cv_exitmove.value) - { - P_RemoveMobj(mobj); - return; - } - - if (!camera.chase) - mobj->flags2 |= MF2_DONTDRAW; - else - mobj->flags2 &= ~MF2_DONTDRAW; - - fixed_t radius = FixedMul(10*mobj->info->speed, mobj->target->scale); - mobj->angle += FixedAngle(mobj->info->speed); - angle_t fa = mobj->angle >> ANGLETOFINESHIFT; - - P_UnsetThingPosition(mobj); - - mobj->x = mobj->target->x + FixedMul(FINECOSINE(fa),radius); - mobj->y = mobj->target->y + FixedMul(FINESINE(fa),radius); - mobj->z = mobj->target->z + mobj->target->height/2; - - P_SetThingPosition(mobj); - P_SetScale(mobj, mobj->target->scale); - } /* FALLTHRU */ default: if (mobj->fuse) From ec67e776dcb0c388e50814caa0ade52d465500bc Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 18 Feb 2020 22:50:22 -0300 Subject: [PATCH 8/9] Standards 2 --- src/p_user.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 38f7f2719..85fa32acf 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -378,11 +378,11 @@ void P_GiveEmerald(boolean spawnObj) // void P_GiveFinishFlags(player_t *player) { + angle_t angle = FixedAngle(player->mo->angle << FRACBITS); + if (!player->mo) return; - - angle_t angle = FixedAngle(player->mo->angle << FRACBITS); - + for (UINT8 i = 0; i < 3; i++) { angle_t fa = (angle >> ANGLETOFINESHIFT) & FINEMASK; From 4a8de7cb55dda9dbc4eb86319ce0c3300fec07ee Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 18 Feb 2020 22:55:40 -0300 Subject: [PATCH 9/9] Enough --- src/p_user.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 85fa32acf..c9efe7596 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -379,11 +379,12 @@ void P_GiveEmerald(boolean spawnObj) void P_GiveFinishFlags(player_t *player) { angle_t angle = FixedAngle(player->mo->angle << FRACBITS); + UINT8 i; if (!player->mo) return; - for (UINT8 i = 0; i < 3; i++) + for (i = 0; i < 3; i++) { angle_t fa = (angle >> ANGLETOFINESHIFT) & FINEMASK; fixed_t xoffs = FINECOSINE(fa);