Fix a few things noted during a test netgame with Salt and FuriousFox.

* Hide the individual lives on the tab menu whenever they're irrelevant.
* Make co-op spectators appear on the tab menu.
* Hide one frame of spectatorhood stuff in splitscreen.
* Fix joining netgames whilst in a special stage not giving the startinglives.
* Make monitors that don't appear to do anything play the failure sound.
* Only make players flash if they're REspawning, rather than spawning into a fresh level - unless it's a NiGHTS level, in which case never.
This commit is contained in:
toasterbabe 2017-07-07 13:35:48 +01:00
parent 1a7a0662ba
commit 88546abb08
7 changed files with 104 additions and 72 deletions

View File

@ -2708,7 +2708,7 @@ void G_AddPlayer(INT32 playernum)
p->height = mobjinfo[MT_PLAYER].height;
if (G_GametypeUsesLives())
if (G_GametypeUsesLives() || ((netgame || multiplayer) && gametype == GT_COOP))
p->lives = cv_startinglives.value;
if (countplayers && !notexiting)
@ -3710,7 +3710,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
if (netgame || multiplayer)
{
if (!FLS || (players[i].lives < cv_startinglives.value))
if (!FLS || (players[i].lives < 1))
players[i].lives = cv_startinglives.value;
players[i].continues = 0;
}

View File

@ -1176,6 +1176,9 @@ void HU_Erase(void)
// IN-LEVEL MULTIPLAYER RANKINGS
//======================================================================
#define supercheckdef ((players[tab[i].num].powers[pw_super] && players[tab[i].num].mo && (players[tab[i].num].mo->state < &states[S_PLAY_SUPER_TRANS] || players[tab[i].num].mo->state > &states[S_PLAY_SUPER_TRANS9])) || (players[tab[i].num].powers[pw_carry] == CR_NIGHTSMODE && skins[players[tab[i].num].skin].flags & SF_SUPER))
#define greycheckdef ((players[tab[i].num].mo && players[tab[i].num].mo->health <= 0) || players[tab[i].num].spectator)
//
// HU_DrawTabRankings
//
@ -1183,6 +1186,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
{
INT32 i;
const UINT8 *colormap;
boolean greycheck, supercheck;
//this function is designed for 9 or less score lines only
I_Assert(scorelines <= 9);
@ -1191,12 +1195,15 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
for (i = 0; i < scorelines; i++)
{
if (players[tab[i].num].spectator)
if (players[tab[i].num].spectator && gametype != GT_COOP)
continue; //ignore them.
greycheck = greycheckdef;
supercheck = supercheckdef;
V_DrawString(x + 20, y,
((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
| ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS)
| (greycheck ? V_60TRANS : 0)
| V_ALLOWLOWERCASE, tab[i].name);
// Draw emeralds
@ -1206,7 +1213,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
HU_DrawEmeralds(x-12,y+2,tab[i].emeralds);
}
if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0)
if (greycheck)
V_DrawSmallTranslucentPatch (x, y-4, V_80TRANS, livesback);
else
V_DrawSmallScaledPatch (x, y-4, 0, livesback);
@ -1214,11 +1221,11 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
if (tab[i].color == 0)
{
colormap = colormaps;
if (players[tab[i].num].powers[pw_super])
if (supercheck)
V_DrawSmallScaledPatch(x, y-4, 0, superprefix[players[tab[i].num].skin]);
else
{
if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0)
if (greycheck)
V_DrawSmallTranslucentPatch(x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin]);
else
V_DrawSmallScaledPatch(x, y-4, 0, faceprefix[players[tab[i].num].skin]);
@ -1226,7 +1233,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
}
else
{
if (players[tab[i].num].powers[pw_super] && players[tab[i].num].mo && (players[tab[i].num].mo->state < &states[S_PLAY_SUPER_TRANS] || players[tab[i].num].mo->state > &states[S_PLAY_SUPER_TRANS9]))
if (supercheck)
{
colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo->color, GTC_CACHE);
V_DrawSmallMappedPatch (x, y-4, 0, superprefix[players[tab[i].num].skin], colormap);
@ -1234,18 +1241,18 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
else
{
colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE);
if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0)
if (greycheck)
V_DrawSmallTranslucentMappedPatch (x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin], colormap);
else
V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap);
}
}
if (G_GametypeUsesLives()) //show lives
V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS), va("%dx", players[tab[i].num].lives));
if (G_GametypeUsesLives() && !(gametype == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3))) //show lives
V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|(greycheck ? V_60TRANS : 0), va("%dx", players[tab[i].num].lives));
else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT)
{
if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0)
if (greycheck)
V_DrawSmallTranslucentPatch(x-32, y-4, V_60TRANS, tagico);
else
V_DrawSmallScaledPatch(x-32, y-4, 0, tagico);
@ -1258,13 +1265,13 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
if (players[tab[i].num].exiting)
V_DrawRightAlignedString(x+240, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime)));
else
V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count));
V_DrawRightAlignedString(x+240, y, (greycheck ? V_60TRANS : 0), va("%u", tab[i].count));
}
else
V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count)));
V_DrawRightAlignedString(x+240, y, (greycheck ? V_60TRANS : 0), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count)));
}
else
V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count));
V_DrawRightAlignedString(x+240, y, (greycheck ? V_60TRANS : 0), va("%u", tab[i].count));
y += 16;
}
@ -1279,6 +1286,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
INT32 redplayers = 0, blueplayers = 0;
const UINT8 *colormap;
char name[MAXPLAYERNAME+1];
boolean greycheck, supercheck;
V_DrawFill(160, 26, 1, 154, 0); //Draw a vertical line to separate the two teams.
V_DrawFill(1, 26, 318, 1, 0); //And a horizontal line to make a T.
@ -1306,10 +1314,13 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
else //er? not on red or blue, so ignore them
continue;
greycheck = greycheckdef;
supercheck = supercheckdef;
strlcpy(name, tab[i].name, 9);
V_DrawString(x + 20, y,
((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
| ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT)
| (greycheck ? V_TRANSLUCENT : 0)
| V_ALLOWLOWERCASE, name);
if (gametype == GT_CTF)
@ -1327,7 +1338,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
HU_DrawEmeralds(x-12,y+2,tab[i].emeralds);
}
if (players[tab[i].num].powers[pw_super])
if (supercheck)
{
colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE);
V_DrawSmallMappedPatch (x, y-4, 0, superprefix[players[tab[i].num].skin], colormap);
@ -1335,12 +1346,12 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer)
else
{
colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE);
if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0)
V_DrawSmallTranslucentMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap);
if (greycheck)
V_DrawSmallTranslucentMappedPatch (x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin], colormap);
else
V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap);
}
V_DrawRightAlignedThinString(x+120, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
V_DrawRightAlignedThinString(x+120, y, (greycheck ? V_TRANSLUCENT : 0), va("%u", tab[i].count));
}
}
@ -1352,6 +1363,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
INT32 i;
const UINT8 *colormap;
char name[MAXPLAYERNAME+1];
boolean greycheck, supercheck;
V_DrawFill(160, 26, 1, 154, 0); //Draw a vertical line to separate the two sides.
V_DrawFill(1, 26, 318, 1, 0); //And a horizontal line to make a T.
@ -1359,16 +1371,19 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
for (i = 0; i < scorelines; i++)
{
if (players[tab[i].num].spectator)
if (players[tab[i].num].spectator && gametype != GT_COOP)
continue; //ignore them.
greycheck = greycheckdef;
supercheck = supercheckdef;
strlcpy(name, tab[i].name, 9);
V_DrawString(x + 20, y,
((tab[i].num == whiteplayer) ? V_YELLOWMAP : 0)
| ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT)
| (greycheck ? V_TRANSLUCENT : 0)
| V_ALLOWLOWERCASE, name);
if (G_GametypeUsesLives()) //show lives
if (G_GametypeUsesLives() && !(gametype == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3))) //show lives
V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE, va("%dx", players[tab[i].num].lives));
else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT)
V_DrawSmallScaledPatch(x-28, y-4, 0, tagico);
@ -1384,19 +1399,19 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
if (tab[i].color == 0)
{
colormap = colormaps;
if (players[tab[i].num].powers[pw_super])
if (supercheck)
V_DrawSmallScaledPatch (x, y-4, 0, superprefix[players[tab[i].num].skin]);
else
{
if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0)
V_DrawSmallTranslucentPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin]);
if (greycheck)
V_DrawSmallTranslucentPatch (x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin]);
else
V_DrawSmallScaledPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin]);
}
}
else
{
if (players[tab[i].num].powers[pw_super])
if (supercheck)
{
colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE);
V_DrawSmallMappedPatch (x, y-4, 0, superprefix[players[tab[i].num].skin], colormap);
@ -1404,8 +1419,8 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
else
{
colormap = R_GetTranslationColormap(players[tab[i].num].skin, players[tab[i].num].mo ? players[tab[i].num].mo->color : tab[i].color, GTC_CACHE);
if (players[tab[i].num].mo && players[tab[i].num].mo->health <= 0)
V_DrawSmallTranslucentMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap);
if (greycheck)
V_DrawSmallTranslucentMappedPatch (x, y-4, V_80TRANS, faceprefix[players[tab[i].num].skin], colormap);
else
V_DrawSmallMappedPatch (x, y-4, 0, faceprefix[players[tab[i].num].skin], colormap);
}
@ -1419,13 +1434,13 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
if (players[tab[i].num].exiting)
V_DrawRightAlignedThinString(x+156, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime)));
else
V_DrawRightAlignedThinString(x+156, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
V_DrawRightAlignedThinString(x+156, y, (greycheck ? V_TRANSLUCENT : 0), va("%u", tab[i].count));
}
else
V_DrawRightAlignedThinString(x+156, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count)));
V_DrawRightAlignedThinString(x+156, y, (greycheck ? V_TRANSLUCENT : 0), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count)));
}
else
V_DrawRightAlignedThinString(x+120, y, ((players[tab[i].num].mo && players[tab[i].num].mo->health > 0) ? 0 : V_TRANSLUCENT), va("%u", tab[i].count));
V_DrawRightAlignedThinString(x+120, y, (greycheck ? V_TRANSLUCENT : 0), va("%u", tab[i].count));
y += 16;
if (y > 160)
@ -1622,61 +1637,67 @@ static void HU_DrawRankings(void)
for (j = 0; j < MAXPLAYERS; j++)
{
if (!playeringame[j] || players[j].spectator)
if (!playeringame[j])
continue;
if (gametype != GT_COOP && players[j].spectator)
continue;
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && !players[i].spectator)
if (!playeringame[i])
continue;
if (gametype != GT_COOP && players[i].spectator)
continue;
if (gametype == GT_RACE)
{
if (gametype == GT_RACE)
if (circuitmap)
{
if (circuitmap)
if ((unsigned)players[i].laps+1 >= tab[scorelines].count && completed[i] == false)
{
if ((unsigned)players[i].laps+1 >= tab[scorelines].count && completed[i] == false)
{
tab[scorelines].count = players[i].laps+1;
tab[scorelines].num = i;
tab[scorelines].color = players[i].skincolor;
tab[scorelines].name = player_names[i];
}
}
else
{
if (players[i].realtime <= tab[scorelines].count && completed[i] == false)
{
tab[scorelines].count = players[i].realtime;
tab[scorelines].num = i;
tab[scorelines].color = players[i].skincolor;
tab[scorelines].name = player_names[i];
}
}
}
else if (gametype == GT_COMPETITION)
{
// todo put something more fitting for the gametype here, such as current
// number of categories led
if (players[i].score >= tab[scorelines].count && completed[i] == false)
{
tab[scorelines].count = players[i].score;
tab[scorelines].count = players[i].laps+1;
tab[scorelines].num = i;
tab[scorelines].color = players[i].skincolor;
tab[scorelines].name = player_names[i];
tab[scorelines].emeralds = players[i].powers[pw_emeralds];
}
}
else
{
if (players[i].score >= tab[scorelines].count && completed[i] == false)
if (players[i].realtime <= tab[scorelines].count && completed[i] == false)
{
tab[scorelines].count = players[i].score;
tab[scorelines].count = players[i].realtime;
tab[scorelines].num = i;
tab[scorelines].color = players[i].skincolor;
tab[scorelines].name = player_names[i];
tab[scorelines].emeralds = players[i].powers[pw_emeralds];
}
}
}
else if (gametype == GT_COMPETITION)
{
// todo put something more fitting for the gametype here, such as current
// number of categories led
if (players[i].score >= tab[scorelines].count && completed[i] == false)
{
tab[scorelines].count = players[i].score;
tab[scorelines].num = i;
tab[scorelines].color = players[i].skincolor;
tab[scorelines].name = player_names[i];
tab[scorelines].emeralds = players[i].powers[pw_emeralds];
}
}
else
{
if (players[i].score >= tab[scorelines].count && completed[i] == false)
{
tab[scorelines].count = players[i].score;
tab[scorelines].num = i;
tab[scorelines].color = players[i].skincolor;
tab[scorelines].name = player_names[i];
tab[scorelines].emeralds = players[i].powers[pw_emeralds];
}
}
}
completed[tab[scorelines].num] = true;
scorelines++;

View File

@ -5629,7 +5629,10 @@ void A_MixUp(mobj_t *actor)
}
if (numplayers <= 1) // Not enough players to mix up.
{
S_StartSound(actor, sfx_lose);
return;
}
else if (numplayers == 2) // Special case -- simple swap
{
fixed_t x, y, z;
@ -5875,7 +5878,10 @@ void A_RecyclePowers(mobj_t *actor)
#endif
if (!multiplayer)
{
S_StartSound(actor, sfx_lose);
return;
}
numplayers = 0;
@ -5911,7 +5917,10 @@ void A_RecyclePowers(mobj_t *actor)
}
if (numplayers <= 1)
{
S_StartSound(actor, sfx_lose);
return; //nobody to touch!
}
//shuffle the post scramble list, whee!
// hardcoded 0-1 to 1-0 for two players

View File

@ -9153,7 +9153,7 @@ void P_SpawnPlayer(INT32 playernum)
p->skincolor = skincolor_blueteam;
}
if ((netgame || multiplayer) && !p->spectator)
if ((netgame || multiplayer) && leveltime && !p->spectator && !(maptol & TOL_NIGHTS))
p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent
mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER);

View File

@ -1150,7 +1150,9 @@ void P_PlayLivesJingle(player_t *player)
if (player && !P_IsLocalPlayer(player))
return;
if (use1upSound)
if (gametype == GT_COOP && (netgame || multiplayer) && cv_cooplives.value == 0)
S_StartSound(NULL, sfx_lose);
else if (use1upSound)
S_StartSound(NULL, sfx_oneup);
else if (mariomode)
S_StartSound(NULL, sfx_marioa);
@ -2335,7 +2337,7 @@ static void P_DoBubbleBreath(player_t *player)
if (player->charflags & SF_MACHINE)
{
if (P_RandomChance((128-(player->powers[pw_underwater]/4))*FRACUNIT/256))
if (player->powers[pw_underwater] && P_RandomChance((128-(player->powers[pw_underwater]/4))*FRACUNIT/256))
{
fixed_t r = player->mo->radius>>FRACBITS;
x += (P_RandomRange(r, -r)<<FRACBITS);

View File

@ -346,7 +346,7 @@ sfxinfo_t S_sfx[NUMSFX] =
{"s3k78", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Magnet"},
{"s3k79", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Electric charge"},
{"s3k7a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rising from lava"},
{"s3k7b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Organic bounce"},
{"s3k7b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Soft bounce"},
{"s3k7c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Magnet"},
{"s3k7d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s3k7e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Eating dirt"},

View File

@ -1356,7 +1356,7 @@ static void ST_drawNiGHTSHUD(void)
realnightstime = lowest_time/TICRATE;
}
if (stplyr->powers[pw_flashing] > TICRATE ) // was hit
if (stplyr->powers[pw_flashing] > TICRATE) // was hit
{
UINT16 flashingLeft = stplyr->powers[pw_flashing]-(TICRATE);
if (flashingLeft < TICRATE/2) // Start fading out
@ -1995,7 +1995,7 @@ static void ST_overlayDrawer(void)
)
ST_drawLevelTitle();
if (!hu_showscores && (netgame || multiplayer) && displayplayer == consoleplayer)
if (!hu_showscores && (netgame || multiplayer) && displayplayer == consoleplayer && (!stplyr->spectator || gametype == GT_COOP))
{
if (stplyr->exiting && cv_playersforexit.value && gametype == GT_COOP)
{