Merge branch 'exitmove-tweaks' into 'next'

Exitmove tweaks

See merge request STJr/SRB2!709
This commit is contained in:
James R 2020-02-18 21:58:18 -05:00
commit 92f65fd822
11 changed files with 141 additions and 11 deletions

View File

@ -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};
@ -3749,9 +3749,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

View File

@ -7477,6 +7477,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",
@ -8598,6 +8601,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

View File

@ -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

View File

@ -407,6 +407,7 @@ char sprnames[NUMSPRITES + 1][5] =
"LCKN", // Target
"TTAG", // Tag Sign
"GFLG", // Got Flag sign
"FNSF", // Finish flag
"CORK",
"LHRT",
@ -3349,7 +3350,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
@ -17995,6 +17999,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_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags
S_NULL // raisestate
},
// ambient water 1a (large)
{ // MT_AWATERA

View File

@ -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,
@ -3485,6 +3486,9 @@ typedef enum state
// Got Flag Sign
S_GOTFLAG,
// Finish flag
S_FINISHFLAG,
S_CORK,
S_LHRT,
@ -4626,6 +4630,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

View File

@ -2542,7 +2542,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
{

View File

@ -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

View File

@ -592,9 +592,6 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
if (!(tails->pflags & PF_CANCARRY))
return;
if (sonic->pflags & PF_FINISHED)
return;
if ((sonic->mo->eflags & MFE_VERTICALFLIP) != (tails->mo->eflags & MFE_VERTICALFLIP))
return; // Both should be in same gravity

View File

@ -8005,6 +8005,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:
{
@ -11563,6 +11594,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

View File

@ -370,6 +370,33 @@ void P_GiveEmerald(boolean spawnObj)
}
}
//
// P_GiveFinishFlags
//
// Give the player visual indicators
// that they've finished the map.
//
void P_GiveFinishFlags(player_t *player)
{
angle_t angle = FixedAngle(player->mo->angle << FRACBITS);
UINT8 i;
if (!player->mo)
return;
for (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 +2198,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]);

View File

@ -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);
@ -944,7 +946,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;
@ -1434,7 +1436,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))
@ -1442,6 +1444,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