Life theft! No menu item, but anything is possible with zombocom.

cv_steallives, defaults to "On"
This commit is contained in:
toasterbabe 2017-05-28 21:55:41 +01:00
parent f9120e3a44
commit 4239036cec
6 changed files with 130 additions and 5 deletions

View File

@ -354,6 +354,8 @@ consvar_t cv_sharedstarposts = {"sharedstarposts", "On", CV_NETVAR, CV_OnOff, NU
static CV_PossibleValue_t respawntype_cons_t[] = {{0, "Request"}, {1, "Starpost"}, {0, NULL}};
consvar_t cv_respawntype = {"respawntype", "Starpost", CV_NETVAR|CV_CHEAT, respawntype_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_steallives = {"steallives", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t advancemap_cons_t[] = {{0, "Off"}, {1, "Next"}, {2, "Random"}, {0, NULL}};
consvar_t cv_advancemap = {"advancemap", "Next", CV_NETVAR, advancemap_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t playersforexit_cons_t[] = {{0, "One"}, {1, "All"}, {0, NULL}};
@ -505,8 +507,6 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_hidetime);
CV_RegisterVar(&cv_inttime);
CV_RegisterVar(&cv_sharedstarposts);
CV_RegisterVar(&cv_respawntype);
CV_RegisterVar(&cv_advancemap);
CV_RegisterVar(&cv_playersforexit);
CV_RegisterVar(&cv_timelimit);
@ -514,6 +514,10 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_forceskin);
CV_RegisterVar(&cv_downloading);
CV_RegisterVar(&cv_sharedstarposts);
CV_RegisterVar(&cv_respawntype);
CV_RegisterVar(&cv_steallives);
CV_RegisterVar(&cv_specialrings);
CV_RegisterVar(&cv_powerstones);
CV_RegisterVar(&cv_competitionboxes);

View File

@ -89,7 +89,7 @@ extern consvar_t cv_recycler;
extern consvar_t cv_itemfinder;
extern consvar_t cv_inttime, cv_sharedstarposts, cv_respawntype, cv_advancemap, cv_playersforexit;
extern consvar_t cv_inttime, cv_sharedstarposts, cv_respawntype, cv_steallives, cv_advancemap, cv_playersforexit;
extern consvar_t cv_overtime;
extern consvar_t cv_startinglives;

View File

@ -1309,7 +1309,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
players[i].starpostangle = special->angle;
players[i].starpostnum = special->health;
if (cv_respawntype.value == 1 && players[i].lives > 0 && players[i].playerstate == PST_DEAD)
if (cv_respawntype.value == 1 && (P_GetLives(&players[i]) || players[i].lives > 0) && players[i].playerstate == PST_DEAD)
players[i].playerstate = PST_REBORN;
}
}

View File

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

View File

@ -8098,6 +8098,51 @@ void P_FindEmerald(void)
return;
}
//
// P_GetLives
// Steal lives if you're allowed to.
//
boolean P_GetLives(player_t *player)
{
INT32 i, maxlivesplayer = -1, livescheck = 1;
if (!(cv_steallives.value
&& (gametype == GT_COOP)
&& (netgame || multiplayer)))
return true;
if (player->lives > 0)
return true;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
if (players[i].spectator) // Ignore spectators
continue;
if (players[i].lives > livescheck)
{
maxlivesplayer = i;
livescheck = players[i].lives;
}
}
if (maxlivesplayer != -1)
{
if (players[maxlivesplayer].mo)
S_StartSound(players[maxlivesplayer].mo, sfx_jshard); // placeholder
P_GivePlayerLives(&players[maxlivesplayer], -1);
P_GivePlayerLives(player, 1);
if (netgame && P_IsLocalPlayer(player))
S_ChangeMusic(mapmusname, mapmusflags, true);
else if (player == &players[displayplayer] || player == &players[secondarydisplayplayer])
P_RestoreMusic(player);
return true;
}
return false;
}
//
// P_DeathThink
// Fall on your face when dying.
@ -8106,6 +8151,8 @@ void P_FindEmerald(void)
static void P_DeathThink(player_t *player)
{
INT32 j = MAXPLAYERS;
ticcmd_t *cmd = &player->cmd;
player->deltaviewheight = 0;
@ -8121,10 +8168,31 @@ static void P_DeathThink(player_t *player)
G_UseContinue(); // Even if we don't have one this handles ending the game
}
if (cv_steallives.value
&& (gametype == GT_COOP)
&& (netgame || multiplayer)
&& (player->lives <= 0))
{
for (j = 0; 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;
}
}
// Force respawn if idle for more than 30 seconds in shooter modes.
if (player->deadtimer > 30*TICRATE && !G_PlatformGametype())
player->playerstate = PST_REBORN;
else if (player->lives > 0 && !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_respawntype.value == 1) // Shamelessly lifted from TD. Thanks, Sryder!
{
@ -8162,6 +8230,9 @@ static void P_DeathThink(player_t *player)
player->playerstate = PST_REBORN;
else switch(gametype) {
case GT_COOP:
if (player->deadtimer > TICRATE && P_GetLives(player))
player->playerstate = PST_REBORN;
break;
case GT_COMPETITION:
if (player->deadtimer > TICRATE)
player->playerstate = PST_REBORN;

View File

@ -731,6 +731,31 @@ static void ST_drawLives(void)
// lives
V_DrawRightAlignedString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0),
V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANS|v_splitflag, va("%d",stplyr->lives));
if (cv_steallives.value
&& (gametype == GT_COOP)
&& (netgame || multiplayer))
{
INT32 i, sum = 0;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
if (players[i].spectator) // Ignore spectators
continue;
if (&players[i] == stplyr)
continue;
if (players[i].lives < 2)
continue;
sum += (players[i].lives - 1);
}
V_DrawString(hudinfo[HUD_LIVESNUM].x, hudinfo[HUD_LIVESNUM].y + (v_splitflag ? -4 : 0),
V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_HUDTRANSHALF|v_splitflag, va("/%d",sum));
}
}
static void ST_drawLevelTitle(void)
@ -1826,6 +1851,30 @@ static void ST_overlayDrawer(void)
p = sboover;
V_DrawScaledPatch((BASEVIDWIDTH - SHORT(p->width))/2, STRINGY(BASEVIDHEIGHT/2 - (SHORT(p->height)/2)), 0, p);
if (cv_steallives.value
&& (gametype == GT_COOP)
&& (netgame || multiplayer))
{
INT32 i;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i])
continue;
if (players[i].spectator) // Ignore spectators
continue;
if (&players[i] == stplyr)
continue;
if (players[i].lives > 1)
break;
}
if (i != MAXPLAYERS)
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(BASEVIDHEIGHT/2 + (SHORT(p->height)/2)) + 15, 0, M_GetText("You'll steal a life on respawn."));
}
}