* Spectatoring for game over supported.

* Don't lose lives when you die as a spectator.
This commit is contained in:
toasterbabe 2017-05-30 20:31:51 +01:00
parent 9fbcd6e883
commit 4353fa65a2
5 changed files with 139 additions and 74 deletions

View file

@ -2592,68 +2592,104 @@ void G_DoReborn(INT32 playernum)
// respawn at the start
mobj_t *oldmo = NULL;
if (gametype == GT_COOP && (netgame || multiplayer) && cv_playstyle.value == 2)
if (gametype == GT_COOP && (netgame || multiplayer))
{
INT32 i;
for (i = 0; i < MAXPLAYERS; i++)
if (player->lives <= 0) // consider game over first
{
if (!playeringame[i])
continue;
if (players[i].playerstate != PST_DEAD && !players[i].spectator && players[i].mo && players[i].mo->health)
break;
}
if (i == MAXPLAYERS)
{
if (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD)
INT32 deadtimercheck = INT32_MAX;
for (i = 0; i < MAXPLAYERS; i++)
{
INT32 j;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
players[i].playerstate = PST_REBORN;
}
P_LoadThingsOnly();
P_ClearStarPost(player->starpostnum);
// Do a wipe
wipegamestate = -1;
if (camera.chase)
P_ResetCamera(&players[displayplayer], &camera);
if (camera2.chase && splitscreen)
P_ResetCamera(&players[secondarydisplayplayer], &camera2);
// clear cmd building stuff
memset(gamekeydown, 0, sizeof (gamekeydown));
for (j = 0; j < JOYAXISSET; j++)
{
joyxmove[j] = joyymove[j] = 0;
joy2xmove[j] = joy2ymove[j] = 0;
}
mousex = mousey = 0;
mouse2x = mouse2y = 0;
// clear hud messages remains (usually from game startup)
CON_ClearHUD();
// Starpost support
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
G_SpawnPlayer(i, (players[i].starposttime != 0));
}
return;
if (!playeringame[i])
continue;
if (players[i].exiting || players[i].lives)
break;
if (players[i].playerstate == PST_DEAD && players[i].deadtimer < deadtimercheck)
deadtimercheck = players[i].deadtimer;
}
if (i == MAXPLAYERS && deadtimercheck >= 8*TICRATE)
{
// They're dead, Jim.
//nextmapoverride = spstage_start;
nextmapoverride = gamemap;
countdown2 = 1*TICRATE;
skipstats = true;
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i])
players[i].score = 0;
}
//emeralds = 0;
tokenbits = 0;
tokenlist = 0;
token = 0;
}
}
if (cv_playstyle.value == 2)
{
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 (i == MAXPLAYERS)
{
if (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD)
{
INT32 j;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
players[i].playerstate = PST_REBORN;
}
P_LoadThingsOnly();
P_ClearStarPost(player->starpostnum);
// Do a wipe
wipegamestate = -1;
if (camera.chase)
P_ResetCamera(&players[displayplayer], &camera);
if (camera2.chase && splitscreen)
P_ResetCamera(&players[secondarydisplayplayer], &camera2);
// clear cmd building stuff
memset(gamekeydown, 0, sizeof (gamekeydown));
for (j = 0; j < JOYAXISSET; j++)
{
joyxmove[j] = joyymove[j] = 0;
joy2xmove[j] = joy2ymove[j] = 0;
}
mousex = mousey = 0;
mouse2x = mouse2y = 0;
// clear hud messages remains (usually from game startup)
CON_ClearHUD();
// Starpost support
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
G_SpawnPlayer(i, (players[i].starposttime != 0));
}
return;
}
else
RESETMAP;
}
else
RESETMAP;
}
}

View file

@ -2246,7 +2246,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
target->flags |= MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY;
P_SetThingPosition(target);
if (!target->player->bot && !G_IsSpecialStage(gamemap)
if (!target->player->bot && !target->player->spectator && !G_IsSpecialStage(gamemap)
&& G_GametypeUsesLives())
{
target->player->lives -= 1; // Lose a life Tails 03-11-2000

View file

@ -9084,11 +9084,10 @@ void P_SpawnPlayer(INT32 playernum)
// spawn as spectator determination
if (!G_GametypeHasSpectators())
{
// Special case for (NiGHTS) special stages!
// if stage has already started, force players to become spectators until the next stage
if (((multiplayer || netgame) && leveltime > 0)
&& ((G_IsSpecialStage(gamemap) && useNightsSS)
|| (gametype == GT_COOP && cv_playstyle.value == 2 && (p->jointime < 1 || p->spectator))))
if (((multiplayer || netgame) && gametype == GT_COOP && leveltime > 0)
&& ((G_IsSpecialStage(gamemap) && useNightsSS) // late join special stage
|| (cv_playstyle.value == 2 && (p->jointime < 1 || p->spectator)) // late join or die in new coop
|| (p->jointime > 0 && p->lives <= 0))) // game over
p->spectator = true;
else
p->spectator = false;

View file

@ -2181,6 +2181,7 @@ lumpnum_t lastloadedmaplumpnum; // for comparative savegame
static void P_LevelInitStuff(void)
{
INT32 i;
boolean canresetlives = true;
leveltime = 0;
@ -2220,9 +2221,21 @@ static void P_LevelInitStuff(void)
// earthquake camera
memset(&quake,0,sizeof(struct quake));
if ((netgame || multiplayer) && gametype == GT_COOP && cv_playstyle.value == 2)
{
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && players[i].lives > 0)
{
canresetlives = false;
break;
}
}
}
for (i = 0; i < MAXPLAYERS; i++)
{
if ((netgame || multiplayer) && (gametype == GT_COMPETITION || players[i].lives <= 0))
if (canresetlives && (netgame || multiplayer) && playeringame[i] && (gametype == GT_COMPETITION || players[i].lives <= 0))
{
// In Co-Op, replenish a user's lives if they are depleted.
players[i].lives = cv_startinglives.value;

View file

@ -8222,7 +8222,7 @@ static void P_DeathThink(player_t *player)
player->playerstate = PST_REBORN;
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)
P_ConsiderAllGone();
if ((player->deadtimer > 5*TICRATE) || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))
{
@ -8286,7 +8286,7 @@ static void P_DeathThink(player_t *player)
}
}
// In a coop game, and out of lives
else if (gametype == GT_COOP)
/*else if (gametype == GT_COOP)
{
for (i = 0; i < MAXPLAYERS; i++)
{
@ -8294,7 +8294,7 @@ static void P_DeathThink(player_t *player)
continue;
if (players[i].exiting || players[i].lives)
break;
if (players[i].deadtimer < deadtimercheck)
if (players[i].playerstate == PST_DEAD && players[i].deadtimer < deadtimercheck)
deadtimercheck = players[i].deadtimer;
}
@ -8317,7 +8317,13 @@ static void P_DeathThink(player_t *player)
tokenlist = 0;
token = 0;
}
}
}*/
}
if (gametype == GT_COOP && (player->lives <= 0) && (player->deadtimer > gameovertics || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE))))
{
player->spectator = true;
player->playerstate = PST_REBORN;
}
if (gametype == GT_RACE || gametype == GT_COMPETITION || (gametype == GT_COOP && (multiplayer || netgame)))
@ -9427,16 +9433,27 @@ void P_PlayerThink(player_t *player)
// Make sure spectators always have a score and ring count of 0.
if (player->spectator)
{
player->score = 0;
if (gametype != GT_COOP)
player->score = 0;
player->mo->health = 1;
player->rings = 0;
}
if ((netgame || multiplayer) && player->lives <= 0)
else if ((netgame || multiplayer) && player->lives <= 0)
{
// In Co-Op, replenish a user's lives if they are depleted.
// of course, this is just a cheap hack, meh...
player->lives = cv_startinglives.value;
if (gametype == GT_COOP)
{
if (!cv_steallives.value || !P_GetLives(player))
{
player->spectator = true;
player->playerstate = PST_REBORN;
}
}
else
{
// Outside of Co-Op, replenish a user's lives if they are depleted.
// of course, this is just a cheap hack, meh...
player->lives = cv_startinglives.value;
}
}
if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE)