* Incorporate (almost) all of Mystic's feedback.

* Prevent ANY input when blindfolded.
* Make CECHOs always perplayer'd. (A little hacky; quads will need work here.)
* Make NiGHTS link timer bounces not a mess, and only when the colour changes.
This commit is contained in:
toasterbabe 2018-03-30 16:39:59 +01:00
parent 98601dc757
commit de8f1fa407
4 changed files with 264 additions and 234 deletions

View File

@ -888,7 +888,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
// why build a ticcmd if we're paused? // why build a ticcmd if we're paused?
// Or, for that matter, if we're being reborn. // Or, for that matter, if we're being reborn.
if (paused || P_AutoPause() || (gamestate == GS_LEVEL && player->playerstate == PST_REBORN)) // ...OR if we're blindfolded. No looking into the floor.
if (paused || P_AutoPause() || (gamestate == GS_LEVEL && (player->playerstate == PST_REBORN || ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK)
&& (leveltime < hidetime * TICRATE) && (player->pflags & PF_TAGIT)))))
{ {
cmd->angleturn = (INT16)(localangle >> 16); cmd->angleturn = (INT16)(localangle >> 16);
cmd->aiming = G_ClipAimingPitch(&localaiming); cmd->aiming = G_ClipAimingPitch(&localaiming);

View File

@ -947,7 +947,7 @@ static void HU_DrawCEcho(void)
INT32 y = (BASEVIDHEIGHT/2)-4; INT32 y = (BASEVIDHEIGHT/2)-4;
INT32 pnumlines = 0; INT32 pnumlines = 0;
UINT32 realflags = cechoflags; UINT32 realflags = cechoflags|V_PERPLAYER; // requested as part of splitscreen's stuff
INT32 realalpha = (INT32)((cechoflags & V_ALPHAMASK) >> V_ALPHASHIFT); INT32 realalpha = (INT32)((cechoflags & V_ALPHAMASK) >> V_ALPHASHIFT);
char *line; char *line;
@ -990,6 +990,12 @@ static void HU_DrawCEcho(void)
*line = '\0'; *line = '\0';
V_DrawCenteredString(BASEVIDWIDTH/2, y, realflags, echoptr); V_DrawCenteredString(BASEVIDWIDTH/2, y, realflags, echoptr);
if (splitscreen)
{
stplyr = ((stplyr == &players[displayplayer]) ? &players[secondarydisplayplayer] : &players[displayplayer]);
V_DrawCenteredString(BASEVIDWIDTH/2, y, realflags, echoptr);
stplyr = ((stplyr == &players[displayplayer]) ? &players[secondarydisplayplayer] : &players[displayplayer]);
}
y += ((realflags & V_RETURN8) ? 8 : 12); y += ((realflags & V_RETURN8) ? 8 : 12);
echoptr = line; echoptr = line;

View File

@ -9709,7 +9709,7 @@ void P_PlayerThink(player_t *player)
} }
} }
if (player->linktimer && (player->linktimer >= (2*TICRATE - 1) || !player->powers[pw_nights_linkfreeze])) if (player->linktimer && !player->powers[pw_nights_linkfreeze])
{ {
if (--player->linktimer <= 0) // Link timer if (--player->linktimer <= 0) // Link timer
player->linkcount = 0; player->linkcount = 0;

View File

@ -737,14 +737,19 @@ static void ST_drawLivesArea(void)
} }
// Lives number // Lives number
if (G_GametypeUsesLives()) if (G_GametypeUsesLives() || gametype == GT_RACE)
{ {
// x // x
V_DrawScaledPatch(hudinfo[HUD_LIVES].x+22, hudinfo[HUD_LIVES].y+10, V_DrawScaledPatch(hudinfo[HUD_LIVES].x+22, hudinfo[HUD_LIVES].y+10,
hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, stlivex); hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, stlivex);
// lives number // lives number
if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) if (gametype == GT_RACE)
{
livescount = 0x7f;
notgreyedout = true;
}
else if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3)
{ {
INT32 i; INT32 i;
livescount = 0; livescount = 0;
@ -788,58 +793,30 @@ static void ST_drawLivesArea(void)
} }
// Spectator // Spectator
else if (stplyr->spectator) else if (stplyr->spectator)
{
//V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "SPECTATOR");
v_colmap = V_GRAYMAP; v_colmap = V_GRAYMAP;
}
// Tag // Tag
else if (gametype == GT_TAG || gametype == GT_HIDEANDSEEK) else if (gametype == GT_TAG || gametype == GT_HIDEANDSEEK)
{ {
if (stplyr->pflags & PF_TAGIT) if (stplyr->pflags & PF_TAGIT)
{ {
V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, (gametype == GT_HIDEANDSEEK) ? "SEEKER" : "IT!"); V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "IT!");
v_colmap = V_ORANGEMAP; v_colmap = V_ORANGEMAP;
} }
else if (stplyr->pflags & PF_GAMETYPEOVER)
{
V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANSHALF|hudinfo[HUD_LIVES].f|V_PERPLAYER, "FAILED");
v_colmap = V_GRAYMAP;
}
else
{
V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, (gametype == GT_HIDEANDSEEK) ? "HIDER" : "RUNNER");
v_colmap = V_GREENMAP;
}
} }
// Team name // Team name
else if (G_GametypeHasTeams()) else if (G_GametypeHasTeams())
{ {
if (stplyr->ctfteam == 1) if (stplyr->ctfteam == 1)
{ {
V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "RED"); V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "RED");
v_colmap = V_REDMAP; v_colmap = V_REDMAP;
} }
else if (stplyr->ctfteam == 2) else if (stplyr->ctfteam == 2)
{ {
V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "BLUE"); V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "BLUE");
v_colmap = V_BLUEMAP; v_colmap = V_BLUEMAP;
} }
else
v_colmap = V_GRAYMAP;
} }
else if (circuitmap)
{
if (stplyr->exiting)
V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "FINISHED");
//V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, hudinfo[HUD_LAP].f|V_YELLOWMAP, "FINISHED!");
else
{
V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, va("%u/%d", stplyr->laps+1, cv_numlaps.value));
//V_DrawString(hudinfo[HUD_LAP].x, hudinfo[HUD_LAP].y, hudinfo[HUD_LAP].f, va("Lap: %u/%d", stplyr->laps+1, cv_numlaps.value));
}
}
/*else
V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER, "PLAYING");*/
// name // name
v_colmap |= (V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER); v_colmap |= (V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER);
@ -1074,13 +1051,8 @@ static void ST_drawLevelTitle(void)
char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl; char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl;
char *subttl = mapheaderinfo[gamemap-1]->subttl; char *subttl = mapheaderinfo[gamemap-1]->subttl;
INT32 actnum = mapheaderinfo[gamemap-1]->actnum; INT32 actnum = mapheaderinfo[gamemap-1]->actnum;
INT32 lvlttlxpos; INT32 lvlttly, zoney, lvlttlxpos, ttlnumxpos, zonexpos;
INT32 subttlxpos = BASEVIDWIDTH/2; INT32 subttlxpos = BASEVIDWIDTH/2;
INT32 ttlnumxpos;
INT32 zonexpos;
INT32 lvlttly;
INT32 zoney;
if (!(timeinmap > 2 && timeinmap-3 < 110)) if (!(timeinmap > 2 && timeinmap-3 < 110))
return; return;
@ -1095,10 +1067,41 @@ static void ST_drawLevelTitle(void)
ttlnumxpos = lvlttlxpos + V_LevelNameWidth(lvlttl); ttlnumxpos = lvlttlxpos + V_LevelNameWidth(lvlttl);
zonexpos = ttlnumxpos - V_LevelNameWidth(M_GetText("ZONE")); zonexpos = ttlnumxpos - V_LevelNameWidth(M_GetText("ZONE"));
ttlnumxpos++;
if (lvlttlxpos < 0) if (lvlttlxpos < 0)
lvlttlxpos = 0; lvlttlxpos = 0;
#if 0 // toaster's experiment. srb2&toast.exe one day, maybe? Requires stuff below to be converted to fixed point.
#define MIDTTLY 79
#define MIDZONEY 105
#define MIDDIFF 4
if (timeinmap < 10)
{
fixed_t z = ((timeinmap - 3)<<FRACBITS)/7;
INT32 ttlh = V_LevelNameHeight(lvlttl);
zoney = (200<<FRACBITS) - ((200 - (MIDZONEY + MIDDIFF))*z);
lvlttly = ((MIDTTLY + ttlh - MIDDIFF)*z) - (ttlh<<FRACBITS);
}
else if (timeinmap < 105)
{
fixed_t z = (((timeinmap - 10)*MIDDIFF)<<(FRACBITS+1))/95;
zoney = ((MIDZONEY + MIDDIFF)<<FRACBITS) - z;
lvlttly = ((MIDTTLY - MIDDIFF)<<FRACBITS) + z;
}
else
{
fixed_t z = ((timeinmap - 105)<<FRACBITS)/7;
INT32 zoneh = V_LevelNameHeight(M_GetText("ZONE"));
zoney = (MIDZONEY + zoneh - MIDDIFF)*(FRACUNIT - z) - (zoneh<<FRACBITS);
lvlttly = ((MIDTTLY + MIDDIFF)<<FRACBITS) + ((200 - (MIDTTLY + MIDDIFF))*z);
}
#undef MIDTTLY
#undef MIDZONEY
#undef MIDDIFF
#else
// There's no consistent algorithm that can accurately define the old positions // There's no consistent algorithm that can accurately define the old positions
// so I just ended up resorting to a single switct statement to define them // so I just ended up resorting to a single switct statement to define them
switch (timeinmap-3) switch (timeinmap-3)
@ -1117,17 +1120,18 @@ static void ST_drawLevelTitle(void)
case 109: zoney = 0; lvlttly = 200; break; case 109: zoney = 0; lvlttly = 200; break;
default: zoney = 104; lvlttly = 80; break; default: zoney = 104; lvlttly = 80; break;
} }
#endif
if (actnum) if (actnum)
V_DrawScaledPatch(ttlnumxpos, zoney, 0, ttlnum); V_DrawScaledPatch(ttlnumxpos, zoney, V_PERPLAYER, ttlnum);
V_DrawLevelTitle(lvlttlxpos, lvlttly, 0, lvlttl); V_DrawLevelTitle(lvlttlxpos, lvlttly, V_PERPLAYER, lvlttl);
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
V_DrawLevelTitle(zonexpos, zoney, 0, M_GetText("ZONE")); V_DrawLevelTitle(zonexpos, zoney, V_PERPLAYER, M_GetText("ZONE"));
if (lvlttly+48 < 200) if (lvlttly+48 < 200)
V_DrawCenteredString(subttlxpos, lvlttly+48, V_ALLOWLOWERCASE, subttl); V_DrawCenteredString(subttlxpos, lvlttly+48, V_PERPLAYER|V_ALLOWLOWERCASE, subttl);
} }
static void ST_drawPowerupHUD(void) static void ST_drawPowerupHUD(void)
@ -1135,7 +1139,8 @@ static void ST_drawPowerupHUD(void)
patch_t *p = NULL; patch_t *p = NULL;
UINT16 invulntime = 0; UINT16 invulntime = 0;
INT32 offs = hudinfo[HUD_POWERUPS].x; INT32 offs = hudinfo[HUD_POWERUPS].x;
static INT32 flagoffs = 0, shieldoffs = 0; const UINT8 q = ((splitscreen && stplyr == &players[secondarydisplayplayer]) ? 1 : 0);
static INT32 flagoffs[2] = {0, 0}, shieldoffs[2] = {0, 0};
#define ICONSEP (16+4) // matches weapon rings HUD #define ICONSEP (16+4) // matches weapon rings HUD
if (stplyr->spectator || stplyr->playerstate != PST_LIVE) if (stplyr->spectator || stplyr->playerstate != PST_LIVE)
@ -1144,7 +1149,7 @@ static void ST_drawPowerupHUD(void)
// Graue 06-18-2004: no V_NOSCALESTART, no SCX, no SCY, snap to right // Graue 06-18-2004: no V_NOSCALESTART, no SCX, no SCY, snap to right
if (stplyr->powers[pw_shield] & SH_NOSTACK) if (stplyr->powers[pw_shield] & SH_NOSTACK)
{ {
shieldoffs = ICONSEP; shieldoffs[q] = ICONSEP;
if ((stplyr->powers[pw_shield] & SH_NOSTACK & ~SH_FORCEHP) == SH_FORCE) if ((stplyr->powers[pw_shield] & SH_NOSTACK & ~SH_FORCEHP) == SH_FORCE)
{ {
@ -1173,32 +1178,32 @@ static void ST_drawPowerupHUD(void)
V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, p); V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, p);
} }
} }
else if (shieldoffs) else if (shieldoffs[q])
{ {
if (shieldoffs > 1) if (shieldoffs[q] > 1)
shieldoffs = 2*shieldoffs/3; shieldoffs[q] = 2*shieldoffs[q]/3;
else else
shieldoffs = 0; shieldoffs[q] = 0;
} }
offs -= shieldoffs; offs -= shieldoffs[q];
// YOU have a flag. Display a monitor-like icon for it. // YOU have a flag. Display a monitor-like icon for it.
if (stplyr->gotflag) if (stplyr->gotflag)
{ {
flagoffs = ICONSEP; flagoffs[q] = ICONSEP;
p = (stplyr->gotflag & GF_REDFLAG) ? gotrflag : gotbflag; p = (stplyr->gotflag & GF_REDFLAG) ? gotrflag : gotbflag;
V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, p); V_DrawSmallScaledPatch(offs, hudinfo[HUD_POWERUPS].y, V_PERPLAYER|hudinfo[HUD_POWERUPS].f|V_HUDTRANS, p);
} }
else if (flagoffs) else if (flagoffs[q])
{ {
if (flagoffs > 1) if (flagoffs[q] > 1)
flagoffs = 2*flagoffs/3; flagoffs[q] = 2*flagoffs[q]/3;
else else
flagoffs = 0; flagoffs[q] = 0;
} }
offs -= flagoffs; offs -= flagoffs[q];
invulntime = stplyr->powers[pw_flashing] ? stplyr->powers[pw_flashing] : stplyr->powers[pw_invulnerability]; invulntime = stplyr->powers[pw_flashing] ? stplyr->powers[pw_flashing] : stplyr->powers[pw_invulnerability];
if (stplyr->powers[pw_invulnerability] > 3*TICRATE || (invulntime && leveltime & 1)) if (stplyr->powers[pw_invulnerability] > 3*TICRATE || (invulntime && leveltime & 1))
@ -1394,7 +1399,6 @@ static void ST_drawNiGHTSHUD(void)
INT32 origamount; INT32 origamount;
INT32 minlink = 1; INT32 minlink = 1;
INT32 total_ringcount; INT32 total_ringcount;
boolean nosshack = false;
// When debugging, show "0 Link". // When debugging, show "0 Link".
if (cv_debug & DBG_NIGHTSBASIC) if (cv_debug & DBG_NIGHTSBASIC)
@ -1411,21 +1415,10 @@ static void ST_drawNiGHTSHUD(void)
#endif #endif
stplyr->powers[pw_carry] == CR_NIGHTSMODE) stplyr->powers[pw_carry] == CR_NIGHTSMODE)
{ {
INT32 locx, locy; INT32 locx = 16, locy = 180;
INT32 dfill; INT32 dfill;
UINT8 fillpatch; UINT8 fillpatch;
if (splitscreen)
{
locx = 110;
locy = 188;
}
else
{
locx = 16;
locy = 180;
}
// Use which patch? // Use which patch?
if (stplyr->pflags & PF_DRILLING) if (stplyr->pflags & PF_DRILLING)
fillpatch = (stplyr->drillmeter & 1) + 1; fillpatch = (stplyr->drillmeter & 1) + 1;
@ -1446,14 +1439,17 @@ static void ST_drawNiGHTSHUD(void)
} }
} }
if (G_IsSpecialStage(gamemap)) /*if (G_IsSpecialStage(gamemap))
{ // Since special stages share score, time, rings, etc. { // Since special stages share score, time, rings, etc.
// disable splitscreen mode for its HUD. // disable splitscreen mode for its HUD.
// --------------------------------------
// NOPE! Consistency between different splitscreen stuffs
// now we've got the screen squashing instead. ~toast
if (stplyr != &players[displayplayer]) if (stplyr != &players[displayplayer])
return; return;
nosshack = splitscreen; nosshack = splitscreen;
splitscreen = false; splitscreen = false;
} }*/
// Link drawing // Link drawing
if ( if (
@ -1462,42 +1458,39 @@ static void ST_drawNiGHTSHUD(void)
#endif #endif
stplyr->linkcount > minlink) stplyr->linkcount > minlink)
{ {
static INT32 prevsel[2] = {0, 0}, prevtime[2] = {0, 0};
const UINT8 q = ((splitscreen && stplyr == &players[secondarydisplayplayer]) ? 1 : 0);
INT32 sel = ((stplyr->linkcount-1) / 5) % NUMLINKCOLORS, aflag = V_PERPLAYER, mag = ((stplyr->linkcount-1 >= 300) ? 1 : 0);
skincolors_t colornum; skincolors_t colornum;
INT32 aflag = V_PERPLAYER;
fixed_t x, y, scale; fixed_t x, y, scale;
if (sel != prevsel[q])
{
prevsel[q] = sel;
prevtime[q] = 2 + mag;
}
if (stplyr->powers[pw_nights_linkfreeze] && (!(stplyr->powers[pw_nights_linkfreeze] & 2) || (stplyr->powers[pw_nights_linkfreeze] > flashingtics))) if (stplyr->powers[pw_nights_linkfreeze] && (!(stplyr->powers[pw_nights_linkfreeze] & 2) || (stplyr->powers[pw_nights_linkfreeze] > flashingtics)))
colornum = SKINCOLOR_ICY; colornum = SKINCOLOR_ICY;
else else
colornum = linkColor[((stplyr->linkcount-1 >= 300) ? 1 : 0)][((stplyr->linkcount-1) / 5) % NUMLINKCOLORS]; colornum = linkColor[mag][sel];
aflag |= ((stplyr->linktimer < 2*TICRATE/3) aflag |= ((stplyr->linktimer < 2*TICRATE/3)
? (9 - 9*stplyr->linktimer/(2*TICRATE/3)) << V_ALPHASHIFT ? (9 - 9*stplyr->linktimer/(2*TICRATE/3)) << V_ALPHASHIFT
: 0); : 0);
y = (nosshack ? 16+11+(BASEVIDHEIGHT/2) : 160+11)<<FRACBITS; y = (160+11)<<FRACBITS;
aflag |= V_SNAPTOBOTTOM; aflag |= V_SNAPTOBOTTOM;
if (splitscreen || nosshack) x = (160+4)<<FRACBITS;
if (prevtime[q])
{ {
aflag |= V_SNAPTORIGHT; scale = ((32 + prevtime[q])<<FRACBITS)/32;
x = (248+4)<<FRACBITS; prevtime[q]--;
} }
else else
x = (160+4)<<FRACBITS; scale = FRACUNIT;
switch (stplyr->linktimer)
{
case (2*TICRATE):
scale = (36*FRACUNIT)/32;
break;
case (2*TICRATE - 1):
scale = (34*FRACUNIT)/32;
break;
default:
scale = FRACUNIT;
break;
}
y -= (11*scale); y -= (11*scale);
@ -1619,7 +1612,7 @@ static void ST_drawNiGHTSHUD(void)
&& LUA_HudEnabled(hud_nightsscore) && LUA_HudEnabled(hud_nightsscore)
#endif #endif
) )
ST_DrawNightsOverlayNum(304<<FRACBITS, 16<<FRACBITS, FRACUNIT, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTORIGHT, stplyr->marescore, nightsnum, SKINCOLOR_AZURE); ST_DrawNightsOverlayNum(304<<FRACBITS, 14<<FRACBITS, FRACUNIT, V_PERPLAYER|V_SNAPTOTOP|V_SNAPTORIGHT, stplyr->marescore, nightsnum, SKINCOLOR_AZURE);
if (!stplyr->exiting if (!stplyr->exiting
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
@ -1687,7 +1680,7 @@ static void ST_drawNiGHTSHUD(void)
else else
numbersize = 48/2; numbersize = 48/2;
ST_DrawNightsOverlayNum((160 + numbersize)<<FRACBITS, 12<<FRACBITS, FRACUNIT, V_PERPLAYER|V_SNAPTOTOP, realnightstime, nightsnum, ST_DrawNightsOverlayNum((160 + numbersize)<<FRACBITS, 14<<FRACBITS, FRACUNIT, V_PERPLAYER|V_SNAPTOTOP, realnightstime, nightsnum,
((realnightstime < 10) ? SKINCOLOR_RED : SKINCOLOR_SUPERGOLD4)); ((realnightstime < 10) ? SKINCOLOR_RED : SKINCOLOR_SUPERGOLD4));
// Show exact time in debug // Show exact time in debug
@ -1727,9 +1720,28 @@ static void ST_drawNiGHTSHUD(void)
if (LUA_HudEnabled(hud_nightsrecords)) if (LUA_HudEnabled(hud_nightsrecords))
#endif #endif
ST_drawNightsRecords(); ST_drawNightsRecords();
}
if (nosshack) static inline void ST_drawWeaponSelect(INT32 xoffs, INT32 y)
splitscreen = true; {
INT32 q = stplyr->weapondelay, del = 0, p = 16;
while (q)
{
if (q > p)
{
del += p;
q -= p;
q /= 2;
if (p > 1)
p /= 2;
}
else
{
del += q;
break;
}
}
V_DrawScaledPatch(6 + xoffs, y-2 - del/2, V_PERPLAYER|V_SNAPTOBOTTOM, curweapon);
} }
static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, INT32 xoffs, INT32 y, patch_t *pat) static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, INT32 xoffs, INT32 y, patch_t *pat)
@ -1751,14 +1763,10 @@ static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, I
} }
V_DrawScaledPatch(8 + xoffs, y, V_PERPLAYER|V_SNAPTOBOTTOM|patflags, pat); V_DrawScaledPatch(8 + xoffs, y, V_PERPLAYER|V_SNAPTOBOTTOM|patflags, pat);
V_DrawRightAlignedThinString(24 + xoffs, y + 8, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon]));
//if (stplyr->powers[weapon] > 9)
V_DrawRightAlignedThinString(24 + xoffs, y + 8, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon]));
/*else
V_DrawRightAlignedString(24 + xoffs, y + 8, V_PERPLAYER|V_SNAPTOBOTTOM|txtflags, va("%d", stplyr->powers[weapon]));*/
if (stplyr->currentweapon == wepflag) if (stplyr->currentweapon == wepflag)
V_DrawScaledPatch(6 + xoffs, y-2, V_PERPLAYER|V_SNAPTOBOTTOM, curweapon); ST_drawWeaponSelect(xoffs, y);
} }
else if (stplyr->ringweapons & rwflag) else if (stplyr->ringweapons & rwflag)
V_DrawScaledPatch(8 + xoffs, y, V_PERPLAYER|V_SNAPTOBOTTOM|V_TRANSLUCENT, pat); V_DrawScaledPatch(8 + xoffs, y, V_PERPLAYER|V_SNAPTOBOTTOM|V_TRANSLUCENT, pat);
@ -1778,13 +1786,16 @@ static void ST_drawMatchHUD(void)
{ {
if (stplyr->powers[pw_infinityring]) if (stplyr->powers[pw_infinityring])
ST_drawWeaponRing(pw_infinityring, 0, 0, offset, y, infinityring); ST_drawWeaponRing(pw_infinityring, 0, 0, offset, y, infinityring);
else if (stplyr->rings > 0)
V_DrawScaledPatch(8 + offset, y, V_PERPLAYER|V_SNAPTOBOTTOM, normring);
else else
V_DrawTranslucentPatch(8 + offset, y, V_PERPLAYER|V_SNAPTOBOTTOM|V_80TRANS, normring); {
if (stplyr->rings > 0)
V_DrawScaledPatch(8 + offset, y, V_PERPLAYER|V_SNAPTOBOTTOM, normring);
else
V_DrawTranslucentPatch(8 + offset, y, V_PERPLAYER|V_SNAPTOBOTTOM|V_80TRANS, normring);
if (!stplyr->currentweapon) if (!stplyr->currentweapon)
V_DrawScaledPatch(6 + offset, y-2, V_PERPLAYER|V_SNAPTOBOTTOM, curweapon); ST_drawWeaponSelect(offset, y);
}
offset += 20; offset += 20;
ST_drawWeaponRing(pw_automaticring, RW_AUTO, WEP_AUTO, offset, y, autoring); ST_drawWeaponRing(pw_automaticring, RW_AUTO, WEP_AUTO, offset, y, autoring);
@ -1801,38 +1812,145 @@ static void ST_drawMatchHUD(void)
} }
} }
static void ST_drawTextHUD(void)
{
INT32 y = 176 - 16; // HUD_LIVES
boolean dof12 = false, dospecheader = false;
#define textHUDdraw(str) \
{\
V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, str);\
y -= 8;\
}
if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (!stplyr->spectator))
{
if (leveltime < hidetime * TICRATE)
{
if (stplyr->pflags & PF_TAGIT)
{
textHUDdraw(M_GetText("Waiting for players to hide..."))
textHUDdraw(M_GetText("\x82""You are blindfolded!"))
}
else if (gametype == GT_HIDEANDSEEK)
textHUDdraw(M_GetText("Hide before time runs out!"))
else
textHUDdraw(M_GetText("Flee before you are hunted!"))
}
else if (gametype == GT_HIDEANDSEEK && !(stplyr->pflags & PF_TAGIT))
{
textHUDdraw(M_GetText("You cannot move while hiding."))
dof12 = true;
}
}
if (!stplyr->spectator && stplyr->exiting && cv_playersforexit.value && gametype == GT_COOP)
{
INT32 i, total = 0, exiting = 0;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
if (players[i].lives <= 0)
continue;
total++;
if (players[i].exiting)
exiting++;
}
if (cv_playersforexit.value != 4)
{
total *= cv_playersforexit.value;
if (total & 3)
total += 4; // round up
total /= 4;
}
if (exiting < total)
{
total -= exiting;
textHUDdraw(va(M_GetText("%d player%s remaining"), total, ((total == 1) ? "" : "s")))
dof12 = true;
}
}
else if (gametype != GT_COOP && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1)))
dof12 = true;
else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text.
{
INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE;
if (respawntime > 0 && !stplyr->spectator)
textHUDdraw(va(M_GetText("Respawn in %d..."), respawntime))
else
textHUDdraw(M_GetText("\x82""JUMP:""\x80 Respawn"))
}
else if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE))
{
if (G_IsSpecialStage(gamemap) && useNightsSS)
textHUDdraw(M_GetText("\x82""Wait for the stage to end..."))
else if (gametype == GT_COOP)
{
if (stplyr->lives <= 0
&& cv_cooplives.value == 2
&& (netgame || multiplayer))
{
INT32 i;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
if (&players[i] == stplyr)
continue;
if (players[i].lives > 1)
break;
}
if (i != MAXPLAYERS)
textHUDdraw(M_GetText("You'll steal a life on respawn..."))
else
textHUDdraw(M_GetText("Wait to respawn..."))
}
else
textHUDdraw(M_GetText("Wait to respawn..."))
}
else
textHUDdraw(M_GetText("\x82""FIRE:""\x80 Enter game"))
textHUDdraw(M_GetText("\x82""SPIN:""\x80 Sink"))
textHUDdraw(M_GetText("\x82""JUMP:""\x80 Float"))
dof12 = true;
dospecheader = true;
}
if (!splitscreen && dof12)
textHUDdraw(M_GetText("\x82""F12:""\x80 Switch view"))
if (circuitmap)
{
if (stplyr->exiting)
textHUDdraw(M_GetText("\x82""FINISHED!"))
else
textHUDdraw(va("Lap:""\x82 %u/%d", stplyr->laps+1, cv_numlaps.value))
}
if (dospecheader)
textHUDdraw(M_GetText("\x86""Spectator mode:"))
#undef textHUDdraw
}
static inline void ST_drawRaceHUD(void) static inline void ST_drawRaceHUD(void)
{ {
if (leveltime > TICRATE && leveltime <= 5*TICRATE) if (leveltime > TICRATE && leveltime <= 5*TICRATE)
ST_drawRaceNum(4*TICRATE - leveltime); ST_drawRaceNum(4*TICRATE - leveltime);
} }
static void ST_drawTagHUD(void)
{
char pstext[33] = "";
// Figure out what we're going to print.
if (leveltime < hidetime * TICRATE) //during the hide time, the seeker and hiders have different messages on their HUD.
{
if (stplyr->pflags & PF_TAGIT)
sprintf(pstext, "%s", M_GetText("Waiting for players to hide..."));
else if (gametype == GT_HIDEANDSEEK) //hide and seek.
sprintf(pstext, "%s", M_GetText("Hide before time runs out!"));
else //default
sprintf(pstext, "%s", M_GetText("Flee before you are hunted!"));
}
else if (gametype == GT_HIDEANDSEEK && !(stplyr->pflags & PF_TAGIT))
{
sprintf(pstext, "%s", M_GetText("You cannot move while hiding."));
if (!splitscreen)
V_DrawThinString(16, 176 - 24, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""F12:""\x80 Switch view"));
}
// Print the stuff.
if (pstext[0])
V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, pstext);
}
static void ST_drawTeamHUD(void) static void ST_drawTeamHUD(void)
{ {
patch_t *p; patch_t *p;
@ -2157,9 +2275,6 @@ static void ST_overlayDrawer(void)
// Race HUD Stuff // Race HUD Stuff
if (gametype == GT_RACE || gametype == GT_COMPETITION) if (gametype == GT_RACE || gametype == GT_COMPETITION)
ST_drawRaceHUD(); ST_drawRaceHUD();
// Tag HUD Stuff
else if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (!stplyr->spectator))
ST_drawTagHUD();
// Special Stage HUD // Special Stage HUD
if (!useNightsSS && G_IsSpecialStage(gamemap) && stplyr == &players[displayplayer]) if (!useNightsSS && G_IsSpecialStage(gamemap) && stplyr == &players[displayplayer])
@ -2207,103 +2322,12 @@ static void ST_overlayDrawer(void)
) )
ST_drawLevelTitle(); ST_drawLevelTitle();
if (!hu_showscores && (netgame || multiplayer) && displayplayer == consoleplayer) if (!hu_showscores && (netgame || multiplayer)
{
if (!stplyr->spectator && stplyr->exiting && cv_playersforexit.value && gametype == GT_COOP)
{
INT32 i, total = 0, exiting = 0;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
if (players[i].lives <= 0)
continue;
total++;
if (players[i].exiting)
exiting++;
}
if (cv_playersforexit.value != 4)
{
total *= cv_playersforexit.value;
if (total & 3)
total += 4; // round up
total /= 4;
}
if (exiting < total)
{
total -= exiting;
V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, va(M_GetText("%d player%s remaining"), total, ((total == 1) ? "" : "s")));
if (!splitscreen)
{
V_DrawThinString(16, 176 - 24, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""F12:""\x80 Switch view"));
}
}
}
else if (!splitscreen && gametype != GT_COOP && (stplyr->exiting || (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1)))
V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""F12:""\x80 Switch view"));
else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) //Death overrides spectator text.
{
INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE;
if (respawntime > 0 && !stplyr->spectator)
V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, va(M_GetText("Respawn in %d..."), respawntime));
else
V_DrawThinString(16, 176 - 16, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""JUMP:""\x80 Respawn"));
}
else if (stplyr->spectator && (gametype != GT_COOP || stplyr->playerstate == PST_LIVE)
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
&& LUA_HudEnabled(hud_textspectator) && LUA_HudEnabled(hud_textspectator)
#endif #endif
) )
{ ST_drawTextHUD();
INT32 y = 176 - 16; // HUD_LIVES
if (G_IsSpecialStage(gamemap) && useNightsSS)
V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_YELLOWMAP, M_GetText("Wait for the stage to end..."));
else if (gametype == GT_COOP)
{
if (stplyr->lives <= 0
&& cv_cooplives.value == 2
&& (netgame || multiplayer))
{
INT32 i;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
if (&players[i] == stplyr)
continue;
if (players[i].lives > 1)
break;
}
if (i != MAXPLAYERS)
V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("You'll steal a life on respawn..."));
else
V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("Wait to respawn..."));
}
else
V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("Wait to respawn..."));
}
else
V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""FIRE:""\x80 Enter game"));
y -= 8;
V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""SPIN:""\x80 Sink"));
y -= 8;
V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""JUMP:""\x80 Float"));
y -= 8;
if (!splitscreen)
{
V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, M_GetText("\x82""F12:""\x80 Switch view"));
y -= 8;
}
V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_GRAYMAP, M_GetText("Spectator mode:"));
}
}
if (modeattacking) if (modeattacking)
ST_drawInput(); ST_drawInput();
@ -2353,13 +2377,11 @@ void ST_Drawer(void)
{ {
stplyr = &players[displayplayer]; stplyr = &players[displayplayer];
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31|V_PERPLAYER); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31|V_PERPLAYER);
V_DrawThinString(16, 176 - 24, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_YELLOWMAP, M_GetText("You are blindfolded!"));
} }
else if (splitscreen && players[secondarydisplayplayer].pflags & PF_TAGIT) else if (splitscreen && players[secondarydisplayplayer].pflags & PF_TAGIT)
{ {
stplyr = &players[secondarydisplayplayer]; stplyr = &players[secondarydisplayplayer];
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31|V_PERPLAYER); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31|V_PERPLAYER);
V_DrawThinString(16, 176 - 24, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_YELLOWMAP, M_GetText("You are blindfolded!"));
} }
} }