mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 17:22:12 +00:00
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:
parent
964df31ee5
commit
726cd9757b
7 changed files with 81 additions and 86 deletions
15
src/g_game.c
15
src/g_game.c
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
126
src/p_user.c
126
src/p_user.c
|
@ -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.
|
||||||
|
|
|
@ -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."));
|
||||||
|
|
Loading…
Reference in a new issue