Merge branch 'next' of https://git.magicalgirl.moe/STJr/SRB2 into playerthink-hook
This commit is contained in:
commit
dc51ba6b64
|
@ -1293,7 +1293,8 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
||||||
|
|
||||||
netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers();
|
netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers();
|
||||||
netbuffer->u.serverinfo.maxplayer = (UINT8)cv_maxplayers.value;
|
netbuffer->u.serverinfo.maxplayer = (UINT8)cv_maxplayers.value;
|
||||||
netbuffer->u.serverinfo.gametype = (UINT8)gametype;
|
strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[gametype],
|
||||||
|
sizeof netbuffer->u.serverinfo.gametypename);
|
||||||
netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame;
|
netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame;
|
||||||
netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled();
|
netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled();
|
||||||
netbuffer->u.serverinfo.isdedicated = (UINT8)dedicated;
|
netbuffer->u.serverinfo.isdedicated = (UINT8)dedicated;
|
||||||
|
@ -2122,12 +2123,9 @@ static void CL_ConnectToServer(boolean viams)
|
||||||
|
|
||||||
if (i != -1)
|
if (i != -1)
|
||||||
{
|
{
|
||||||
UINT16 num = serverlist[i].info.gametype;
|
char *gametypestr = serverlist[i].info.gametypename;
|
||||||
const char *gametypestr = NULL;
|
|
||||||
CONS_Printf(M_GetText("Connecting to: %s\n"), serverlist[i].info.servername);
|
CONS_Printf(M_GetText("Connecting to: %s\n"), serverlist[i].info.servername);
|
||||||
if (num < gametypecount)
|
gametypestr[sizeof serverlist[i].info.gametypename - 1] = '\0';
|
||||||
gametypestr = Gametype_Names[num];
|
|
||||||
if (gametypestr)
|
|
||||||
CONS_Printf(M_GetText("Gametype: %s\n"), gametypestr);
|
CONS_Printf(M_GetText("Gametype: %s\n"), gametypestr);
|
||||||
CONS_Printf(M_GetText("Version: %d.%d.%u\n"), serverlist[i].info.version/100,
|
CONS_Printf(M_GetText("Version: %d.%d.%u\n"), serverlist[i].info.version/100,
|
||||||
serverlist[i].info.version%100, serverlist[i].info.subversion);
|
serverlist[i].info.version%100, serverlist[i].info.subversion);
|
||||||
|
@ -3656,6 +3654,8 @@ static void HandleServerInfo(SINT8 node)
|
||||||
netbuffer->u.serverinfo.servername[MAXSERVERNAME-1] = 0;
|
netbuffer->u.serverinfo.servername[MAXSERVERNAME-1] = 0;
|
||||||
netbuffer->u.serverinfo.application
|
netbuffer->u.serverinfo.application
|
||||||
[sizeof netbuffer->u.serverinfo.application - 1] = '\0';
|
[sizeof netbuffer->u.serverinfo.application - 1] = '\0';
|
||||||
|
netbuffer->u.serverinfo.gametypename
|
||||||
|
[sizeof netbuffer->u.serverinfo.gametypename - 1] = '\0';
|
||||||
|
|
||||||
SL_InsertServer(&netbuffer->u.serverinfo, node);
|
SL_InsertServer(&netbuffer->u.serverinfo, node);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ This version is independent of the mod name, and standard
|
||||||
version and subversion. It should only account for the
|
version and subversion. It should only account for the
|
||||||
basic fields of the packet, and change infrequently.
|
basic fields of the packet, and change infrequently.
|
||||||
*/
|
*/
|
||||||
#define PACKETVERSION 0
|
#define PACKETVERSION 1
|
||||||
|
|
||||||
// Network play related stuff.
|
// Network play related stuff.
|
||||||
// There is a data struct that stores network
|
// There is a data struct that stores network
|
||||||
|
@ -361,7 +361,7 @@ typedef struct
|
||||||
UINT8 subversion;
|
UINT8 subversion;
|
||||||
UINT8 numberofplayer;
|
UINT8 numberofplayer;
|
||||||
UINT8 maxplayer;
|
UINT8 maxplayer;
|
||||||
UINT8 gametype;
|
char gametypename[24];
|
||||||
UINT8 modifiedgame;
|
UINT8 modifiedgame;
|
||||||
UINT8 cheatsenabled;
|
UINT8 cheatsenabled;
|
||||||
UINT8 isdedicated;
|
UINT8 isdedicated;
|
||||||
|
|
|
@ -766,7 +766,7 @@ void D_StartTitle(void)
|
||||||
|
|
||||||
if (netgame)
|
if (netgame)
|
||||||
{
|
{
|
||||||
if (gametype == GT_COOP)
|
if (gametyperules & GTR_CAMPAIGN)
|
||||||
{
|
{
|
||||||
G_SetGamestate(GS_WAITINGPLAYERS); // hack to prevent a command repeat
|
G_SetGamestate(GS_WAITINGPLAYERS); // hack to prevent a command repeat
|
||||||
|
|
||||||
|
|
|
@ -3747,7 +3747,7 @@ static void CoopStarposts_OnChange(void)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
|
||||||
if (!(netgame || multiplayer) || gametype != GT_COOP)
|
if (!(netgame || multiplayer) || !G_GametypeUsesCoopStarposts())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (cv_coopstarposts.value)
|
switch (cv_coopstarposts.value)
|
||||||
|
@ -3802,7 +3802,7 @@ static void CoopLives_OnChange(void)
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
|
|
||||||
if (!(netgame || multiplayer) || gametype != GT_COOP)
|
if (!(netgame || multiplayer) || !G_GametypeUsesCoopLives())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (cv_cooplives.value)
|
switch (cv_cooplives.value)
|
||||||
|
|
|
@ -8904,32 +8904,35 @@ static const char *const GAMETYPERULE_LIST[] = {
|
||||||
"CAMPAIGN",
|
"CAMPAIGN",
|
||||||
"RINGSLINGER",
|
"RINGSLINGER",
|
||||||
"SPECTATORS",
|
"SPECTATORS",
|
||||||
"FRIENDLYFIRE",
|
|
||||||
"LIVES",
|
"LIVES",
|
||||||
"TEAMS",
|
"TEAMS",
|
||||||
|
"FIRSTPERSON",
|
||||||
|
"POWERSTONES",
|
||||||
|
"TEAMFLAGS",
|
||||||
|
"FRIENDLY",
|
||||||
|
"SPECIALSTAGES",
|
||||||
|
"EMERALDTOKENS",
|
||||||
|
"EMERALDHUNT",
|
||||||
"RACE",
|
"RACE",
|
||||||
"TAG",
|
"TAG",
|
||||||
"POINTLIMIT",
|
"POINTLIMIT",
|
||||||
"TIMELIMIT",
|
"TIMELIMIT",
|
||||||
"HIDETIME",
|
"OVERTIME",
|
||||||
|
"HURTMESSAGES",
|
||||||
|
"FRIENDLYFIRE",
|
||||||
|
"STARTCOUNTDOWN",
|
||||||
"HIDEFROZEN",
|
"HIDEFROZEN",
|
||||||
"BLINDFOLDED",
|
"BLINDFOLDED",
|
||||||
"FIRSTPERSON",
|
"RESPAWNDELAY",
|
||||||
"MATCHEMERALDS",
|
|
||||||
"TEAMFLAGS",
|
|
||||||
"PITYSHIELD",
|
"PITYSHIELD",
|
||||||
"DEATHPENALTY",
|
"DEATHPENALTY",
|
||||||
"NOSPECTATORSPAWN",
|
"NOSPECTATORSPAWN",
|
||||||
"DEATHMATCHSTARTS",
|
"DEATHMATCHSTARTS",
|
||||||
"SPECIALSTAGES",
|
"SPAWNINVUL",
|
||||||
"EMERALDTOKENS",
|
|
||||||
"EMERALDHUNT",
|
|
||||||
"SPAWNENEMIES",
|
"SPAWNENEMIES",
|
||||||
"ALLOWEXIT",
|
"ALLOWEXIT",
|
||||||
"NOTITLECARD",
|
"NOTITLECARD",
|
||||||
"OVERTIME",
|
"CUTSCENES",
|
||||||
"HURTMESSAGES",
|
|
||||||
"SPAWNINVUL",
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -397,32 +397,35 @@ enum GameTypeRules
|
||||||
GTR_CAMPAIGN = 1, // Linear Co-op map progression, don't allow random maps
|
GTR_CAMPAIGN = 1, // Linear Co-op map progression, don't allow random maps
|
||||||
GTR_RINGSLINGER = 1<<1, // Outside of Co-op, Competition, and Race (overriden by cv_ringslinger)
|
GTR_RINGSLINGER = 1<<1, // Outside of Co-op, Competition, and Race (overriden by cv_ringslinger)
|
||||||
GTR_SPECTATORS = 1<<2, // Outside of Co-op, Competition, and Race
|
GTR_SPECTATORS = 1<<2, // Outside of Co-op, Competition, and Race
|
||||||
GTR_FRIENDLYFIRE = 1<<3, // Always allow friendly fire
|
GTR_LIVES = 1<<3, // Co-op and Competition
|
||||||
GTR_LIVES = 1<<4, // Co-op and Competition
|
GTR_TEAMS = 1<<4, // Team Match, CTF
|
||||||
GTR_TEAMS = 1<<5, // Team Match, CTF
|
GTR_FIRSTPERSON = 1<<5, // First person camera
|
||||||
GTR_RACE = 1<<6, // Race and Competition
|
GTR_POWERSTONES = 1<<6, // Power stones (Match and CTF)
|
||||||
GTR_TAG = 1<<7, // Tag and Hide and Seek
|
GTR_TEAMFLAGS = 1<<7, // Gametype has team flags (CTF)
|
||||||
GTR_POINTLIMIT = 1<<8, // Ringslinger point limit
|
GTR_FRIENDLY = 1<<8, // Co-op
|
||||||
GTR_TIMELIMIT = 1<<9, // Ringslinger time limit
|
GTR_SPECIALSTAGES = 1<<9, // Allow special stages
|
||||||
GTR_HIDETIME = 1<<10, // Hide time (Tag and Hide and Seek)
|
GTR_EMERALDTOKENS = 1<<10, // Spawn emerald tokens
|
||||||
GTR_HIDEFROZEN = 1<<11, // Frozen after hide time (Hide and Seek, but not Tag)
|
GTR_EMERALDHUNT = 1<<11, // Emerald Hunt
|
||||||
GTR_BLINDFOLDED = 1<<12, // Blindfolded view (Tag and Hide and Seek)
|
GTR_RACE = 1<<12, // Race and Competition
|
||||||
GTR_FIRSTPERSON = 1<<13, // First person camera
|
GTR_TAG = 1<<13, // Tag and Hide and Seek
|
||||||
GTR_MATCHEMERALDS = 1<<14, // Ringslinger emeralds (Match and CTF)
|
GTR_POINTLIMIT = 1<<14, // Ringslinger point limit
|
||||||
GTR_TEAMFLAGS = 1<<15, // Gametype has team flags (CTF)
|
GTR_TIMELIMIT = 1<<15, // Ringslinger time limit
|
||||||
GTR_PITYSHIELD = 1<<16, // Award pity shield
|
GTR_OVERTIME = 1<<16, // Allow overtime
|
||||||
GTR_DEATHPENALTY = 1<<17, // Death score penalty
|
GTR_HURTMESSAGES = 1<<17, // Hit and death messages
|
||||||
GTR_NOSPECTATORSPAWN = 1<<18, // Use with GTR_SPECTATORS, spawn in the map instead of with the spectators
|
GTR_FRIENDLYFIRE = 1<<18, // Always allow friendly fire
|
||||||
GTR_DEATHMATCHSTARTS = 1<<19, // Use deathmatch starts
|
GTR_STARTCOUNTDOWN = 1<<19, // Hide time countdown (Tag and Hide and Seek)
|
||||||
GTR_SPECIALSTAGES = 1<<20, // Allow special stages
|
GTR_HIDEFROZEN = 1<<20, // Frozen after hide time (Hide and Seek, but not Tag)
|
||||||
GTR_EMERALDTOKENS = 1<<21, // Spawn emerald tokens
|
GTR_BLINDFOLDED = 1<<21, // Blindfolded view (Tag and Hide and Seek)
|
||||||
GTR_EMERALDHUNT = 1<<22, // Emerald Hunt
|
GTR_RESPAWNDELAY = 1<<22, // Respawn delay
|
||||||
GTR_SPAWNENEMIES = 1<<23, // Spawn enemies
|
GTR_PITYSHIELD = 1<<23, // Award pity shield
|
||||||
GTR_ALLOWEXIT = 1<<24, // Allow exit sectors
|
GTR_DEATHPENALTY = 1<<24, // Death score penalty
|
||||||
GTR_NOTITLECARD = 1<<25, // Don't show the title card
|
GTR_NOSPECTATORSPAWN = 1<<25, // Use with GTR_SPECTATORS, spawn in the map instead of with the spectators
|
||||||
GTR_OVERTIME = 1<<26, // Allow overtime
|
GTR_DEATHMATCHSTARTS = 1<<26, // Use deathmatch starts
|
||||||
GTR_HURTMESSAGES = 1<<27, // Hit and death messages
|
GTR_SPAWNINVUL = 1<<27, // Babysitting deterrent
|
||||||
GTR_SPAWNINVUL = 1<<28, // Babysitting deterrent
|
GTR_SPAWNENEMIES = 1<<28, // Spawn enemies
|
||||||
|
GTR_ALLOWEXIT = 1<<29, // Allow exit sectors
|
||||||
|
GTR_NOTITLECARD = 1<<30, // Don't show the title card
|
||||||
|
GTR_CUTSCENES = 1<<31, // Play cutscenes, ending, credits, and evaluation
|
||||||
};
|
};
|
||||||
|
|
||||||
// String names for gametypes
|
// String names for gametypes
|
||||||
|
|
163
src/g_game.c
163
src/g_game.c
|
@ -2689,8 +2689,7 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost)
|
||||||
|
|
||||||
// -- DM/Tag/CTF-spectator/etc --
|
// -- DM/Tag/CTF-spectator/etc --
|
||||||
// Order: DM->CTF->Coop
|
// Order: DM->CTF->Coop
|
||||||
else if ((gametyperules & GTR_DEATHMATCHSTARTS) || gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF
|
else if ((gametyperules & GTR_DEATHMATCHSTARTS) && !(players[playernum].pflags & PF_TAGIT))
|
||||||
|| ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && !(players[playernum].pflags & PF_TAGIT)))
|
|
||||||
{
|
{
|
||||||
if (!(spawnpoint = G_FindMatchStart(playernum)) // find a DM start
|
if (!(spawnpoint = G_FindMatchStart(playernum)) // find a DM start
|
||||||
&& !(spawnpoint = G_FindCTFStart(playernum))) // find a CTF start
|
&& !(spawnpoint = G_FindCTFStart(playernum))) // find a CTF start
|
||||||
|
@ -2891,11 +2890,11 @@ void G_DoReborn(INT32 playernum)
|
||||||
|
|
||||||
if (countdowntimeup || (!(netgame || multiplayer) && gametype == GT_COOP))
|
if (countdowntimeup || (!(netgame || multiplayer) && gametype == GT_COOP))
|
||||||
resetlevel = true;
|
resetlevel = true;
|
||||||
else if (gametype == GT_COOP && (netgame || multiplayer) && !G_IsSpecialStage(gamemap))
|
else if ((G_GametypeUsesCoopLives() || G_GametypeUsesCoopStarposts()) && (netgame || multiplayer) && !G_IsSpecialStage(gamemap))
|
||||||
{
|
{
|
||||||
boolean notgameover = true;
|
boolean notgameover = true;
|
||||||
|
|
||||||
if (cv_cooplives.value != 0 && player->lives <= 0) // consider game over first
|
if (G_GametypeUsesCoopLives() && (cv_cooplives.value != 0 && player->lives <= 0)) // consider game over first
|
||||||
{
|
{
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
|
@ -2930,7 +2929,7 @@ void G_DoReborn(INT32 playernum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notgameover && cv_coopstarposts.value == 2)
|
if (G_GametypeUsesCoopStarposts() && (notgameover && cv_coopstarposts.value == 2))
|
||||||
{
|
{
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
|
@ -3006,7 +3005,7 @@ void G_DoReborn(INT32 playernum)
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore time in netgame (see also p_setup.c)
|
// restore time in netgame (see also p_setup.c)
|
||||||
if ((netgame || multiplayer) && gametype == GT_COOP && cv_coopstarposts.value == 2)
|
if ((netgame || multiplayer) && G_GametypeUsesCoopStarposts() && cv_coopstarposts.value == 2)
|
||||||
{
|
{
|
||||||
// is this a hack? maybe
|
// is this a hack? maybe
|
||||||
tic_t maxstarposttime = 0;
|
tic_t maxstarposttime = 0;
|
||||||
|
@ -3077,7 +3076,7 @@ void G_AddPlayer(INT32 playernum)
|
||||||
if (!players[i].exiting)
|
if (!players[i].exiting)
|
||||||
notexiting++;
|
notexiting++;
|
||||||
|
|
||||||
if (!(cv_coopstarposts.value && (gametype == GT_COOP) && (p->starpostnum < players[i].starpostnum)))
|
if (!(cv_coopstarposts.value && G_GametypeUsesCoopStarposts() && (p->starpostnum < players[i].starpostnum)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
p->starpostscale = players[i].starpostscale;
|
p->starpostscale = players[i].starpostscale;
|
||||||
|
@ -3194,24 +3193,24 @@ const char *Gametype_ConstantNames[NUMGAMETYPES] =
|
||||||
UINT32 gametypedefaultrules[NUMGAMETYPES] =
|
UINT32 gametypedefaultrules[NUMGAMETYPES] =
|
||||||
{
|
{
|
||||||
// Co-op
|
// Co-op
|
||||||
GTR_CAMPAIGN|GTR_LIVES|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDHUNT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES,
|
GTR_CAMPAIGN|GTR_LIVES|GTR_FRIENDLY|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDHUNT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES|GTR_CUTSCENES,
|
||||||
// Competition
|
// Competition
|
||||||
GTR_RACE|GTR_LIVES|GTR_SPAWNENEMIES|GTR_EMERALDTOKENS|GTR_SPAWNINVUL|GTR_ALLOWEXIT,
|
GTR_RACE|GTR_LIVES|GTR_SPAWNENEMIES|GTR_EMERALDTOKENS|GTR_SPAWNINVUL|GTR_ALLOWEXIT,
|
||||||
// Race
|
// Race
|
||||||
GTR_RACE|GTR_SPAWNENEMIES|GTR_SPAWNINVUL|GTR_ALLOWEXIT,
|
GTR_RACE|GTR_SPAWNENEMIES|GTR_SPAWNINVUL|GTR_ALLOWEXIT,
|
||||||
|
|
||||||
// Match
|
// Match
|
||||||
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_SPAWNINVUL|GTR_PITYSHIELD|GTR_DEATHPENALTY,
|
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_POWERSTONES|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD|GTR_DEATHPENALTY,
|
||||||
// Team Match
|
// Team Match
|
||||||
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_SPAWNINVUL|GTR_PITYSHIELD,
|
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD,
|
||||||
|
|
||||||
// Tag
|
// Tag
|
||||||
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_SPAWNINVUL,
|
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_STARTCOUNTDOWN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY,
|
||||||
// Hide and Seek
|
// Hide and Seek
|
||||||
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_SPAWNINVUL,
|
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_STARTCOUNTDOWN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY,
|
||||||
|
|
||||||
// CTF
|
// CTF
|
||||||
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_SPAWNINVUL|GTR_PITYSHIELD,
|
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_POWERSTONES|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD,
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -3252,50 +3251,68 @@ INT16 G_AddGametype(UINT32 rules)
|
||||||
//
|
//
|
||||||
void G_AddGametypeConstant(INT16 gtype, const char *newgtconst)
|
void G_AddGametypeConstant(INT16 gtype, const char *newgtconst)
|
||||||
{
|
{
|
||||||
char *gtconst = Z_Malloc(strlen(newgtconst) + 3, PU_STATIC, NULL);
|
size_t r = 0; // read
|
||||||
// Copy GT_ and the gametype name.
|
size_t w = 0; // write
|
||||||
strcpy(gtconst, "GT_");
|
char *gtconst = Z_Calloc(strlen(newgtconst) + 3, PU_STATIC, NULL);
|
||||||
strcat(gtconst, newgtconst);
|
char *tmpconst = Z_Calloc(strlen(newgtconst), PU_STATIC, NULL);
|
||||||
|
|
||||||
|
// Copy the gametype name.
|
||||||
|
strcpy(tmpconst, newgtconst);
|
||||||
|
|
||||||
// Make uppercase.
|
// Make uppercase.
|
||||||
strupr(gtconst);
|
strupr(tmpconst);
|
||||||
// Remove characters.
|
|
||||||
#define REMOVECHAR(chr) \
|
// Prepare to write the new constant string now.
|
||||||
{ \
|
strcpy(gtconst, "GT_");
|
||||||
char *chrfind = strchr(gtconst, chr); \
|
|
||||||
while (chrfind) \
|
// Remove characters that will not be allowed in the constant string.
|
||||||
{ \
|
for (; r < strlen(tmpconst); r++)
|
||||||
*chrfind = '_'; \
|
{
|
||||||
chrfind = strchr(chrfind, chr); \
|
boolean writechar = true;
|
||||||
} \
|
char rc = tmpconst[r];
|
||||||
|
switch (rc)
|
||||||
|
{
|
||||||
|
// Space, at sign and question mark
|
||||||
|
case ' ':
|
||||||
|
case '@':
|
||||||
|
case '?':
|
||||||
|
// Used for operations
|
||||||
|
case '+':
|
||||||
|
case '-':
|
||||||
|
case '*':
|
||||||
|
case '/':
|
||||||
|
case '%':
|
||||||
|
case '^':
|
||||||
|
case '&':
|
||||||
|
case '!':
|
||||||
|
// Part of Lua's syntax
|
||||||
|
case '#':
|
||||||
|
case '=':
|
||||||
|
case '~':
|
||||||
|
case '<':
|
||||||
|
case '>':
|
||||||
|
case '(':
|
||||||
|
case ')':
|
||||||
|
case '{':
|
||||||
|
case '}':
|
||||||
|
case '[':
|
||||||
|
case ']':
|
||||||
|
case ':':
|
||||||
|
case ';':
|
||||||
|
case ',':
|
||||||
|
case '.':
|
||||||
|
writechar = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (writechar)
|
||||||
|
{
|
||||||
|
gtconst[3 + w] = rc;
|
||||||
|
w++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Space
|
// Free the temporary string.
|
||||||
REMOVECHAR(' ')
|
Z_Free(tmpconst);
|
||||||
// Used for operations
|
|
||||||
REMOVECHAR('+')
|
|
||||||
REMOVECHAR('-')
|
|
||||||
REMOVECHAR('*')
|
|
||||||
REMOVECHAR('/')
|
|
||||||
REMOVECHAR('%')
|
|
||||||
REMOVECHAR('^')
|
|
||||||
// Part of Lua's syntax
|
|
||||||
REMOVECHAR('#')
|
|
||||||
REMOVECHAR('=')
|
|
||||||
REMOVECHAR('~')
|
|
||||||
REMOVECHAR('<')
|
|
||||||
REMOVECHAR('>')
|
|
||||||
REMOVECHAR('(')
|
|
||||||
REMOVECHAR(')')
|
|
||||||
REMOVECHAR('{')
|
|
||||||
REMOVECHAR('}')
|
|
||||||
REMOVECHAR('[')
|
|
||||||
REMOVECHAR(']')
|
|
||||||
REMOVECHAR(':')
|
|
||||||
REMOVECHAR(';')
|
|
||||||
REMOVECHAR(',')
|
|
||||||
REMOVECHAR('.')
|
|
||||||
|
|
||||||
#undef REMOVECHAR
|
|
||||||
|
|
||||||
// Finally, set the constant string.
|
// Finally, set the constant string.
|
||||||
Gametype_ConstantNames[gtype] = gtconst;
|
Gametype_ConstantNames[gtype] = gtconst;
|
||||||
|
@ -3440,6 +3457,28 @@ boolean G_GametypeUsesLives(void)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// G_GametypeUsesCoopLives
|
||||||
|
//
|
||||||
|
// Returns true if the current gametype uses
|
||||||
|
// the cooplives CVAR. False otherwise.
|
||||||
|
//
|
||||||
|
boolean G_GametypeUsesCoopLives(void)
|
||||||
|
{
|
||||||
|
return (gametyperules & (GTR_LIVES|GTR_FRIENDLY)) == (GTR_LIVES|GTR_FRIENDLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// G_GametypeUsesCoopStarposts
|
||||||
|
//
|
||||||
|
// Returns true if the current gametype uses
|
||||||
|
// the coopstarposts CVAR. False otherwise.
|
||||||
|
//
|
||||||
|
boolean G_GametypeUsesCoopStarposts(void)
|
||||||
|
{
|
||||||
|
return (gametyperules & GTR_FRIENDLY);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// G_GametypeHasTeams
|
// G_GametypeHasTeams
|
||||||
//
|
//
|
||||||
|
@ -3493,6 +3532,16 @@ boolean G_TagGametype(void)
|
||||||
return (gametyperules & GTR_TAG);
|
return (gametyperules & GTR_TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// G_CompetitionGametype
|
||||||
|
//
|
||||||
|
// For gametypes that are race gametypes, and have lives.
|
||||||
|
//
|
||||||
|
boolean G_CompetitionGametype(void)
|
||||||
|
{
|
||||||
|
return ((gametyperules & GTR_RACE) && (gametyperules & GTR_LIVES));
|
||||||
|
}
|
||||||
|
|
||||||
/** Get the typeoflevel flag needed to indicate support of a gametype.
|
/** Get the typeoflevel flag needed to indicate support of a gametype.
|
||||||
* In single-player, this always returns TOL_SP.
|
* In single-player, this always returns TOL_SP.
|
||||||
* \param gametype The gametype for which support is desired.
|
* \param gametype The gametype for which support is desired.
|
||||||
|
@ -3734,7 +3783,7 @@ void G_AfterIntermission(void)
|
||||||
|
|
||||||
HU_ClearCEcho();
|
HU_ClearCEcho();
|
||||||
|
|
||||||
if (mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking && skipstats <= 1) // Start a custom cutscene.
|
if ((gametyperules & GTR_CUTSCENES) && mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking && skipstats <= 1) // Start a custom cutscene.
|
||||||
F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false);
|
F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3844,7 +3893,7 @@ static void G_DoContinued(void)
|
||||||
void G_EndGame(void)
|
void G_EndGame(void)
|
||||||
{
|
{
|
||||||
// Only do evaluation and credits in coop games.
|
// Only do evaluation and credits in coop games.
|
||||||
if (gametype == GT_COOP)
|
if (gametyperules & GTR_CUTSCENES)
|
||||||
{
|
{
|
||||||
if (nextmap == 1103-1) // end game with ending
|
if (nextmap == 1103-1) // end game with ending
|
||||||
{
|
{
|
||||||
|
@ -4547,7 +4596,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
|
||||||
automapactive = false;
|
automapactive = false;
|
||||||
imcontinuing = false;
|
imcontinuing = false;
|
||||||
|
|
||||||
if (!skipprecutscene && mapheaderinfo[gamemap-1]->precutscenenum && !modeattacking) // Start a custom cutscene.
|
if ((gametyperules & GTR_CUTSCENES) && !skipprecutscene && mapheaderinfo[gamemap-1]->precutscenenum && !modeattacking) // Start a custom cutscene.
|
||||||
F_StartCustomCutscene(mapheaderinfo[gamemap-1]->precutscenenum-1, true, resetplayer);
|
F_StartCustomCutscene(mapheaderinfo[gamemap-1]->precutscenenum-1, true, resetplayer);
|
||||||
else
|
else
|
||||||
G_DoLoadLevel(resetplayer);
|
G_DoLoadLevel(resetplayer);
|
||||||
|
|
|
@ -218,11 +218,14 @@ void G_SetGametypeDescription(INT16 gtype, char *descriptiontext, UINT8 leftcolo
|
||||||
INT32 G_GetGametypeByName(const char *gametypestr);
|
INT32 G_GetGametypeByName(const char *gametypestr);
|
||||||
boolean G_IsSpecialStage(INT32 mapnum);
|
boolean G_IsSpecialStage(INT32 mapnum);
|
||||||
boolean G_GametypeUsesLives(void);
|
boolean G_GametypeUsesLives(void);
|
||||||
|
boolean G_GametypeUsesCoopLives(void);
|
||||||
|
boolean G_GametypeUsesCoopStarposts(void);
|
||||||
boolean G_GametypeHasTeams(void);
|
boolean G_GametypeHasTeams(void);
|
||||||
boolean G_GametypeHasSpectators(void);
|
boolean G_GametypeHasSpectators(void);
|
||||||
boolean G_RingSlingerGametype(void);
|
boolean G_RingSlingerGametype(void);
|
||||||
boolean G_PlatformGametype(void);
|
boolean G_PlatformGametype(void);
|
||||||
boolean G_TagGametype(void);
|
boolean G_TagGametype(void);
|
||||||
|
boolean G_CompetitionGametype(void);
|
||||||
boolean G_EnoughPlayersFinished(void);
|
boolean G_EnoughPlayersFinished(void);
|
||||||
void G_ExitLevel(void);
|
void G_ExitLevel(void);
|
||||||
void G_NextLevel(void);
|
void G_NextLevel(void);
|
||||||
|
|
|
@ -2437,7 +2437,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (G_GametypeUsesLives() && !(gametyperankings[gametype] == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives
|
if (G_GametypeUsesLives() && !(G_GametypeUsesCoopLives() && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives
|
||||||
V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|(greycheck ? V_60TRANS : 0), va("%dx", players[tab[i].num].lives));
|
V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|(greycheck ? V_60TRANS : 0), va("%dx", players[tab[i].num].lives));
|
||||||
else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT)
|
else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT)
|
||||||
{
|
{
|
||||||
|
@ -2746,7 +2746,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
|
||||||
| (greycheck ? V_TRANSLUCENT : 0)
|
| (greycheck ? V_TRANSLUCENT : 0)
|
||||||
| V_ALLOWLOWERCASE, name);
|
| V_ALLOWLOWERCASE, name);
|
||||||
|
|
||||||
if (G_GametypeUsesLives() && !(gametyperankings[gametype] == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives
|
if (G_GametypeUsesLives() && !(G_GametypeUsesCoopLives() && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives
|
||||||
V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE, va("%dx", players[tab[i].num].lives));
|
V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE, va("%dx", players[tab[i].num].lives));
|
||||||
else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT)
|
else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT)
|
||||||
V_DrawSmallScaledPatch(x-28, y-4, 0, tagico);
|
V_DrawSmallScaledPatch(x-28, y-4, 0, tagico);
|
||||||
|
|
|
@ -2854,6 +2854,22 @@ static int lib_gGametypeUsesLives(lua_State *L)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int lib_gGametypeUsesCoopLives(lua_State *L)
|
||||||
|
{
|
||||||
|
//HUDSAFE
|
||||||
|
INLEVEL
|
||||||
|
lua_pushboolean(L, G_GametypeUsesCoopLives());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lib_gGametypeUsesCoopStarposts(lua_State *L)
|
||||||
|
{
|
||||||
|
//HUDSAFE
|
||||||
|
INLEVEL
|
||||||
|
lua_pushboolean(L, G_GametypeUsesCoopStarposts());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int lib_gGametypeHasTeams(lua_State *L)
|
static int lib_gGametypeHasTeams(lua_State *L)
|
||||||
{
|
{
|
||||||
//HUDSAFE
|
//HUDSAFE
|
||||||
|
@ -2894,6 +2910,14 @@ static int lib_gTagGametype(lua_State *L)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int lib_gCompetitionGametype(lua_State *L)
|
||||||
|
{
|
||||||
|
//HUDSAFE
|
||||||
|
INLEVEL
|
||||||
|
lua_pushboolean(L, G_CompetitionGametype());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int lib_gTicsToHours(lua_State *L)
|
static int lib_gTicsToHours(lua_State *L)
|
||||||
{
|
{
|
||||||
tic_t rtic = luaL_checkinteger(L, 1);
|
tic_t rtic = luaL_checkinteger(L, 1);
|
||||||
|
@ -3139,11 +3163,14 @@ static luaL_Reg lib[] = {
|
||||||
{"G_ExitLevel",lib_gExitLevel},
|
{"G_ExitLevel",lib_gExitLevel},
|
||||||
{"G_IsSpecialStage",lib_gIsSpecialStage},
|
{"G_IsSpecialStage",lib_gIsSpecialStage},
|
||||||
{"G_GametypeUsesLives",lib_gGametypeUsesLives},
|
{"G_GametypeUsesLives",lib_gGametypeUsesLives},
|
||||||
|
{"G_GametypeUsesCoopLives",lib_gGametypeUsesCoopLives},
|
||||||
|
{"G_GametypeUsesCoopStarposts",lib_gGametypeUsesCoopStarposts},
|
||||||
{"G_GametypeHasTeams",lib_gGametypeHasTeams},
|
{"G_GametypeHasTeams",lib_gGametypeHasTeams},
|
||||||
{"G_GametypeHasSpectators",lib_gGametypeHasSpectators},
|
{"G_GametypeHasSpectators",lib_gGametypeHasSpectators},
|
||||||
{"G_RingSlingerGametype",lib_gRingSlingerGametype},
|
{"G_RingSlingerGametype",lib_gRingSlingerGametype},
|
||||||
{"G_PlatformGametype",lib_gPlatformGametype},
|
{"G_PlatformGametype",lib_gPlatformGametype},
|
||||||
{"G_TagGametype",lib_gTagGametype},
|
{"G_TagGametype",lib_gTagGametype},
|
||||||
|
{"G_CompetitionGametype",lib_gCompetitionGametype},
|
||||||
{"G_TicsToHours",lib_gTicsToHours},
|
{"G_TicsToHours",lib_gTicsToHours},
|
||||||
{"G_TicsToMinutes",lib_gTicsToMinutes},
|
{"G_TicsToMinutes",lib_gTicsToMinutes},
|
||||||
{"G_TicsToSeconds",lib_gTicsToSeconds},
|
{"G_TicsToSeconds",lib_gTicsToSeconds},
|
||||||
|
|
|
@ -53,6 +53,7 @@ enum hook {
|
||||||
hook_IntermissionThinker,
|
hook_IntermissionThinker,
|
||||||
hook_TeamSwitch,
|
hook_TeamSwitch,
|
||||||
hook_ViewpointSwitch,
|
hook_ViewpointSwitch,
|
||||||
|
hook_SeenPlayer,
|
||||||
hook_PlayerThink,
|
hook_PlayerThink,
|
||||||
|
|
||||||
hook_MAX // last hook
|
hook_MAX // last hook
|
||||||
|
@ -98,6 +99,9 @@ void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting
|
||||||
void LUAh_IntermissionThinker(void); // Hook for Y_Ticker
|
void LUAh_IntermissionThinker(void); // Hook for Y_Ticker
|
||||||
boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble); // Hook for team switching in... uh....
|
boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble); // Hook for team switching in... uh....
|
||||||
UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced); // Hook for spy mode
|
UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced); // Hook for spy mode
|
||||||
|
#ifdef SEENAMES
|
||||||
|
boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend); // Hook for MT_NAMECHECK
|
||||||
|
#endif
|
||||||
#define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink
|
#define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -64,6 +64,7 @@ const char *const hookNames[hook_MAX+1] = {
|
||||||
"IntermissionThinker",
|
"IntermissionThinker",
|
||||||
"TeamSwitch",
|
"TeamSwitch",
|
||||||
"ViewpointSwitch",
|
"ViewpointSwitch",
|
||||||
|
"SeenPlayer",
|
||||||
"PlayerThink",
|
"PlayerThink",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
@ -208,6 +209,7 @@ static int lib_addHook(lua_State *L)
|
||||||
case hook_PlayerCanDamage:
|
case hook_PlayerCanDamage:
|
||||||
case hook_TeamSwitch:
|
case hook_TeamSwitch:
|
||||||
case hook_ViewpointSwitch:
|
case hook_ViewpointSwitch:
|
||||||
|
case hook_SeenPlayer:
|
||||||
case hook_ShieldSpawn:
|
case hook_ShieldSpawn:
|
||||||
case hook_ShieldSpecial:
|
case hook_ShieldSpecial:
|
||||||
case hook_PlayerThink:
|
case hook_PlayerThink:
|
||||||
|
@ -1414,7 +1416,7 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
lua_settop(gL, 0);
|
lua_settop(gL, 0);
|
||||||
hud_running = true;
|
hud_running = true; // local hook
|
||||||
|
|
||||||
for (hookp = playerhooks; hookp; hookp = hookp->next)
|
for (hookp = playerhooks; hookp; hookp = hookp->next)
|
||||||
{
|
{
|
||||||
|
@ -1455,4 +1457,49 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean
|
||||||
return canSwitchView;
|
return canSwitchView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hook for MT_NAMECHECK
|
||||||
|
#ifdef SEENAMES
|
||||||
|
boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend)
|
||||||
|
{
|
||||||
|
hook_p hookp;
|
||||||
|
boolean hasSeenPlayer = true;
|
||||||
|
if (!gL || !(hooksAvailable[hook_SeenPlayer/8] & (1<<(hook_SeenPlayer%8))))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
lua_settop(gL, 0);
|
||||||
|
hud_running = true; // local hook
|
||||||
|
|
||||||
|
for (hookp = playerhooks; hookp; hookp = hookp->next)
|
||||||
|
{
|
||||||
|
if (hookp->type != hook_SeenPlayer)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (lua_gettop(gL) == 0)
|
||||||
|
{
|
||||||
|
LUA_PushUserdata(gL, player, META_PLAYER);
|
||||||
|
LUA_PushUserdata(gL, seenfriend, META_PLAYER);
|
||||||
|
}
|
||||||
|
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
|
||||||
|
lua_gettable(gL, LUA_REGISTRYINDEX);
|
||||||
|
lua_pushvalue(gL, -3);
|
||||||
|
lua_pushvalue(gL, -3);
|
||||||
|
if (lua_pcall(gL, 2, 1, 0)) {
|
||||||
|
if (!hookp->error || cv_debug & DBG_LUA)
|
||||||
|
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
|
||||||
|
lua_pop(gL, 1);
|
||||||
|
hookp->error = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!lua_isnil(gL, -1) && !lua_toboolean(gL, -1))
|
||||||
|
hasSeenPlayer = false; // Hasn't seen player
|
||||||
|
lua_pop(gL, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_settop(gL, 0);
|
||||||
|
hud_running = false;
|
||||||
|
|
||||||
|
return hasSeenPlayer;
|
||||||
|
}
|
||||||
|
#endif // SEENAMES
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -299,9 +299,7 @@ int LUA_PushGlobals(lua_State *L, const char *word)
|
||||||
// See the above.
|
// See the above.
|
||||||
int LUA_CheckGlobals(lua_State *L, const char *word)
|
int LUA_CheckGlobals(lua_State *L, const char *word)
|
||||||
{
|
{
|
||||||
if (fastcmp(word, "gametyperules"))
|
if (fastcmp(word, "redscore"))
|
||||||
gametyperules = (UINT32)luaL_checkinteger(L, 2);
|
|
||||||
else if (fastcmp(word, "redscore"))
|
|
||||||
redscore = (UINT32)luaL_checkinteger(L, 2);
|
redscore = (UINT32)luaL_checkinteger(L, 2);
|
||||||
else if (fastcmp(word, "bluescore"))
|
else if (fastcmp(word, "bluescore"))
|
||||||
bluescore = (UINT32)luaL_checkinteger(L, 2);
|
bluescore = (UINT32)luaL_checkinteger(L, 2);
|
||||||
|
|
27
src/m_menu.c
27
src/m_menu.c
|
@ -4735,7 +4735,7 @@ static boolean M_CanShowLevelOnPlatter(INT32 mapnum, INT32 gt)
|
||||||
if (gt == GT_RACE && (mapheaderinfo[mapnum]->typeoflevel & TOL_RACE))
|
if (gt == GT_RACE && (mapheaderinfo[mapnum]->typeoflevel & TOL_RACE))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (gt > 0 && gt < gametypecount && (mapheaderinfo[mapnum]->typeoflevel & gametypetol[gt]))
|
if (gt >= 0 && gt < gametypecount && (mapheaderinfo[mapnum]->typeoflevel & gametypetol[gt]))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -9971,7 +9971,7 @@ static void M_DrawRoomMenu(void)
|
||||||
static void M_DrawConnectMenu(void)
|
static void M_DrawConnectMenu(void)
|
||||||
{
|
{
|
||||||
UINT16 i;
|
UINT16 i;
|
||||||
const char *gt = "Unknown";
|
char *gt;
|
||||||
INT32 numPages = (serverlistcount+(SERVERS_PER_PAGE-1))/SERVERS_PER_PAGE;
|
INT32 numPages = (serverlistcount+(SERVERS_PER_PAGE-1))/SERVERS_PER_PAGE;
|
||||||
|
|
||||||
for (i = FIRSTSERVERLINE; i < min(localservercount, SERVERS_PER_PAGE)+FIRSTSERVERLINE; i++)
|
for (i = FIRSTSERVERLINE; i < min(localservercount, SERVERS_PER_PAGE)+FIRSTSERVERLINE; i++)
|
||||||
|
@ -10015,14 +10015,17 @@ static void M_DrawConnectMenu(void)
|
||||||
V_DrawSmallString(currentMenu->x, S_LINEY(i)+8, globalflags,
|
V_DrawSmallString(currentMenu->x, S_LINEY(i)+8, globalflags,
|
||||||
va("Ping: %u", (UINT32)LONG(serverlist[slindex].info.time)));
|
va("Ping: %u", (UINT32)LONG(serverlist[slindex].info.time)));
|
||||||
|
|
||||||
gt = "Unknown";
|
gt = serverlist[slindex].info.gametypename;
|
||||||
if (serverlist[slindex].info.gametype < gametypecount)
|
|
||||||
gt = Gametype_Names[serverlist[slindex].info.gametype];
|
|
||||||
|
|
||||||
V_DrawSmallString(currentMenu->x+46,S_LINEY(i)+8, globalflags,
|
V_DrawSmallString(currentMenu->x+46,S_LINEY(i)+8, globalflags,
|
||||||
va("Players: %02d/%02d", serverlist[slindex].info.numberofplayer, serverlist[slindex].info.maxplayer));
|
va("Players: %02d/%02d", serverlist[slindex].info.numberofplayer, serverlist[slindex].info.maxplayer));
|
||||||
|
|
||||||
V_DrawSmallString(currentMenu->x+112, S_LINEY(i)+8, globalflags, va("Gametype: %s", gt));
|
if (strlen(gt) > 11)
|
||||||
|
gt = va("Gametype: %.11s...", gt);
|
||||||
|
else
|
||||||
|
gt = va("Gametype: %s", gt);
|
||||||
|
|
||||||
|
V_DrawSmallString(currentMenu->x+112, S_LINEY(i)+8, globalflags, gt);
|
||||||
|
|
||||||
MP_ConnectMenu[i+FIRSTSERVERLINE].status = IT_STRING | IT_CALL;
|
MP_ConnectMenu[i+FIRSTSERVERLINE].status = IT_STRING | IT_CALL;
|
||||||
}
|
}
|
||||||
|
@ -10063,7 +10066,15 @@ SERVER_LIST_ENTRY_COMPARATOR(time)
|
||||||
SERVER_LIST_ENTRY_COMPARATOR(numberofplayer)
|
SERVER_LIST_ENTRY_COMPARATOR(numberofplayer)
|
||||||
SERVER_LIST_ENTRY_COMPARATOR_REVERSE(numberofplayer)
|
SERVER_LIST_ENTRY_COMPARATOR_REVERSE(numberofplayer)
|
||||||
SERVER_LIST_ENTRY_COMPARATOR_REVERSE(maxplayer)
|
SERVER_LIST_ENTRY_COMPARATOR_REVERSE(maxplayer)
|
||||||
SERVER_LIST_ENTRY_COMPARATOR(gametype)
|
|
||||||
|
static int ServerListEntryComparator_gametypename(const void *entry1, const void *entry2)
|
||||||
|
{
|
||||||
|
const serverelem_t *sa = (const serverelem_t*)entry1, *sb = (const serverelem_t*)entry2;
|
||||||
|
int c;
|
||||||
|
if (( c = strcasecmp(sa->info.gametypename, sb->info.gametypename) ))
|
||||||
|
return c;
|
||||||
|
return strcmp(sa->info.servername, sb->info.servername); \
|
||||||
|
}
|
||||||
|
|
||||||
// Special one for modified state.
|
// Special one for modified state.
|
||||||
static int ServerListEntryComparator_modified(const void *entry1, const void *entry2)
|
static int ServerListEntryComparator_modified(const void *entry1, const void *entry2)
|
||||||
|
@ -10103,7 +10114,7 @@ void M_SortServerList(void)
|
||||||
qsort(serverlist, serverlistcount, sizeof(serverelem_t), ServerListEntryComparator_maxplayer_reverse);
|
qsort(serverlist, serverlistcount, sizeof(serverelem_t), ServerListEntryComparator_maxplayer_reverse);
|
||||||
break;
|
break;
|
||||||
case 5: // Gametype.
|
case 5: // Gametype.
|
||||||
qsort(serverlist, serverlistcount, sizeof(serverelem_t), ServerListEntryComparator_gametype);
|
qsort(serverlist, serverlistcount, sizeof(serverelem_t), ServerListEntryComparator_gametypename);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1451,7 +1451,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
|
||||||
if (player->starpostnum >= special->health)
|
if (player->starpostnum >= special->health)
|
||||||
return; // Already hit this post
|
return; // Already hit this post
|
||||||
|
|
||||||
if (cv_coopstarposts.value && gametype == GT_COOP && (netgame || multiplayer))
|
if (cv_coopstarposts.value && G_GametypeUsesCoopStarposts() && (netgame || multiplayer))
|
||||||
{
|
{
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
|
@ -2521,7 +2521,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
||||||
target->colorized = false;
|
target->colorized = false;
|
||||||
G_GhostAddColor(GHC_NORMAL);
|
G_GhostAddColor(GHC_NORMAL);
|
||||||
|
|
||||||
if ((target->player->lives <= 1) && (netgame || multiplayer) && (gametype == GT_COOP) && (cv_cooplives.value == 0))
|
if ((target->player->lives <= 1) && (netgame || multiplayer) && G_GametypeUsesCoopLives() && (cv_cooplives.value == 0))
|
||||||
;
|
;
|
||||||
else if (!target->player->bot && !target->player->spectator && (target->player->lives != INFLIVES)
|
else if (!target->player->bot && !target->player->spectator && (target->player->lives != INFLIVES)
|
||||||
&& G_GametypeUsesLives())
|
&& G_GametypeUsesLives())
|
||||||
|
@ -2531,7 +2531,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
||||||
if (target->player->lives <= 0) // Tails 03-14-2000
|
if (target->player->lives <= 0) // Tails 03-14-2000
|
||||||
{
|
{
|
||||||
boolean gameovermus = false;
|
boolean gameovermus = false;
|
||||||
if ((netgame || multiplayer) && (gametype == GT_COOP) && (cv_cooplives.value != 1))
|
if ((netgame || multiplayer) && G_GametypeUsesCoopLives() && (cv_cooplives.value != 1))
|
||||||
{
|
{
|
||||||
INT32 i;
|
INT32 i;
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
@ -3199,9 +3199,11 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
|
||||||
player->powers[pw_carry] = CR_NONE;
|
player->powers[pw_carry] = CR_NONE;
|
||||||
|
|
||||||
// Burst weapons and emeralds in Match/CTF only
|
// Burst weapons and emeralds in Match/CTF only
|
||||||
if (source && (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF))
|
if (source)
|
||||||
{
|
{
|
||||||
|
if ((gametyperules & GTR_RINGSLINGER) && !(gametyperules & GTR_TAG))
|
||||||
P_PlayerRingBurst(player, player->rings);
|
P_PlayerRingBurst(player, player->rings);
|
||||||
|
if (gametyperules & GTR_POWERSTONES)
|
||||||
P_PlayerEmeraldBurst(player, false);
|
P_PlayerEmeraldBurst(player, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -746,8 +746,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
if (tmthing->type == MT_NAMECHECK)
|
if (tmthing->type == MT_NAMECHECK)
|
||||||
{
|
{
|
||||||
// Ignore things that aren't players, ignore spectators, ignore yourself.
|
// Ignore things that aren't players, ignore spectators, ignore yourself.
|
||||||
// (also don't bother to check that tmthing->target->player is non-NULL because we're not actually using it here.)
|
if (!thing->player || !(tmthing->target && tmthing->target->player) || thing->player->spectator || (tmthing->target && thing->player == tmthing->target->player))
|
||||||
if (!thing->player || thing->player->spectator || (tmthing->target && thing->player == tmthing->target->player))
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Now check that you actually hit them.
|
// Now check that you actually hit them.
|
||||||
|
@ -760,6 +759,12 @@ static boolean PIT_CheckThing(mobj_t *thing)
|
||||||
if (tmthing->z + tmthing->height < thing->z)
|
if (tmthing->z + tmthing->height < thing->z)
|
||||||
return true; // underneath
|
return true; // underneath
|
||||||
|
|
||||||
|
#ifdef HAVE_BLUA
|
||||||
|
// REX HAS SEEN YOU
|
||||||
|
if (!LUAh_SeenPlayer(tmthing->target->player, thing->player))
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
seenplayer = thing->player;
|
seenplayer = thing->player;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11823,7 +11823,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i)
|
||||||
if (!cv_powerstones.value)
|
if (!cv_powerstones.value)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!(gametyperules & GTR_MATCHEMERALDS))
|
if (!(gametyperules & GTR_POWERSTONES))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
runemeraldmanager = true;
|
runemeraldmanager = true;
|
||||||
|
|
|
@ -2446,7 +2446,7 @@ static void P_InitLevelSettings(void)
|
||||||
// earthquake camera
|
// earthquake camera
|
||||||
memset(&quake,0,sizeof(struct quake));
|
memset(&quake,0,sizeof(struct quake));
|
||||||
|
|
||||||
if ((netgame || multiplayer) && gametype == GT_COOP && cv_coopstarposts.value == 2)
|
if ((netgame || multiplayer) && G_GametypeUsesCoopStarposts() && cv_coopstarposts.value == 2)
|
||||||
{
|
{
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
|
@ -2464,7 +2464,7 @@ static void P_InitLevelSettings(void)
|
||||||
{
|
{
|
||||||
G_PlayerReborn(i, true);
|
G_PlayerReborn(i, true);
|
||||||
|
|
||||||
if (canresetlives && (netgame || multiplayer) && playeringame[i] && (gametype == GT_COMPETITION || players[i].lives <= 0))
|
if (canresetlives && (netgame || multiplayer) && playeringame[i] && (G_CompetitionGametype() || players[i].lives <= 0))
|
||||||
{
|
{
|
||||||
// In Co-Op, replenish a user's lives if they are depleted.
|
// In Co-Op, replenish a user's lives if they are depleted.
|
||||||
players[i].lives = cv_startinglives.value;
|
players[i].lives = cv_startinglives.value;
|
||||||
|
@ -2754,17 +2754,10 @@ static void P_SetupCamera(void)
|
||||||
{
|
{
|
||||||
mapthing_t *thing;
|
mapthing_t *thing;
|
||||||
|
|
||||||
switch (gametype)
|
if (gametyperules & GTR_DEATHMATCHSTARTS)
|
||||||
{
|
|
||||||
case GT_MATCH:
|
|
||||||
case GT_TAG:
|
|
||||||
thing = deathmatchstarts[0];
|
thing = deathmatchstarts[0];
|
||||||
break;
|
else
|
||||||
|
|
||||||
default:
|
|
||||||
thing = playerstarts[0];
|
thing = playerstarts[0];
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thing)
|
if (thing)
|
||||||
{
|
{
|
||||||
|
@ -2979,7 +2972,7 @@ static void P_InitGametype(void)
|
||||||
P_InitPlayers();
|
P_InitPlayers();
|
||||||
|
|
||||||
// restore time in netgame (see also g_game.c)
|
// restore time in netgame (see also g_game.c)
|
||||||
if ((netgame || multiplayer) && gametype == GT_COOP && cv_coopstarposts.value == 2)
|
if ((netgame || multiplayer) && G_GametypeUsesCoopStarposts() && cv_coopstarposts.value == 2)
|
||||||
{
|
{
|
||||||
// is this a hack? maybe
|
// is this a hack? maybe
|
||||||
tic_t maxstarposttime = 0;
|
tic_t maxstarposttime = 0;
|
||||||
|
@ -3023,6 +3016,7 @@ boolean P_LoadLevel(boolean fromnetsave)
|
||||||
|
|
||||||
// This is needed. Don't touch.
|
// This is needed. Don't touch.
|
||||||
maptol = mapheaderinfo[gamemap-1]->typeoflevel;
|
maptol = mapheaderinfo[gamemap-1]->typeoflevel;
|
||||||
|
gametyperules = gametypedefaultrules[gametype];
|
||||||
|
|
||||||
CON_Drawer(); // let the user know what we are going to do
|
CON_Drawer(); // let the user know what we are going to do
|
||||||
I_FinishUpdate(); // page flip or blit buffer
|
I_FinishUpdate(); // page flip or blit buffer
|
||||||
|
|
41
src/p_user.c
41
src/p_user.c
|
@ -1230,13 +1230,13 @@ void P_GivePlayerLives(player_t *player, INT32 numlives)
|
||||||
|
|
||||||
if (gamestate == GS_LEVEL)
|
if (gamestate == GS_LEVEL)
|
||||||
{
|
{
|
||||||
if (player->lives == INFLIVES || (gametype != GT_COOP && gametype != GT_COMPETITION))
|
if (player->lives == INFLIVES || !(gametyperules & GTR_LIVES))
|
||||||
{
|
{
|
||||||
P_GivePlayerRings(player, 100*numlives);
|
P_GivePlayerRings(player, 100*numlives);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0)
|
if ((netgame || multiplayer) && G_GametypeUsesCoopLives() && cv_cooplives.value == 0)
|
||||||
{
|
{
|
||||||
P_GivePlayerRings(player, 100*numlives);
|
P_GivePlayerRings(player, 100*numlives);
|
||||||
if (player->lives - prevlives >= numlives)
|
if (player->lives - prevlives >= numlives)
|
||||||
|
@ -1267,7 +1267,7 @@ docooprespawn:
|
||||||
|
|
||||||
void P_GiveCoopLives(player_t *player, INT32 numlives, boolean sound)
|
void P_GiveCoopLives(player_t *player, INT32 numlives, boolean sound)
|
||||||
{
|
{
|
||||||
if (!((netgame || multiplayer) && gametype == GT_COOP))
|
if (!((netgame || multiplayer) && G_GametypeUsesCoopLives()))
|
||||||
{
|
{
|
||||||
P_GivePlayerLives(player, numlives);
|
P_GivePlayerLives(player, numlives);
|
||||||
if (sound)
|
if (sound)
|
||||||
|
@ -1395,7 +1395,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount)
|
||||||
player->score = MAXSCORE;
|
player->score = MAXSCORE;
|
||||||
|
|
||||||
// check for extra lives every 50000 pts
|
// check for extra lives every 50000 pts
|
||||||
if (!ultimatemode && !modeattacking && player->score > oldscore && player->score % 50000 < amount && (gametype == GT_COMPETITION || gametype == GT_COOP))
|
if (!ultimatemode && !modeattacking && player->score > oldscore && player->score % 50000 < amount && (gametyperules & GTR_LIVES))
|
||||||
{
|
{
|
||||||
P_GivePlayerLives(player, (player->score/50000) - (oldscore/50000));
|
P_GivePlayerLives(player, (player->score/50000) - (oldscore/50000));
|
||||||
P_PlayLivesJingle(player);
|
P_PlayLivesJingle(player);
|
||||||
|
@ -9305,7 +9305,7 @@ boolean P_GetLives(player_t *player)
|
||||||
{
|
{
|
||||||
INT32 i, maxlivesplayer = -1, livescheck = 1;
|
INT32 i, maxlivesplayer = -1, livescheck = 1;
|
||||||
if (!(netgame || multiplayer)
|
if (!(netgame || multiplayer)
|
||||||
|| (gametype != GT_COOP)
|
|| !G_GametypeUsesCoopLives()
|
||||||
|| (player->lives == INFLIVES))
|
|| (player->lives == INFLIVES))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -9454,7 +9454,7 @@ static void P_DeathThink(player_t *player)
|
||||||
player->playerstate = PST_REBORN;
|
player->playerstate = PST_REBORN;
|
||||||
else if ((player->lives > 0 || j != MAXPLAYERS) && !(!(netgame || multiplayer) && G_IsSpecialStage(gamemap))) // Don't allow "click to respawn" in special stages!
|
else if ((player->lives > 0 || j != MAXPLAYERS) && !(!(netgame || multiplayer) && G_IsSpecialStage(gamemap))) // Don't allow "click to respawn" in special stages!
|
||||||
{
|
{
|
||||||
if (gametype == GT_COOP && (netgame || multiplayer) && cv_coopstarposts.value == 2)
|
if (G_GametypeUsesCoopStarposts() && (netgame || multiplayer) && cv_coopstarposts.value == 2)
|
||||||
{
|
{
|
||||||
P_ConsiderAllGone();
|
P_ConsiderAllGone();
|
||||||
if ((player->deadtimer > TICRATE<<1) || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))
|
if ((player->deadtimer > TICRATE<<1) || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE)))
|
||||||
|
@ -9469,19 +9469,22 @@ static void P_DeathThink(player_t *player)
|
||||||
// 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 (gametype != GT_COOP && player->spectator)
|
// You're a spectator, so respawn right away.
|
||||||
|
if ((gametyperules & GTR_SPECTATORS) && player->spectator)
|
||||||
player->playerstate = PST_REBORN;
|
player->playerstate = PST_REBORN;
|
||||||
else switch(gametype) {
|
else
|
||||||
case GT_COOP:
|
{
|
||||||
case GT_COMPETITION:
|
// Give me one second.
|
||||||
case GT_RACE:
|
INT32 respawndelay = TICRATE;
|
||||||
if (player->deadtimer > TICRATE)
|
|
||||||
|
// Non-platform gametypes
|
||||||
|
if (gametyperules & GTR_RESPAWNDELAY)
|
||||||
|
respawndelay = (cv_respawntime.value*TICRATE);
|
||||||
|
|
||||||
|
// You've been dead for enough time.
|
||||||
|
// You may now respawn.
|
||||||
|
if (player->deadtimer > respawndelay)
|
||||||
player->playerstate = PST_REBORN;
|
player->playerstate = PST_REBORN;
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (player->deadtimer > cv_respawntime.value*TICRATE)
|
|
||||||
player->playerstate = PST_REBORN;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9495,7 +9498,7 @@ static void P_DeathThink(player_t *player)
|
||||||
INT32 i, deadtimercheck = INT32_MAX;
|
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 (G_CompetitionGametype())
|
||||||
{
|
{
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
|
@ -11560,7 +11563,7 @@ void P_PlayerThink(player_t *player)
|
||||||
#else
|
#else
|
||||||
if (player->spectator &&
|
if (player->spectator &&
|
||||||
#endif
|
#endif
|
||||||
gametype == GT_COOP && (netgame || multiplayer) && cv_coopstarposts.value == 2)
|
G_GametypeUsesCoopStarposts() && (netgame || multiplayer) && cv_coopstarposts.value == 2)
|
||||||
P_ConsiderAllGone();
|
P_ConsiderAllGone();
|
||||||
|
|
||||||
if (player->playerstate == PST_DEAD)
|
if (player->playerstate == PST_DEAD)
|
||||||
|
|
146
src/st_stuff.c
146
src/st_stuff.c
|
@ -694,7 +694,7 @@ static void ST_drawTime(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Counting down the hidetime?
|
// Counting down the hidetime?
|
||||||
if ((gametyperules & GTR_HIDETIME) && (stplyr->realtime <= (hidetime*TICRATE)))
|
if ((gametyperules & GTR_STARTCOUNTDOWN) && (stplyr->realtime <= (hidetime*TICRATE)))
|
||||||
{
|
{
|
||||||
tics = (hidetime*TICRATE - stplyr->realtime);
|
tics = (hidetime*TICRATE - stplyr->realtime);
|
||||||
if (tics < 3*TICRATE)
|
if (tics < 3*TICRATE)
|
||||||
|
@ -705,7 +705,7 @@ static void ST_drawTime(void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Hidetime finish!
|
// Hidetime finish!
|
||||||
if ((gametyperules & GTR_HIDETIME) && (stplyr->realtime < ((hidetime+1)*TICRATE)))
|
if ((gametyperules & GTR_STARTCOUNTDOWN) && (stplyr->realtime < ((hidetime+1)*TICRATE)))
|
||||||
ST_drawRaceNum(hidetime*TICRATE - stplyr->realtime);
|
ST_drawRaceNum(hidetime*TICRATE - stplyr->realtime);
|
||||||
|
|
||||||
// Time limit?
|
// Time limit?
|
||||||
|
@ -723,7 +723,7 @@ static void ST_drawTime(void)
|
||||||
downwards = true;
|
downwards = true;
|
||||||
}
|
}
|
||||||
// Post-hidetime normal.
|
// Post-hidetime normal.
|
||||||
else if (gametyperules & GTR_TAG)
|
else if (gametyperules & GTR_STARTCOUNTDOWN)
|
||||||
tics = stplyr->realtime - hidetime*TICRATE;
|
tics = stplyr->realtime - hidetime*TICRATE;
|
||||||
// "Shadow! What are you doing? Hurry and get back here
|
// "Shadow! What are you doing? Hurry and get back here
|
||||||
// right now before the island blows up with you on it!"
|
// right now before the island blows up with you on it!"
|
||||||
|
@ -845,69 +845,13 @@ static void ST_drawLivesArea(void)
|
||||||
hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, faceprefix[stplyr->skin], colormap);
|
hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, faceprefix[stplyr->skin], colormap);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lives number
|
// Metal Sonic recording
|
||||||
if (metalrecording)
|
if (metalrecording)
|
||||||
{
|
{
|
||||||
if (((2*leveltime)/TICRATE) & 1)
|
if (((2*leveltime)/TICRATE) & 1)
|
||||||
V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8,
|
V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8,
|
||||||
hudinfo[HUD_LIVES].f|V_PERPLAYER|V_REDMAP|V_HUDTRANS, "REC");
|
hudinfo[HUD_LIVES].f|V_PERPLAYER|V_REDMAP|V_HUDTRANS, "REC");
|
||||||
}
|
}
|
||||||
else if (G_GametypeUsesLives() || gametype == GT_RACE)
|
|
||||||
{
|
|
||||||
// x
|
|
||||||
V_DrawScaledPatch(hudinfo[HUD_LIVES].x+22, hudinfo[HUD_LIVES].y+10,
|
|
||||||
hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, stlivex);
|
|
||||||
|
|
||||||
// lives number
|
|
||||||
if (gametype == GT_RACE)
|
|
||||||
{
|
|
||||||
livescount = INFLIVES;
|
|
||||||
notgreyedout = true;
|
|
||||||
}
|
|
||||||
else if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3)
|
|
||||||
{
|
|
||||||
INT32 i;
|
|
||||||
livescount = 0;
|
|
||||||
notgreyedout = (stplyr->lives > 0);
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
|
||||||
{
|
|
||||||
if (!playeringame[i])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (players[i].lives < 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (players[i].lives > 1)
|
|
||||||
notgreyedout = true;
|
|
||||||
|
|
||||||
if (players[i].lives == INFLIVES)
|
|
||||||
{
|
|
||||||
livescount = INFLIVES;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (livescount < 99)
|
|
||||||
livescount += (players[i].lives);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
livescount = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? INFLIVES : stplyr->lives);
|
|
||||||
notgreyedout = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (livescount == INFLIVES)
|
|
||||||
V_DrawCharacter(hudinfo[HUD_LIVES].x+50, hudinfo[HUD_LIVES].y+8,
|
|
||||||
'\x16' | 0x80 | hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, false);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (stplyr->playerstate == PST_DEAD && !(stplyr->spectator) && (livescount || stplyr->deadtimer < (TICRATE<<1)))
|
|
||||||
livescount++;
|
|
||||||
if (livescount > 99)
|
|
||||||
livescount = 99;
|
|
||||||
V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8,
|
|
||||||
hudinfo[HUD_LIVES].f|V_PERPLAYER|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF), va("%d",livescount));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Spectator
|
// Spectator
|
||||||
else if (stplyr->spectator)
|
else if (stplyr->spectator)
|
||||||
v_colmap = V_GRAYMAP;
|
v_colmap = V_GRAYMAP;
|
||||||
|
@ -934,6 +878,82 @@ static void ST_drawLivesArea(void)
|
||||||
v_colmap = V_BLUEMAP;
|
v_colmap = V_BLUEMAP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Lives number
|
||||||
|
else
|
||||||
|
{
|
||||||
|
boolean candrawlives = true;
|
||||||
|
|
||||||
|
// Co-op and Competition, normal life counter
|
||||||
|
if (G_GametypeUsesLives())
|
||||||
|
{
|
||||||
|
// Handle cooplives here
|
||||||
|
if ((netgame || multiplayer) && G_GametypeUsesCoopLives() && cv_cooplives.value == 3)
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
livescount = 0;
|
||||||
|
notgreyedout = (stplyr->lives > 0);
|
||||||
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
|
{
|
||||||
|
if (!playeringame[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (players[i].lives < 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (players[i].lives > 1)
|
||||||
|
notgreyedout = true;
|
||||||
|
|
||||||
|
if (players[i].lives == INFLIVES)
|
||||||
|
{
|
||||||
|
livescount = INFLIVES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (livescount < 99)
|
||||||
|
livescount += (players[i].lives);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
livescount = (((netgame || multiplayer) && G_GametypeUsesCoopLives() && cv_cooplives.value == 0) ? INFLIVES : stplyr->lives);
|
||||||
|
notgreyedout = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Infinity symbol (Race)
|
||||||
|
else if (G_PlatformGametype() && !(gametyperules & GTR_LIVES))
|
||||||
|
{
|
||||||
|
livescount = INFLIVES;
|
||||||
|
notgreyedout = true;
|
||||||
|
}
|
||||||
|
// Otherwise nothing, sorry.
|
||||||
|
// Special Stages keep not showing lives,
|
||||||
|
// as G_GametypeUsesLives() returns false in
|
||||||
|
// Special Stages, and the infinity symbol
|
||||||
|
// cannot show up because Special Stages
|
||||||
|
// still have the GTR_LIVES gametype rule
|
||||||
|
// by default.
|
||||||
|
else
|
||||||
|
candrawlives = false;
|
||||||
|
|
||||||
|
// Draw the lives counter here.
|
||||||
|
if (candrawlives)
|
||||||
|
{
|
||||||
|
// x
|
||||||
|
V_DrawScaledPatch(hudinfo[HUD_LIVES].x+22, hudinfo[HUD_LIVES].y+10, hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, stlivex);
|
||||||
|
if (livescount == INFLIVES)
|
||||||
|
V_DrawCharacter(hudinfo[HUD_LIVES].x+50, hudinfo[HUD_LIVES].y+8,
|
||||||
|
'\x16' | 0x80 | hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, false);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (stplyr->playerstate == PST_DEAD && !(stplyr->spectator) && (livescount || stplyr->deadtimer < (TICRATE<<1)))
|
||||||
|
livescount++;
|
||||||
|
if (livescount > 99)
|
||||||
|
livescount = 99;
|
||||||
|
V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8,
|
||||||
|
hudinfo[HUD_LIVES].f|V_PERPLAYER|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF), va("%d",livescount));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#undef ST_drawLivesX
|
||||||
|
}
|
||||||
|
|
||||||
// name
|
// name
|
||||||
v_colmap |= (V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER);
|
v_colmap |= (V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER);
|
||||||
|
@ -2202,7 +2222,7 @@ static void ST_drawTextHUD(void)
|
||||||
donef12 = true;
|
donef12 = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) // Death overrides spectator text.
|
else if ((gametyperules & GTR_RESPAWNDELAY) && stplyr->playerstate == PST_DEAD && stplyr->lives) // Death overrides spectator text.
|
||||||
{
|
{
|
||||||
INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE;
|
INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE;
|
||||||
|
|
||||||
|
@ -2226,7 +2246,7 @@ static void ST_drawTextHUD(void)
|
||||||
textHUDdraw(M_GetText("\x82""Wait for the stage to end..."))
|
textHUDdraw(M_GetText("\x82""Wait for the stage to end..."))
|
||||||
else if (G_PlatformGametype())
|
else if (G_PlatformGametype())
|
||||||
{
|
{
|
||||||
if (gametype == GT_COOP)
|
if (G_GametypeUsesCoopLives())
|
||||||
{
|
{
|
||||||
if (stplyr->lives <= 0
|
if (stplyr->lives <= 0
|
||||||
&& cv_cooplives.value == 2
|
&& cv_cooplives.value == 2
|
||||||
|
@ -2637,7 +2657,7 @@ static void ST_overlayDrawer(void)
|
||||||
INT32 i = MAXPLAYERS;
|
INT32 i = MAXPLAYERS;
|
||||||
INT32 deadtimer = stplyr->spectator ? TICRATE : (stplyr->deadtimer-(TICRATE<<1));
|
INT32 deadtimer = stplyr->spectator ? TICRATE : (stplyr->deadtimer-(TICRATE<<1));
|
||||||
|
|
||||||
if ((gametype == GT_COOP)
|
if (G_GametypeUsesCoopLives()
|
||||||
&& (netgame || multiplayer)
|
&& (netgame || multiplayer)
|
||||||
&& (cv_cooplives.value != 1))
|
&& (cv_cooplives.value != 1))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1997,7 +1997,7 @@ static void Y_AwardCoopBonuses(void)
|
||||||
|
|
||||||
if (i == consoleplayer)
|
if (i == consoleplayer)
|
||||||
{
|
{
|
||||||
data.coop.gotlife = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? 0 : ptlives);
|
data.coop.gotlife = (((netgame || multiplayer) && G_GametypeUsesCoopLives() && cv_cooplives.value == 0) ? 0 : ptlives);
|
||||||
M_Memcpy(&data.coop.bonuses, &localbonuses, sizeof(data.coop.bonuses));
|
M_Memcpy(&data.coop.bonuses, &localbonuses, sizeof(data.coop.bonuses));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2052,7 +2052,7 @@ static void Y_AwardSpecialStageBonus(void)
|
||||||
|
|
||||||
if (i == consoleplayer)
|
if (i == consoleplayer)
|
||||||
{
|
{
|
||||||
data.spec.gotlife = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? 0 : ptlives);
|
data.spec.gotlife = (((netgame || multiplayer) && G_GametypeUsesCoopLives() && cv_cooplives.value == 0) ? 0 : ptlives);
|
||||||
M_Memcpy(&data.spec.bonuses, &localbonuses, sizeof(data.spec.bonuses));
|
M_Memcpy(&data.spec.bonuses, &localbonuses, sizeof(data.spec.bonuses));
|
||||||
|
|
||||||
// Continues related
|
// Continues related
|
||||||
|
|
Loading…
Reference in New Issue