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

View file

@ -3299,12 +3299,6 @@ void A_ExtraLife(mobj_t *actor)
if (!playeringame[i])
continue;
if ((netgame || multiplayer) && players[i].spectator) // Ignore spectators
continue;
if (players[i].bot)
continue;
P_GivePlayerLives(&players[i], 1);
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].starpostnum = special->health;
if (cv_playstyle.value == 2 && (P_GetLives(&players[i]) || players[i].lives > 0) && players[i].playerstate == PST_DEAD)
players[i].playerstate = PST_REBORN;
if (cv_playstyle.value == 2 && (P_GetLives(&players[i]) || players[i].lives > 0) && (players[i].playerstate == PST_DEAD || players[i].spectator))
P_SpectatorJoinGame(&players[i]); //players[i].playerstate = PST_REBORN;
}
}
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));
boolean P_GetLives(player_t *player);
boolean P_SpectatorJoinGame(player_t *player);
//
// P_MOBJ

View file

@ -9086,7 +9086,9 @@ void P_SpawnPlayer(INT32 playernum)
{
// Special case for (NiGHTS) special stages!
// 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;
else
p->spectator = false;
@ -9134,6 +9136,9 @@ void P_SpawnPlayer(INT32 playernum)
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->player = p)->mo = mobj;

View file

@ -946,12 +946,6 @@ void P_GivePlayerRings(player_t *player, INT32 num_rings)
if (!playeringame[i])
continue;
if ((netgame || multiplayer) && players[i].spectator) // Ignore spectators
continue;
if (players[i].bot)
continue;
P_GivePlayerLives(&players[i], gainlives);
P_PlayLivesJingle(&players[i]);
}
@ -8119,9 +8113,6 @@ boolean P_GetLives(player_t *player)
if (!playeringame[i])
continue;
if (players[i].spectator) // Ignore spectators
continue;
if (players[i].lives > livescheck)
{
maxlivesplayer = i;
@ -8143,6 +8134,41 @@ boolean P_GetLives(player_t *player)
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
// Fall on your face when dying.
@ -8173,17 +8199,11 @@ static void P_DeathThink(player_t *player)
&& (netgame || multiplayer)
&& (player->lives <= 0))
{
for (j = 0; j < MAXPLAYERS; j++)
for (; j < MAXPLAYERS; j++)
{
if (!playeringame[j])
continue;
if (players[j].spectator) // Ignore spectators
continue;
if (players[j].bot) // ignore dumb, stupid tails
continue;
if (players[j].lives > 1)
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!
{
if (gametype == GT_COOP && (netgame || multiplayer) && cv_playstyle.value == 2) // Shamelessly lifted from TD. Thanks, Sryder!
P_ConsiderAllGone();
if ((player->deadtimer > 5*TICRATE) || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))
{
INT32 i, lastdeadplayer = -1, deadtimercheck = INT32_MAX;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
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;
player->spectator = true;
player->playerstate = PST_REBORN;
}
else
{
// Respawn with jump button, force respawn time (3 second default, cheat protected) in shooter modes.
if (cmd->buttons & BT_JUMP)
{
if (player->spectator)
if (gametype != GT_COOP && player->spectator)
player->playerstate = PST_REBORN;
else switch(gametype) {
case GT_COOP:
@ -8254,33 +8254,39 @@ static void P_DeathThink(player_t *player)
}
else if ((netgame || multiplayer) && player->deadtimer == 8*TICRATE)
{
INT32 i, deadtimercheck = INT32_MAX;
// In a net/multiplayer game, and out of lives
if (gametype == GT_COMPETITION)
{
INT32 i;
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && !players[i].exiting && players[i].lives)
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.
if (!countdown2 || countdown2 > 1*TICRATE)
countdown2 = 1*TICRATE;
}
}
// 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++)
{
if (playeringame[i] && (players[i].exiting || players[i].lives))
break;
if (players[i].deadtimer < deadtimercheck)
deadtimercheck = players[i].deadtimer;
}
if (i == MAXPLAYERS)
if (i == MAXPLAYERS && deadtimercheck == 8*TICRATE)
{
// They're dead, Jim.
//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);
}
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 (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 (gametype != GT_COOP && !cv_allowteamchange.value)
{
if (P_IsLocalPlayer(player))
CONS_Printf(M_GetText("Server does not allow team change.\n"));
@ -9088,6 +9087,7 @@ static boolean P_SpectatorJoinGame(player_t *player)
if (P_IsLocalPlayer(player) && displayplayer != consoleplayer)
displayplayer = consoleplayer;
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.
}
@ -9401,6 +9401,8 @@ void P_PlayerThink(player_t *player)
if (!player->spectator)
P_PlayerInSpecialSector(player);
else if (gametype == GT_COOP && (netgame || multiplayer) && cv_playstyle.value == 2)
P_ConsiderAllGone();
if (player->playerstate == PST_DEAD)
{
@ -9446,7 +9448,11 @@ void P_PlayerThink(player_t *player)
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))
return; // player->mo was removed.

View file

@ -742,9 +742,6 @@ static void ST_drawLives(void)
if (!playeringame[i])
continue;
if (players[i].spectator) // Ignore spectators
continue;
if (&players[i] == stplyr)
continue;
@ -1862,9 +1859,6 @@ static void ST_overlayDrawer(void)
if (!playeringame[i])
continue;
if (players[i].spectator) // Ignore spectators
continue;
if (&players[i] == stplyr)
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."));
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."));
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(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."));