Make gametype struct and organize gametype data

This commit is contained in:
Lactozilla 2023-08-05 01:58:18 -03:00
parent 9e72b78a24
commit 08c087f6f6
12 changed files with 168 additions and 308 deletions

View file

@ -1389,7 +1389,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
netbuffer->u.serverinfo.refusereason = GetRefuseReason(node); netbuffer->u.serverinfo.refusereason = GetRefuseReason(node);
strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[gametype], strncpy(netbuffer->u.serverinfo.gametypename, gametypes[gametype].name,
sizeof netbuffer->u.serverinfo.gametypename); 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();

View file

@ -323,10 +323,6 @@ consvar_t cv_numlaps = CVAR_INIT ("numlaps", "4", CV_NETVAR|CV_CALL|CV_NOINIT|CV
static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "Map default"}, {0, NULL}}; static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "Map default"}, {0, NULL}};
consvar_t cv_basenumlaps = CVAR_INIT ("basenumlaps", "Map default", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT|CV_ALLOWLUA, basenumlaps_cons_t, BaseNumLaps_OnChange); consvar_t cv_basenumlaps = CVAR_INIT ("basenumlaps", "Map default", CV_SAVE|CV_NETVAR|CV_CALL|CV_CHEAT|CV_ALLOWLUA, basenumlaps_cons_t, BaseNumLaps_OnChange);
// Point and time limits for every gametype
INT32 pointlimits[NUMGAMETYPES];
INT32 timelimits[NUMGAMETYPES];
// log elemental hazards -- not a netvar, is local to current player // log elemental hazards -- not a netvar, is local to current player
consvar_t cv_hazardlog = CVAR_INIT ("hazardlog", "Yes", 0, CV_YesNo, NULL); consvar_t cv_hazardlog = CVAR_INIT ("hazardlog", "Yes", 0, CV_YesNo, NULL);
@ -439,15 +435,7 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
*/ */
void D_RegisterServerCommands(void) void D_RegisterServerCommands(void)
{ {
INT32 i; G_UpdateGametypeSelections();
for (i = 0; i < NUMGAMETYPES; i++)
{
gametype_cons_t[i].value = i;
gametype_cons_t[i].strvalue = Gametype_Names[i];
}
gametype_cons_t[NUMGAMETYPES].value = 0;
gametype_cons_t[NUMGAMETYPES].strvalue = NULL;
RegisterNetXCmd(XD_NAMEANDCOLOR, Got_NameAndColor); RegisterNetXCmd(XD_NAMEANDCOLOR, Got_NameAndColor);
RegisterNetXCmd(XD_WEAPONPREF, Got_WeaponPref); RegisterNetXCmd(XD_WEAPONPREF, Got_WeaponPref);
@ -1807,7 +1795,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
} }
CONS_Debug(DBG_GAMELOGIC, "Map change: mapnum=%d gametype=%d ultmode=%d resetplayers=%d delay=%d skipprecutscene=%d\n", CONS_Debug(DBG_GAMELOGIC, "Map change: mapnum=%d gametype=%d ultmode=%d resetplayers=%d delay=%d skipprecutscene=%d\n",
mapnum, newgametype, pultmode, resetplayers, delay, skipprecutscene); mapnum, newgametype, pultmode, resetplayers, delay, skipprecutscene);
if ((netgame || multiplayer) && !((gametype == newgametype) && (gametypedefaultrules[newgametype] & GTR_CAMPAIGN))) if ((netgame || multiplayer) && !((gametype == newgametype) && (gametypes[newgametype].rules & GTR_CAMPAIGN)))
FLS = false; FLS = false;
if (delay != 2) if (delay != 2)
@ -2049,7 +2037,7 @@ static void Command_Map_f(void)
fromlevelselect = fromlevelselect =
( netgame || multiplayer ) && ( netgame || multiplayer ) &&
newgametype == gametype && newgametype == gametype &&
gametypedefaultrules[newgametype] & GTR_CAMPAIGN; gametypes[newgametype].rules & GTR_CAMPAIGN;
} }
} }
@ -3921,7 +3909,7 @@ static void Command_ShowGametype_f(void)
// get name string for current gametype // get name string for current gametype
if (gametype >= 0 && gametype < gametypecount) if (gametype >= 0 && gametype < gametypecount)
gametypestr = Gametype_Names[gametype]; gametypestr = gametypes[gametype].name;
if (gametypestr) if (gametypestr)
CONS_Printf(M_GetText("Current gametype is %s\n"), gametypestr); CONS_Printf(M_GetText("Current gametype is %s\n"), gametypestr);
@ -4183,9 +4171,9 @@ void D_GameTypeChanged(INT32 lastgametype)
const char *oldgt = NULL, *newgt = NULL; const char *oldgt = NULL, *newgt = NULL;
if (lastgametype >= 0 && lastgametype < gametypecount) if (lastgametype >= 0 && lastgametype < gametypecount)
oldgt = Gametype_Names[lastgametype]; oldgt = gametypes[lastgametype].name;
if (gametype >= 0 && lastgametype < gametypecount) if (gametype >= 0 && lastgametype < gametypecount)
newgt = Gametype_Names[gametype]; newgt = gametypes[gametype].name;
if (oldgt && newgt) if (oldgt && newgt)
CONS_Printf(M_GetText("Gametype was changed from %s to %s\n"), oldgt, newgt); CONS_Printf(M_GetText("Gametype was changed from %s to %s\n"), oldgt, newgt);
@ -4199,55 +4187,13 @@ void D_GameTypeChanged(INT32 lastgametype)
else if (!cv_itemrespawn.changed || lastgametype == GT_COMPETITION) else if (!cv_itemrespawn.changed || lastgametype == GT_COMPETITION)
CV_SetValue(&cv_itemrespawn, 1); CV_SetValue(&cv_itemrespawn, 1);
switch (gametype) if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits
{ {
case GT_COOP: CV_SetValue(&cv_timelimit, gametypes[gametype].timelimit);
if (!cv_itemrespawntime.changed) CV_SetValue(&cv_pointlimit, gametypes[gametype].pointlimit);
CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); // respawn normally
break;
case GT_MATCH:
case GT_TEAMMATCH:
if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits
{
// default settings for match: timelimit 10 mins, no pointlimit
CV_SetValue(&cv_pointlimit, 0);
CV_SetValue(&cv_timelimit, 10);
}
if (!cv_itemrespawntime.changed)
CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); // respawn normally
break;
case GT_TAG:
case GT_HIDEANDSEEK:
if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits
{
// default settings for tag: 5 mins, no pointlimit
// Note that tag mode also uses an alternate timing mechanism in tandem with timelimit.
CV_SetValue(&cv_timelimit, 5);
CV_SetValue(&cv_pointlimit, 0);
}
if (!cv_itemrespawntime.changed)
CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); // respawn normally
break;
case GT_CTF:
if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits
{
// default settings for CTF: no timelimit, pointlimit 5
CV_SetValue(&cv_timelimit, 0);
CV_SetValue(&cv_pointlimit, 5);
}
if (!cv_itemrespawntime.changed)
CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); // respawn normally
break;
default:
if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits
{
CV_SetValue(&cv_timelimit, timelimits[gametype]);
CV_SetValue(&cv_pointlimit, pointlimits[gametype]);
}
if (!cv_itemrespawntime.changed)
CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); // respawn normally
break;
} }
if (!cv_itemrespawntime.changed)
CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); // respawn normally
} }
else if (!multiplayer && !netgame) else if (!multiplayer && !netgame)
{ {

View file

@ -307,8 +307,8 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
} }
else if (fastncmp("GT_", word, 3)) { else if (fastncmp("GT_", word, 3)) {
p = word; p = word;
for (i = 0; Gametype_ConstantNames[i]; i++) for (i = 0; i < gametypecount; i++)
if (fastcmp(p, Gametype_ConstantNames[i])) { if (fastcmp(p, gametypes[i].constant_name)) {
CacheAndPushConstant(L, word, i); CacheAndPushConstant(L, word, i);
return 1; return 1;
} }

View file

@ -1318,13 +1318,13 @@ void readgametype(MYFILE *f, char *gtname)
// Not covered by G_AddGametype alone. // Not covered by G_AddGametype alone.
if (newgtrankingstype == -1) if (newgtrankingstype == -1)
newgtrankingstype = newgtidx; newgtrankingstype = newgtidx;
gametyperankings[newgtidx] = newgtrankingstype; gametypes[newgtidx].rankings_type = newgtrankingstype;
intermissiontypes[newgtidx] = newgtinttype; gametypes[newgtidx].intermission_type = newgtinttype;
pointlimits[newgtidx] = newgtpointlimit; gametypes[newgtidx].pointlimit = newgtpointlimit;
timelimits[newgtidx] = newgttimelimit; gametypes[newgtidx].timelimit = newgttimelimit;
// Write the new gametype name. // Write the new gametype name.
Gametype_Names[newgtidx] = Z_StrDup((const char *)gtname); gametypes[newgtidx].name = Z_StrDup((const char *)gtname);
// Write the constant name. // Write the constant name.
if (gtconst[0] == '\0') if (gtconst[0] == '\0')
@ -1334,7 +1334,7 @@ void readgametype(MYFILE *f, char *gtname)
// Update gametype_cons_t accordingly. // Update gametype_cons_t accordingly.
G_UpdateGametypeSelections(); G_UpdateGametypeSelections();
CONS_Printf("Added gametype %s\n", Gametype_Names[newgtidx]); CONS_Printf("Added gametype %s\n", gametypes[newgtidx].name);
} }
void readlevelheader(MYFILE *f, INT32 num) void readlevelheader(MYFILE *f, INT32 num)
@ -4221,34 +4221,6 @@ menutype_t get_menutype(const char *word)
return MN_NONE; return MN_NONE;
} }
/*static INT16 get_gametype(const char *word)
{ // Returns the value of GT_ enumerations
INT16 i;
if (*word >= '0' && *word <= '9')
return atoi(word);
if (fastncmp("GT_",word,3))
word += 3; // take off the GT_
for (i = 0; i < NUMGAMETYPES; i++)
if (fastcmp(word, Gametype_ConstantNames[i]+3))
return i;
deh_warning("Couldn't find gametype named 'GT_%s'",word);
return GT_COOP;
}
static powertype_t get_power(const char *word)
{ // Returns the value of pw_ enumerations
powertype_t i;
if (*word >= '0' && *word <= '9')
return atoi(word);
if (fastncmp("PW_",word,3))
word += 3; // take off the pw_
for (i = 0; i < NUMPOWERS; i++)
if (fastcmp(word, POWERS_LIST[i]))
return i;
deh_warning("Couldn't find power named 'pw_%s'",word);
return pw_invulnerability;
}*/
/// \todo Make ANY of this completely over-the-top math craziness obey the order of operations. /// \todo Make ANY of this completely over-the-top math craziness obey the order of operations.
static fixed_t op_mul(fixed_t a, fixed_t b) { return a*b; } static fixed_t op_mul(fixed_t a, fixed_t b) { return a*b; }
static fixed_t op_div(fixed_t a, fixed_t b) { return a/b; } static fixed_t op_div(fixed_t a, fixed_t b) { return a/b; }

View file

@ -98,7 +98,6 @@ extern boolean multiplayer;
extern INT16 gametype; extern INT16 gametype;
extern UINT32 gametyperules; extern UINT32 gametyperules;
extern INT16 gametypecount;
extern boolean splitscreen; extern boolean splitscreen;
extern boolean circuitmap; // Does this level have 'circuit mode'? extern boolean circuitmap; // Does this level have 'circuit mode'?
@ -409,7 +408,7 @@ enum GameType
GT_LASTFREESLOT = GT_FIRSTFREESLOT + NUMGAMETYPEFREESLOTS - 1, GT_LASTFREESLOT = GT_FIRSTFREESLOT + NUMGAMETYPEFREESLOTS - 1,
NUMGAMETYPES NUMGAMETYPES
}; };
// If you alter this list, update deh_tables.c, MISC_ChangeGameTypeMenu in m_menu.c, and Gametype_Names in g_game.c // If you alter this list, update deh_tables.c, MISC_ChangeGameTypeMenu in m_menu.c, and gametypes in g_game.c
// Gametype rules // Gametype rules
enum GameTypeRules enum GameTypeRules
@ -448,13 +447,27 @@ enum GameTypeRules
GTR_CUTSCENES = 1<<31, // Play cutscenes, ending, credits, and evaluation GTR_CUTSCENES = 1<<31, // Play cutscenes, ending, credits, and evaluation
}; };
// String names for gametypes enum
extern const char *Gametype_Names[NUMGAMETYPES]; {
extern const char *Gametype_ConstantNames[NUMGAMETYPES]; RANKINGS_DEFAULT,
RANKINGS_COMPETITION,
RANKINGS_RACE
};
// Point and time limits for every gametype typedef struct
extern INT32 pointlimits[NUMGAMETYPES]; {
extern INT32 timelimits[NUMGAMETYPES]; const char *name;
const char *constant_name;
UINT32 rules;
UINT32 typeoflevel;
UINT8 intermission_type;
INT16 rankings_type;
INT32 pointlimit;
INT32 timelimit;
} gametype_t;
extern gametype_t gametypes[NUMGAMETYPES];
extern INT16 gametypecount;
// TypeOfLevel things // TypeOfLevel things
enum TypeOfLevel enum TypeOfLevel

View file

@ -3404,86 +3404,117 @@ void G_ExitLevel(void)
} }
} }
// See also the enum GameType in doomstat.h gametype_t gametypes[NUMGAMETYPES] = {
const char *Gametype_Names[NUMGAMETYPES] = // GT_COOP
{ {
"Co-op", // GT_COOP .name = "Co-op",
"Competition", // GT_COMPETITION .constant_name = "GT_COOP",
"Race", // GT_RACE .rules = GTR_CAMPAIGN|GTR_LIVES|GTR_FRIENDLY|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDHUNT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES|GTR_CUTSCENES,
.typeoflevel = TOL_COOP,
"Match", // GT_MATCH .intermission_type = int_coop,
"Team Match", // GT_TEAMMATCH .rankings_type = RANKINGS_DEFAULT,
},
"Tag", // GT_TAG // GT_COMPETITION
"Hide & Seek", // GT_HIDEANDSEEK {
.name = "Competition",
"CTF" // GT_CTF .constant_name = "GT_COMPETITION",
}; .rules = GTR_RACE|GTR_LIVES|GTR_SPAWNENEMIES|GTR_EMERALDTOKENS|GTR_SPAWNINVUL|GTR_ALLOWEXIT,
.typeoflevel = TOL_COMPETITION,
// For dehacked .intermission_type = int_comp,
const char *Gametype_ConstantNames[NUMGAMETYPES] = .rankings_type = RANKINGS_COMPETITION,
{ },
"GT_COOP", // GT_COOP // GT_RACE
"GT_COMPETITION", // GT_COMPETITION {
"GT_RACE", // GT_RACE .name = "Race",
.constant_name = "GT_RACE",
"GT_MATCH", // GT_MATCH .rules = GTR_RACE|GTR_SPAWNENEMIES|GTR_SPAWNINVUL|GTR_ALLOWEXIT,
"GT_TEAMMATCH", // GT_TEAMMATCH .typeoflevel = TOL_RACE,
.intermission_type = int_race,
"GT_TAG", // GT_TAG .rankings_type = RANKINGS_RACE,
"GT_HIDEANDSEEK", // GT_HIDEANDSEEK },
// GT_MATCH
"GT_CTF" // GT_CTF {
}; .name = "Match",
.constant_name = "GT_MATCH",
// Gametype rules .rules = GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_POWERSTONES|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD|GTR_DEATHPENALTY,
UINT32 gametypedefaultrules[NUMGAMETYPES] = .typeoflevel = TOL_MATCH,
{ .intermission_type = int_match,
// Co-op .rankings_type = RANKINGS_DEFAULT,
GTR_CAMPAIGN|GTR_LIVES|GTR_FRIENDLY|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDHUNT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES|GTR_CUTSCENES, // default settings for match: timelimit 10 mins, no pointlimit
// Competition .timelimit = 10,
GTR_RACE|GTR_LIVES|GTR_SPAWNENEMIES|GTR_EMERALDTOKENS|GTR_SPAWNINVUL|GTR_ALLOWEXIT, .pointlimit = 0
// Race },
GTR_RACE|GTR_SPAWNENEMIES|GTR_SPAWNINVUL|GTR_ALLOWEXIT, // GT_TEAMMATCH
{
// Match .name = "Team Match",
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_POWERSTONES|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD|GTR_DEATHPENALTY, .constant_name = "GT_TEAMMATCH",
// Team Match .rules = GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD,
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, .typeoflevel = TOL_MATCH,
.intermission_type = int_teammatch,
// Tag .rankings_type = RANKINGS_DEFAULT,
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_STARTCOUNTDOWN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, // default settings for match: timelimit 10 mins, no pointlimit
// Hide and Seek .timelimit = 10,
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_STARTCOUNTDOWN|GTR_HIDEFROZEN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, .pointlimit = 0
},
// CTF // GT_TAG
GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_POWERSTONES|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, {
.name = "Tag",
.constant_name = "GT_TAG",
.rules = GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_STARTCOUNTDOWN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY,
.typeoflevel = TOL_TAG,
.intermission_type = int_match,
.rankings_type = RANKINGS_DEFAULT,
// default settings for tag: 5 mins, no pointlimit
// Note that tag mode also uses an alternate timing mechanism in tandem with timelimit.
.timelimit = 5,
.pointlimit = 0
},
// GT_HIDEANDSEEK
{
.name = "Hide & Seek",
.constant_name = "GT_HIDEANDSEEK",
.rules = GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_STARTCOUNTDOWN|GTR_HIDEFROZEN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY,
.typeoflevel = TOL_TAG,
.intermission_type = int_match,
.rankings_type = RANKINGS_DEFAULT,
// default settings for tag: 5 mins, no pointlimit
// Note that tag mode also uses an alternate timing mechanism in tandem with timelimit.
.timelimit = 5,
.pointlimit = 0
},
// GT_CTF
{
.name = "CTF",
.constant_name = "GT_CTF",
.rules = GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_OVERTIME|GTR_POWERSTONES|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD,
.typeoflevel = TOL_CTF,
.intermission_type = int_ctf,
.rankings_type = RANKINGS_DEFAULT,
// default settings for CTF: no timelimit, pointlimit 5
.timelimit = 0,
.pointlimit = 5
},
}; };
// //
// G_SetGametype // Sets a new gametype, also setting gametype rules accordingly.
//
// Set a new gametype, also setting gametype rules accordingly. Yay!
// //
void G_SetGametype(INT16 gtype) void G_SetGametype(INT16 gtype)
{ {
gametype = gtype; gametype = gtype;
gametyperules = gametypedefaultrules[gametype]; gametyperules = gametypes[gametype].rules;
} }
// //
// G_AddGametype // Adds a gametype. Returns the new gametype number.
//
// Add a gametype. Returns the new gametype number.
// //
INT16 G_AddGametype(UINT32 rules) INT16 G_AddGametype(UINT32 rules)
{ {
INT16 newgtype = gametypecount; INT16 newgtype = gametypecount;
gametypecount++; gametypecount++;
// Set gametype rules. gametypes[newgtype].name = "???";
gametypedefaultrules[newgtype] = rules; gametypes[newgtype].rules = rules;
Gametype_Names[newgtype] = "???";
// Update gametype_cons_t accordingly. // Update gametype_cons_t accordingly.
G_UpdateGametypeSelections(); G_UpdateGametypeSelections();
@ -3491,78 +3522,27 @@ INT16 G_AddGametype(UINT32 rules)
return newgtype; return newgtype;
} }
//
// G_AddGametypeConstant
//
// Self-explanatory. Filters out "bad" characters.
//
void G_AddGametypeConstant(INT16 gtype, const char *newgtconst) void G_AddGametypeConstant(INT16 gtype, const char *newgtconst)
{ {
size_t r = 0; // read
size_t w = 0; // write
char *gtconst = Z_Calloc(strlen(newgtconst) + 4, PU_STATIC, NULL); char *gtconst = Z_Calloc(strlen(newgtconst) + 4, PU_STATIC, NULL);
char *tmpconst = Z_Calloc(strlen(newgtconst) + 1, PU_STATIC, NULL); char *tmpconst = Z_Calloc(strlen(newgtconst) + 1, PU_STATIC, NULL);
// Copy the gametype name.
strcpy(tmpconst, newgtconst); strcpy(tmpconst, newgtconst);
// Make uppercase.
strupr(tmpconst); strupr(tmpconst);
// Prepare to write the new constant string now.
strcpy(gtconst, "GT_"); strcpy(gtconst, "GT_");
// Remove characters that will not be allowed in the constant string. size_t w = strlen(gtconst);
for (; r < strlen(tmpconst); r++)
for (size_t r = 0; r < strlen(tmpconst); r++)
{ {
boolean writechar = true;
char rc = tmpconst[r]; char rc = tmpconst[r];
switch (rc) if (isalpha(rc) || isdigit(rc))
{ gtconst[w++] = 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++;
}
} }
// Free the temporary string.
Z_Free(tmpconst); Z_Free(tmpconst);
// Finally, set the constant string. gametypes[gtype].constant_name = gtconst;
Gametype_ConstantNames[gtype] = gtconst;
} }
// //
@ -3576,7 +3556,7 @@ void G_UpdateGametypeSelections(void)
for (i = 0; i < gametypecount; i++) for (i = 0; i < gametypecount; i++)
{ {
gametype_cons_t[i].value = i; gametype_cons_t[i].value = i;
gametype_cons_t[i].strvalue = Gametype_Names[i]; gametype_cons_t[i].strvalue = gametypes[i].name;
} }
gametype_cons_t[NUMGAMETYPES].value = 0; gametype_cons_t[NUMGAMETYPES].value = 0;
gametype_cons_t[NUMGAMETYPES].strvalue = NULL; gametype_cons_t[NUMGAMETYPES].strvalue = NULL;
@ -3596,38 +3576,6 @@ void G_SetGametypeDescription(INT16 gtype, char *descriptiontext, UINT8 leftcolo
gametypedesc[gtype].col[1] = rightcolor; gametypedesc[gtype].col[1] = rightcolor;
} }
// Gametype rankings
INT16 gametyperankings[NUMGAMETYPES] =
{
GT_COOP,
GT_COMPETITION,
GT_RACE,
GT_MATCH,
GT_TEAMMATCH,
GT_TAG,
GT_HIDEANDSEEK,
GT_CTF,
};
// Gametype to TOL (Type Of Level)
UINT32 gametypetol[NUMGAMETYPES] =
{
TOL_COOP, // Co-op
TOL_COMPETITION, // Competition
TOL_RACE, // Race
TOL_MATCH, // Match
TOL_MATCH, // Team Match
TOL_TAG, // Tag
TOL_TAG, // Hide and Seek
TOL_CTF, // CTF
};
tolinfo_t TYPEOFLEVEL[NUMTOLNAMES] = { tolinfo_t TYPEOFLEVEL[NUMTOLNAMES] = {
{"SOLO",TOL_SP}, {"SOLO",TOL_SP},
{"SP",TOL_SP}, {"SP",TOL_SP},
@ -3681,7 +3629,7 @@ void G_AddTOL(UINT32 newtol, const char *tolname)
// //
void G_AddGametypeTOL(INT16 gtype, UINT32 newtol) void G_AddGametypeTOL(INT16 gtype, UINT32 newtol)
{ {
gametypetol[gtype] = newtol; gametypes[gtype].typeoflevel = newtol;
} }
// //
@ -3694,7 +3642,7 @@ INT32 G_GetGametypeByName(const char *gametypestr)
INT32 i; INT32 i;
for (i = 0; i < gametypecount; i++) for (i = 0; i < gametypecount; i++)
if (!stricmp(gametypestr, Gametype_Names[i])) if (!stricmp(gametypestr, gametypes[i].name))
return i; return i;
return -1; // unknown gametype return -1; // unknown gametype
@ -3840,7 +3788,8 @@ UINT32 G_TOLFlag(INT32 pgametype)
{ {
if (!multiplayer) if (!multiplayer)
return TOL_SP; return TOL_SP;
return gametypetol[pgametype];
return gametypes[pgametype].typeoflevel;
} }
/** Select a random map with the given typeoflevel flags. /** Select a random map with the given typeoflevel flags.

View file

@ -190,10 +190,6 @@ void G_SaveGame(UINT32 slot, INT16 mapnum);
void G_SaveGameOver(UINT32 slot, boolean modifylives); void G_SaveGameOver(UINT32 slot, boolean modifylives);
extern UINT32 gametypedefaultrules[NUMGAMETYPES];
extern UINT32 gametypetol[NUMGAMETYPES];
extern INT16 gametyperankings[NUMGAMETYPES];
void G_SetGametype(INT16 gametype); void G_SetGametype(INT16 gametype);
INT16 G_AddGametype(UINT32 rules); INT16 G_AddGametype(UINT32 rules);
void G_AddGametypeConstant(INT16 gtype, const char *newgtconst); void G_AddGametypeConstant(INT16 gtype, const char *newgtconst);

View file

@ -1905,7 +1905,7 @@ static void HU_drawGametype(void)
if (gametype < 0 || gametype >= gametypecount) if (gametype < 0 || gametype >= gametypecount)
return; // not a valid gametype??? return; // not a valid gametype???
strvalue = Gametype_Names[gametype]; strvalue = gametypes[gametype].name;
if (splitscreen) if (splitscreen)
V_DrawString(4, 184, 0, strvalue); V_DrawString(4, 184, 0, strvalue);
@ -2188,7 +2188,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
for (i = 0; i < scorelines; i++) for (i = 0; i < scorelines; i++)
{ {
if (players[tab[i].num].spectator && gametyperankings[gametype] != GT_COOP) if (players[tab[i].num].spectator && !G_GametypeUsesCoopLives())
continue; //ignore them. continue; //ignore them.
greycheck = greycheckdef; greycheck = greycheckdef;
@ -2265,7 +2265,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
if (players[tab[i].num].exiting || (players[tab[i].num].pflags & PF_FINISHED)) if (players[tab[i].num].exiting || (players[tab[i].num].pflags & PF_FINISHED))
V_DrawSmallScaledPatch(x - exiticon->width/2 - 1, y-3, 0, exiticon); V_DrawSmallScaledPatch(x - exiticon->width/2 - 1, y-3, 0, exiticon);
if (gametyperankings[gametype] == GT_RACE) if (gametypes[gametype].rankings_type == RANKINGS_RACE)
{ {
if (circuitmap) if (circuitmap)
{ {
@ -2546,7 +2546,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
for (i = 0; i < scorelines; i++) for (i = 0; i < scorelines; i++)
{ {
if (players[tab[i].num].spectator && gametyperankings[gametype] != GT_COOP) if (players[tab[i].num].spectator && !G_GametypeUsesCoopLives())
continue; //ignore them. continue; //ignore them.
greycheck = greycheckdef; greycheck = greycheckdef;
@ -2613,7 +2613,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline
} }
// All data drawn with thin string for space. // All data drawn with thin string for space.
if (gametyperankings[gametype] == GT_RACE) if (gametypes[gametype].rankings_type == RANKINGS_RACE)
{ {
if (circuitmap) if (circuitmap)
{ {
@ -2653,7 +2653,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor
for (i = 0; i < scorelines; i++) for (i = 0; i < scorelines; i++)
{ {
if (players[tab[i].num].spectator && gametyperankings[gametype] != GT_COOP) if (players[tab[i].num].spectator && !G_GametypeUsesCoopLives())
continue; //ignore them. continue; //ignore them.
greycheck = greycheckdef; greycheck = greycheckdef;
@ -2724,7 +2724,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor
} }
// All data drawn with thin string for space. // All data drawn with thin string for space.
if (gametyperankings[gametype] == GT_RACE) if (gametypes[gametype].rankings_type == RANKINGS_RACE)
{ {
if (circuitmap) if (circuitmap)
{ {
@ -2884,7 +2884,7 @@ static void HU_DrawRankings(void)
tab[i].num = -1; tab[i].num = -1;
tab[i].name = 0; tab[i].name = 0;
if (gametyperankings[gametype] == GT_RACE && !circuitmap) if (gametypes[gametype].rankings_type == RANKINGS_RACE && !circuitmap)
tab[i].count = INT32_MAX; tab[i].count = INT32_MAX;
} }
@ -2904,7 +2904,7 @@ static void HU_DrawRankings(void)
if (!G_PlatformGametype() && players[i].spectator) if (!G_PlatformGametype() && players[i].spectator)
continue; continue;
if (gametyperankings[gametype] == GT_RACE) if (gametypes[gametype].rankings_type == RANKINGS_RACE)
{ {
if (circuitmap) if (circuitmap)
{ {
@ -2927,7 +2927,7 @@ static void HU_DrawRankings(void)
} }
} }
} }
else if (gametyperankings[gametype] == GT_COMPETITION) else if (gametypes[gametype].rankings_type == RANKINGS_COMPETITION)
{ {
// todo put something more fitting for the gametype here, such as current // todo put something more fitting for the gametype here, such as current
// number of categories led // number of categories led

View file

@ -3519,13 +3519,13 @@ static int lib_gAddGametype(lua_State *L)
// Not covered by G_AddGametype alone. // Not covered by G_AddGametype alone.
if (newgtrankingstype == -1) if (newgtrankingstype == -1)
newgtrankingstype = newgtidx; newgtrankingstype = newgtidx;
gametyperankings[newgtidx] = newgtrankingstype; gametypes[newgtidx].rankings_type = newgtrankingstype;
intermissiontypes[newgtidx] = newgtinttype; gametypes[newgtidx].intermission_type = newgtinttype;
pointlimits[newgtidx] = newgtpointlimit; gametypes[newgtidx].pointlimit = newgtpointlimit;
timelimits[newgtidx] = newgttimelimit; gametypes[newgtidx].timelimit = newgttimelimit;
// Write the new gametype name. // Write the new gametype name.
Gametype_Names[newgtidx] = gtname; gametypes[newgtidx].name = gtname;
// Write the constant name. // Write the constant name.
if (gtconst == NULL) if (gtconst == NULL)
@ -3536,7 +3536,7 @@ static int lib_gAddGametype(lua_State *L)
G_UpdateGametypeSelections(); G_UpdateGametypeSelections();
// done // done
CONS_Printf("Added gametype %s\n", Gametype_Names[newgtidx]); CONS_Printf("Added gametype %s\n", gametypes[newgtidx].name);
return 0; return 0;
} }

View file

@ -5085,7 +5085,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 & gametypes[gt].typeoflevel))
return true; return true;
return false; return false;

View file

@ -7646,7 +7646,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
// 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]; gametyperules = gametypes[gametype].rules;
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

View file

@ -164,7 +164,6 @@ static INT32 tallydonetic = -1;
static INT32 endtic = -1; static INT32 endtic = -1;
intertype_t intertype = int_none; intertype_t intertype = int_none;
intertype_t intermissiontypes[NUMGAMETYPES];
static huddrawlist_h luahuddrawlist_intermission; static huddrawlist_h luahuddrawlist_intermission;
@ -1275,25 +1274,10 @@ void Y_Ticker(void)
// //
void Y_DetermineIntermissionType(void) void Y_DetermineIntermissionType(void)
{ {
// set to int_none initially intertype = gametypes[gametype].intermission_type;
intertype = int_none;
if (intermissiontypes[gametype] != int_none) if (intertype == int_coop && G_IsSpecialStage(gamemap))
intertype = intermissiontypes[gametype]; intertype = int_spec;
else if (gametype == GT_COOP)
intertype = (G_IsSpecialStage(gamemap)) ? int_spec : int_coop;
else if (gametype == GT_TEAMMATCH)
intertype = int_teammatch;
else if (gametype == GT_MATCH
|| gametype == GT_TAG
|| gametype == GT_HIDEANDSEEK)
intertype = int_match;
else if (gametype == GT_RACE)
intertype = int_race;
else if (gametype == GT_COMPETITION)
intertype = int_comp;
else if (gametype == GT_CTF)
intertype = int_ctf;
} }
// //