Spectators in new Coop instead of staring at a dead screen all the time!

Needs a bunch of changes to HUD rendering, especially in splitscreen, which doesn't try to show spectator stuff whatsoever. Also, if you're the player whose respawn determines when the map reloads, you'll see the spectator text during the front half of the fade. Unless, of course, it's 2-player mode.
This commit is contained in:
toasterbabe 2017-05-29 21:23:00 +01:00
parent 964df31ee5
commit 726cd9757b
7 changed files with 81 additions and 86 deletions

View File

@ -2205,8 +2205,8 @@ void G_PlayerReborn(INT32 player)
p->rings = 0; // 0 rings p->rings = 0; // 0 rings
p->panim = PA_IDLE; // standing animation p->panim = PA_IDLE; // standing animation
if ((netgame || multiplayer) && !p->spectator) //if ((netgame || multiplayer) && !p->spectator) -- moved into P_SpawnPlayer to account for forced changes there
p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent //p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent
if (p-players == consoleplayer) if (p-players == consoleplayer)
{ {
@ -2597,16 +2597,11 @@ void G_DoReborn(INT32 playernum)
INT32 i; INT32 i;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
if (!(playeringame[i] && players[i].playerstate == PST_LIVE)) if (!playeringame[i])
continue; continue;
if (players[i].spectator) // Ignore spectators if (players[i].playerstate != PST_DEAD && !players[i].spectator && players[i].mo && players[i].mo->health)
continue; break;
if (players[i].bot) // ignore dumb, stupid tails
continue;
break;
} }
if (i == MAXPLAYERS) if (i == MAXPLAYERS)
{ {

View File

@ -3299,12 +3299,6 @@ void A_ExtraLife(mobj_t *actor)
if (!playeringame[i]) if (!playeringame[i])
continue; continue;
if ((netgame || multiplayer) && players[i].spectator) // Ignore spectators
continue;
if (players[i].bot)
continue;
P_GivePlayerLives(&players[i], 1); P_GivePlayerLives(&players[i], 1);
P_PlayLivesJingle(&players[i]); P_PlayLivesJingle(&players[i]);
} }

View File

@ -1309,8 +1309,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
players[i].starpostangle = special->angle; players[i].starpostangle = special->angle;
players[i].starpostnum = special->health; players[i].starpostnum = special->health;
if (cv_playstyle.value == 2 && (P_GetLives(&players[i]) || players[i].lives > 0) && players[i].playerstate == PST_DEAD) if (cv_playstyle.value == 2 && (P_GetLives(&players[i]) || players[i].lives > 0) && (players[i].playerstate == PST_DEAD || players[i].spectator))
players[i].playerstate = PST_REBORN; P_SpectatorJoinGame(&players[i]); //players[i].playerstate = PST_REBORN;
} }
} }
S_StartSound(NULL, special->info->painsound); S_StartSound(NULL, special->info->painsound);

View File

@ -199,6 +199,7 @@ void P_PlayLivesJingle(player_t *player);
#define P_PlayVictorySound(s) S_StartSound(s, sfx_victr1 + P_RandomKey(4)); #define P_PlayVictorySound(s) S_StartSound(s, sfx_victr1 + P_RandomKey(4));
boolean P_GetLives(player_t *player); boolean P_GetLives(player_t *player);
boolean P_SpectatorJoinGame(player_t *player);
// //
// P_MOBJ // P_MOBJ

View File

@ -9086,7 +9086,9 @@ void P_SpawnPlayer(INT32 playernum)
{ {
// Special case for (NiGHTS) special stages! // Special case for (NiGHTS) special stages!
// if stage has already started, force players to become spectators until the next stage // if stage has already started, force players to become spectators until the next stage
if (multiplayer && netgame && G_IsSpecialStage(gamemap) && useNightsSS && leveltime > 0) if (((multiplayer || netgame) && leveltime > 0)
&& ((G_IsSpecialStage(gamemap) && useNightsSS)
|| (gametype == GT_COOP && cv_playstyle.value == 2 && (p->jointime < 1 || p->spectator))))
p->spectator = true; p->spectator = true;
else else
p->spectator = false; p->spectator = false;
@ -9134,6 +9136,9 @@ void P_SpawnPlayer(INT32 playernum)
p->skincolor = skincolor_blueteam; p->skincolor = skincolor_blueteam;
} }
if ((netgame || multiplayer) && !p->spectator)
p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent
mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER); mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER);
(mobj->player = p)->mo = mobj; (mobj->player = p)->mo = mobj;

View File

@ -946,12 +946,6 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings)
if (!playeringame[i]) if (!playeringame[i])
continue; continue;
if ((netgame || multiplayer) && players[i].spectator) // Ignore spectators
continue;
if (players[i].bot)
continue;
P_GivePlayerLives(&players[i], gainlives); P_GivePlayerLives(&players[i], gainlives);
P_PlayLivesJingle(&players[i]); P_PlayLivesJingle(&players[i]);
} }
@ -8119,9 +8113,6 @@ boolean P_GetLives(player_t *player)
if (!playeringame[i]) if (!playeringame[i])
continue; continue;
if (players[i].spectator) // Ignore spectators
continue;
if (players[i].lives > livescheck) if (players[i].lives > livescheck)
{ {
maxlivesplayer = i; maxlivesplayer = i;
@ -8143,6 +8134,41 @@ boolean P_GetLives(player_t *player)
return false; return false;
} }
//
// P_ConsiderAllGone
// Shamelessly lifted from TD. Thanks, Sryder!
//
static void P_ConsiderAllGone(void)
{
INT32 i, lastdeadplayer = -1, deadtimercheck = INT32_MAX;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
if (players[i].playerstate != PST_DEAD && !players[i].spectator && players[i].mo && players[i].mo->health)
break;
if (players[i].lives > 0)
{
if (players[i].spectator && lastdeadplayer == -1)
;
else if (players[i].deadtimer < deadtimercheck)
deadtimercheck = players[i].deadtimer;
else
continue;
lastdeadplayer = i;
}
}
if (i == MAXPLAYERS && lastdeadplayer != -1 && deadtimercheck > 2*TICRATE) // the last killed player will reset the level in G_DoReborn
{
players[lastdeadplayer].spectator = true;
players[lastdeadplayer].playerstate = PST_REBORN;
}
}
// //
// P_DeathThink // P_DeathThink
// Fall on your face when dying. // Fall on your face when dying.
@ -8173,17 +8199,11 @@ static void P_DeathThink(player_t *player)
&& (netgame || multiplayer) && (netgame || multiplayer)
&& (player->lives <= 0)) && (player->lives <= 0))
{ {
for (j = 0; j < MAXPLAYERS; j++) for (; j < MAXPLAYERS; j++)
{ {
if (!playeringame[j]) if (!playeringame[j])
continue; continue;
if (players[j].spectator) // Ignore spectators
continue;
if (players[j].bot) // ignore dumb, stupid tails
continue;
if (players[j].lives > 1) if (players[j].lives > 1)
break; break;
} }
@ -8195,38 +8215,18 @@ static void P_DeathThink(player_t *player)
else if ((player->lives > 0 || j != MAXPLAYERS) && !G_IsSpecialStage(gamemap)) // Don't allow "click to respawn" in special stages! else if ((player->lives > 0 || j != MAXPLAYERS) && !G_IsSpecialStage(gamemap)) // Don't allow "click to respawn" in special stages!
{ {
if (gametype == GT_COOP && (netgame || multiplayer) && cv_playstyle.value == 2) // Shamelessly lifted from TD. Thanks, Sryder! if (gametype == GT_COOP && (netgame || multiplayer) && cv_playstyle.value == 2) // Shamelessly lifted from TD. Thanks, Sryder!
{ P_ConsiderAllGone();
INT32 i, lastdeadplayer = -1, deadtimercheck = INT32_MAX; if ((player->deadtimer > 5*TICRATE) || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))
for (i = 0; i < MAXPLAYERS; i++)
{ {
if (!playeringame[i]) player->spectator = true;
continue; player->playerstate = PST_REBORN;
if (players[i].spectator) // Ignore spectators
continue;
if (players[i].bot) // ignore dumb, stupid tails
continue;
if (players[i].playerstate != PST_DEAD)
break;
if (players[i].lives && players[i].deadtimer < deadtimercheck)
{
lastdeadplayer = i;
deadtimercheck = players[i].deadtimer;
}
} }
if (i == MAXPLAYERS && lastdeadplayer != -1 && deadtimercheck > 2*TICRATE) // the last killed player will reset the level in G_DoReborn
players[lastdeadplayer].playerstate = PST_REBORN;
}
else else
{ {
// Respawn with jump button, force respawn time (3 second default, cheat protected) in shooter modes. // Respawn with jump button, force respawn time (3 second default, cheat protected) in shooter modes.
if (cmd->buttons & BT_JUMP) if (cmd->buttons & BT_JUMP)
{ {
if (player->spectator) if (gametype != GT_COOP && player->spectator)
player->playerstate = PST_REBORN; player->playerstate = PST_REBORN;
else switch(gametype) { else switch(gametype) {
case GT_COOP: case GT_COOP:
@ -8254,33 +8254,39 @@ static void P_DeathThink(player_t *player)
} }
else if ((netgame || multiplayer) && player->deadtimer == 8*TICRATE) else if ((netgame || multiplayer) && player->deadtimer == 8*TICRATE)
{ {
INT32 i, deadtimercheck = INT32_MAX;
// In a net/multiplayer game, and out of lives // In a net/multiplayer game, and out of lives
if (gametype == GT_COMPETITION) if (gametype == GT_COMPETITION)
{ {
INT32 i;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && !players[i].exiting && players[i].lives) if (playeringame[i] && !players[i].exiting && players[i].lives)
break; break;
if (players[i].deadtimer < deadtimercheck)
deadtimercheck = players[i].deadtimer;
}
if (i == MAXPLAYERS) if (i == MAXPLAYERS && deadtimercheck == 8*TICRATE)
{ {
// Everyone's either done with the race, or dead. // Everyone's either done with the race, or dead.
if (!countdown2 || countdown2 > 1*TICRATE) if (!countdown2 || countdown2 > 1*TICRATE)
countdown2 = 1*TICRATE; countdown2 = 1*TICRATE;
} }
} }
// In a coop game, and out of lives // In a coop game, and out of lives
if (gametype == GT_COOP) else if (gametype == GT_COOP)
{ {
INT32 i;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && (players[i].exiting || players[i].lives)) if (playeringame[i] && (players[i].exiting || players[i].lives))
break; break;
if (players[i].deadtimer < deadtimercheck)
deadtimercheck = players[i].deadtimer;
}
if (i == MAXPLAYERS) if (i == MAXPLAYERS && deadtimercheck == 8*TICRATE)
{ {
// They're dead, Jim. // They're dead, Jim.
//nextmapoverride = spstage_start; //nextmapoverride = spstage_start;
@ -8991,16 +8997,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
return (x == thiscam->x && y == thiscam->y && z == thiscam->z && angle == thiscam->aiming); return (x == thiscam->x && y == thiscam->y && z == thiscam->z && angle == thiscam->aiming);
} }
static boolean P_SpectatorJoinGame(player_t *player) boolean P_SpectatorJoinGame(player_t *player)
{ {
if (!G_GametypeHasSpectators() && G_IsSpecialStage(gamemap) && useNightsSS) // Special Stage spectators should NEVER be allowed to rejoin the game if (gametype != GT_COOP && !cv_allowteamchange.value)
{
if (P_IsLocalPlayer(player))
CONS_Printf(M_GetText("You cannot enter the game while a special stage is in progress.\n"));
player->powers[pw_flashing] += 2*TICRATE; //to prevent message spam.
}
else if (!cv_allowteamchange.value)
{ {
if (P_IsLocalPlayer(player)) if (P_IsLocalPlayer(player))
CONS_Printf(M_GetText("Server does not allow team change.\n")); CONS_Printf(M_GetText("Server does not allow team change.\n"));
@ -9088,7 +9087,8 @@ static boolean P_SpectatorJoinGame(player_t *player)
if (P_IsLocalPlayer(player) && displayplayer != consoleplayer) if (P_IsLocalPlayer(player) && displayplayer != consoleplayer)
displayplayer = consoleplayer; displayplayer = consoleplayer;
CONS_Printf(M_GetText("%s entered the game.\n"), player_names[player-players]); if (gametype != GT_COOP)
CONS_Printf(M_GetText("%s entered the game.\n"), player_names[player-players]);
return true; // no more player->mo, cannot continue. return true; // no more player->mo, cannot continue.
} }
else else
@ -9401,6 +9401,8 @@ void P_PlayerThink(player_t *player)
if (!player->spectator) if (!player->spectator)
P_PlayerInSpecialSector(player); P_PlayerInSpecialSector(player);
else if (gametype == GT_COOP && (netgame || multiplayer) && cv_playstyle.value == 2)
P_ConsiderAllGone();
if (player->playerstate == PST_DEAD) if (player->playerstate == PST_DEAD)
{ {
@ -9446,7 +9448,11 @@ void P_PlayerThink(player_t *player)
player->realtime = leveltime; player->realtime = leveltime;
} }
if ((netgame || splitscreen) && player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing]) if ((netgame || splitscreen) && player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing]
&& (G_GametypeHasSpectators()
|| !((G_IsSpecialStage(gamemap) && useNightsSS)
|| (gametype == GT_COOP && cv_playstyle.value == 2)
)))
{ {
if (P_SpectatorJoinGame(player)) if (P_SpectatorJoinGame(player))
return; // player->mo was removed. return; // player->mo was removed.

View File

@ -742,9 +742,6 @@ static void ST_drawLives(void)
if (!playeringame[i]) if (!playeringame[i])
continue; continue;
if (players[i].spectator) // Ignore spectators
continue;
if (&players[i] == stplyr) if (&players[i] == stplyr)
continue; continue;
@ -1862,9 +1859,6 @@ static void ST_overlayDrawer(void)
if (!playeringame[i]) if (!playeringame[i])
continue; continue;
if (players[i].spectator) // Ignore spectators
continue;
if (&players[i] == stplyr) if (&players[i] == stplyr)
continue; continue;
@ -1988,7 +1982,7 @@ static void ST_overlayDrawer(void)
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Fire to be assigned to a team.")); V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Fire to be assigned to a team."));
else if (G_IsSpecialStage(gamemap) && useNightsSS) else if (G_IsSpecialStage(gamemap) && useNightsSS)
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("You cannot join the game until the stage has ended.")); V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("You cannot join the game until the stage has ended."));
else else if (!gametype == GT_COOP)
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Fire to enter the game.")); V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), V_HUDTRANSHALF, M_GetText("Press Fire to enter the game."));
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(148), V_HUDTRANSHALF, M_GetText("Press F12 to watch another player.")); V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(148), V_HUDTRANSHALF, M_GetText("Press F12 to watch another player."));
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(164), V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink.")); V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(164), V_HUDTRANSHALF, M_GetText("Press Jump to float and Spin to sink."));