gametype_t
- New array of pointers to structures in memory (currently mixing static for base-game and Callocated for custom)
- Centralises a metric-ton of previously seperately handled properties into one struct
- Gametype_Names[]
- Gametype_ConstantNames[]
- gametypetol[]
- timelimits[]
- pointlimits[]
- gametypedefaultrules[]
- gametypecolor[] - Nep: This one was blan exclusive but I added it regardless.
- Don't attempt to guess custom gametype in Replay Hut (requires more work to make custom gametypes behave across the entire experience)
- I_Error if invalid gametype set
- gametyperules is deprecated since it will never be modified seperately from gametype (temporarily a #define, don't wanna bloat this commit too much)
This commit is contained in:
parent
926f29dfb8
commit
4932bde9b0
16 changed files with 191 additions and 251 deletions
|
|
@ -1008,7 +1008,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
|
|||
else
|
||||
netbuffer->u.serverinfo.refusereason = 0;
|
||||
|
||||
strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[prefgametype],
|
||||
strncpy(netbuffer->u.serverinfo.gametypename, gametypes[prefgametype]->name,
|
||||
sizeof netbuffer->u.serverinfo.gametypename);
|
||||
netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame;
|
||||
netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled();
|
||||
|
|
|
|||
|
|
@ -1752,9 +1752,6 @@ void D_SRB2Main(void)
|
|||
|
||||
CON_Init();
|
||||
|
||||
memset(timelimits, 0, sizeof(timelimits));
|
||||
memset(pointlimits, 0, sizeof(pointlimits));
|
||||
|
||||
CON_SetLoadingProgress(LOADED_HUINIT);
|
||||
|
||||
if (modifiedgame)
|
||||
|
|
@ -2097,7 +2094,7 @@ void D_SRB2Main(void)
|
|||
if (newgametype == -1) // reached end of the list with no match
|
||||
{
|
||||
j = atoi(sgametype); // assume they gave us a gametype number, which is okay too
|
||||
if (j >= 0 && j < gametypecount)
|
||||
if (j >= 0 && j < numgametypes)
|
||||
newgametype = (INT16)j;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -766,10 +766,6 @@ consvar_t cv_timelimit = CVAR_INIT ("timelimit", "2", CV_NETVAR|CV_CALL|CV_NOINI
|
|||
static CV_PossibleValue_t numlaps_cons_t[] = {{0, "MIN"}, {MAX_LAPS, "MAX"}, {-1, "Map default"}, {0, NULL}};
|
||||
consvar_t cv_numlaps = CVAR_INIT ("numlaps", "Map default", CV_NETVAR|CV_CALL|CV_CHEAT, numlaps_cons_t, NumLaps_OnChange);
|
||||
|
||||
// Point and time limits for every gametype
|
||||
INT32 pointlimits[NUMGAMETYPES];
|
||||
INT32 timelimits[NUMGAMETYPES];
|
||||
|
||||
consvar_t cv_forceskin = CVAR_INIT ("forceskin", "None", CV_NETVAR|CV_CALL|CV_CHEAT, NULL, ForceSkin_OnChange);
|
||||
|
||||
consvar_t cv_downloading = CVAR_INIT ("downloading", "On", 0, CV_OnOff, NULL);
|
||||
|
|
@ -873,8 +869,7 @@ char timedemo_csv_id[256];
|
|||
boolean timedemo_quit;
|
||||
|
||||
INT16 gametype = GT_RACE;
|
||||
UINT32 gametyperules = 0;
|
||||
INT16 gametypecount = GT_FIRSTFREESLOT;
|
||||
INT16 numgametypes = GT_FIRSTFREESLOT;
|
||||
|
||||
boolean forceresetplayers = false;
|
||||
boolean deferencoremode = false;
|
||||
|
|
@ -960,13 +955,7 @@ void D_RegisterServerCommands(void)
|
|||
Forceskin_cons_t[0].value = -1;
|
||||
Forceskin_cons_t[0].strvalue = "Off";
|
||||
|
||||
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;
|
||||
G_UpdateGametypeSelections();
|
||||
|
||||
// Set the values to 0/NULL, it will be overwritten later when a skin is assigned to the slot.
|
||||
for (i = 1; i < MAXSKINS; i++)
|
||||
|
|
@ -3420,12 +3409,12 @@ void D_SetupVote(void)
|
|||
UINT8 secondgt = G_SometimesGetDifferentGametype(gt);
|
||||
INT16 votebuffer[4] = {-1,-1,-1,0};
|
||||
|
||||
if (cv_kartencore.value && cv_encorevotes.value == 1 && (gametypedefaultrules[gt] & GTR_CIRCUIT))
|
||||
if (cv_kartencore.value && cv_encorevotes.value == 1 && (gametypes[gt]->rules & GTR_CIRCUIT))
|
||||
WRITEUINT8(p, (gt|VOTEMODIFIER_ENCORE));
|
||||
else
|
||||
WRITEUINT8(p, gt);
|
||||
|
||||
if (cv_kartencore.value && cv_encorevotes.value == 0 && (gametypedefaultrules[gt] & GTR_CIRCUIT))
|
||||
if (cv_kartencore.value && cv_encorevotes.value == 0 && (gametyperules & GTR_CIRCUIT))
|
||||
WRITEUINT8(p, secondgt|VOTEMODIFIER_ENCORE);
|
||||
else
|
||||
WRITEUINT8(p, secondgt);
|
||||
|
|
@ -3680,7 +3669,7 @@ static void Command_Map_f(void)
|
|||
if (isdigit(gametypename[0]))
|
||||
{
|
||||
d = atoi(gametypename);
|
||||
if (d >= 0 && d < gametypecount)
|
||||
if (d >= 0 && d < numgametypes)
|
||||
newgametype = d;
|
||||
else
|
||||
{
|
||||
|
|
@ -3688,7 +3677,7 @@ static void Command_Map_f(void)
|
|||
"Gametype number %d is out of range. Use a number between"
|
||||
" 0 and %d inclusive. ...Or just use the name. :v\n",
|
||||
d,
|
||||
gametypecount-1);
|
||||
numgametypes-1);
|
||||
Z_Free(realmapname);
|
||||
Z_Free(mapname);
|
||||
return;
|
||||
|
|
@ -3923,7 +3912,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
|
|||
gametype = READUINT8(*cp);
|
||||
G_SetGametype(gametype); // I fear putting that macro as an argument
|
||||
|
||||
if (gametype < 0 || gametype >= gametypecount)
|
||||
if (gametype < 0 || gametype >= numgametypes)
|
||||
gametype = lastgametype;
|
||||
else if (gametype != lastgametype)
|
||||
D_GameTypeChanged(lastgametype); // emulate consvar_t behavior for gametype
|
||||
|
|
@ -5944,8 +5933,8 @@ static void Command_ShowGametype_f(void)
|
|||
const char *gametypestr = NULL;
|
||||
|
||||
// get name string for current gametype
|
||||
if (gametype >= 0 && gametype < gametypecount)
|
||||
gametypestr = Gametype_Names[gametype];
|
||||
if (gametype >= 0 && gametype < numgametypes)
|
||||
gametypestr = gametypes[gametype]->name;
|
||||
|
||||
if (gametypestr)
|
||||
CONS_Printf(M_GetText("Current gametype is %s\n"), gametypestr);
|
||||
|
|
@ -6110,10 +6099,10 @@ void D_GameTypeChanged(INT32 lastgametype)
|
|||
{
|
||||
const char *oldgt = NULL, *newgt = NULL;
|
||||
|
||||
if (lastgametype >= 0 && lastgametype < gametypecount)
|
||||
oldgt = Gametype_Names[lastgametype];
|
||||
if (gametype >= 0 && lastgametype < gametypecount)
|
||||
newgt = Gametype_Names[gametype];
|
||||
if (lastgametype >= 0 && lastgametype < numgametypes)
|
||||
oldgt = gametypes[lastgametype]->name;
|
||||
if (gametype >= 0 && gametype < numgametypes)
|
||||
newgt = gametypes[gametype]->name;
|
||||
|
||||
if (oldgt && newgt)
|
||||
CONS_Printf(M_GetText("Gametype was changed from %s to %s\n"), oldgt, newgt);
|
||||
|
|
@ -6124,11 +6113,11 @@ void D_GameTypeChanged(INT32 lastgametype)
|
|||
{
|
||||
if (!cv_timelimit.changed) // user hasn't changed limits
|
||||
{
|
||||
CV_SetValue(&cv_timelimit, timelimits[gametype]);
|
||||
CV_SetValue(&cv_timelimit, gametypes[gametype]->timelimit);
|
||||
}
|
||||
if (!cv_pointlimit.changed)
|
||||
{
|
||||
CV_SetValue(&cv_pointlimit, pointlimits[gametype]);
|
||||
CV_SetValue(&cv_pointlimit, gametypes[gametype]->pointlimit);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6429,25 +6418,25 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum)
|
|||
|
||||
// Strip illegal Encore flag.
|
||||
if ((gt & VOTEMODIFIER_ENCORE)
|
||||
&& !(gametypedefaultrules[(gt & ~VOTEMODIFIER_ENCORE)] & GTR_CIRCUIT))
|
||||
&& !(gametypes[(gt & ~VOTEMODIFIER_ENCORE)]->rules & GTR_CIRCUIT))
|
||||
{
|
||||
gt &= ~VOTEMODIFIER_ENCORE;
|
||||
}
|
||||
|
||||
if ((gt & ~VOTEMODIFIER_ENCORE) >= gametypecount)
|
||||
if ((gt & ~VOTEMODIFIER_ENCORE) >= numgametypes)
|
||||
{
|
||||
gt &= ~VOTEMODIFIER_ENCORE;
|
||||
if (server)
|
||||
I_Error("Got_SetupVotecmd: Internal gametype ID %d not found (gametypecount = %d)", gt, gametypecount);
|
||||
I_Error("Got_SetupVotecmd: Internal gametype ID %d not found (numgametypes = %d)", gt, numgametypes);
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Vote setup with bad gametype ID %d received from %s\n"), gt, player_names[playernum]);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((secondgt & ~VOTEMODIFIER_ENCORE) >= gametypecount)
|
||||
if ((secondgt & ~VOTEMODIFIER_ENCORE) >= numgametypes)
|
||||
{
|
||||
secondgt &= ~VOTEMODIFIER_ENCORE;
|
||||
if (server)
|
||||
I_Error("Got_SetupVotecmd: Internal second gametype ID %d not found (gametypecount = %d)", secondgt, gametypecount);
|
||||
I_Error("Got_SetupVotecmd: Internal second gametype ID %d not found (numgametypes = %d)", secondgt, numgametypes);
|
||||
CONS_Alert(CONS_WARNING, M_GetText("Vote setup with bad second gametype ID %d received from %s\n"), secondgt, player_names[playernum]);
|
||||
return;
|
||||
}
|
||||
|
|
@ -6471,11 +6460,11 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum)
|
|||
|
||||
// If third entry has an illelegal Encore flag... (illelegal!?)
|
||||
if ((secondgt & VOTEMODIFIER_ENCORE)
|
||||
&& !(gametypedefaultrules[(secondgt & ~VOTEMODIFIER_ENCORE)] & GTR_CIRCUIT))
|
||||
&& !(gametypes[(secondgt & ~VOTEMODIFIER_ENCORE)]->rules & GTR_CIRCUIT))
|
||||
{
|
||||
secondgt &= ~VOTEMODIFIER_ENCORE;
|
||||
// Apply it to the second entry instead, gametype permitting!
|
||||
if (gametypedefaultrules[gt] & GTR_CIRCUIT)
|
||||
if (gametypes[gt]->rules & GTR_CIRCUIT)
|
||||
{
|
||||
g_voteLevels[1][1] |= VOTEMODIFIER_ENCORE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -202,11 +202,16 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word)
|
|||
}
|
||||
else if (fastncmp("GT_", word, 3)) {
|
||||
p = word;
|
||||
for (i = 0; Gametype_ConstantNames[i]; i++)
|
||||
if (fastcmp(p, Gametype_ConstantNames[i])) {
|
||||
i = 0;
|
||||
while (gametypes[i] != NULL)
|
||||
{
|
||||
if (fastcmp(p, gametypes[i]->constant))
|
||||
{
|
||||
CacheAndPushConstant(L, word, i);
|
||||
return 1;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "gametype '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -642,14 +642,13 @@ void readgametype(MYFILE *f, char *gtname)
|
|||
char *tmp;
|
||||
INT32 i, j;
|
||||
|
||||
INT16 newgtidx = 0;
|
||||
gametype_t *newgametype = NULL;
|
||||
UINT32 newgtrules = 0;
|
||||
UINT32 newgttol = 0;
|
||||
INT32 newgtpointlimit = 0;
|
||||
INT32 newgttimelimit = 0;
|
||||
INT16 newgtrankingstype = -1;
|
||||
INT32 newgtcolor = V_YELLOWMAP;
|
||||
int newgtinttype = 0;
|
||||
UINT8 newgtinttype = 0;
|
||||
char gtconst[MAXLINELEN];
|
||||
|
||||
// Empty strings.
|
||||
|
|
@ -700,12 +699,6 @@ void readgametype(MYFILE *f, char *gtname)
|
|||
newgtpointlimit = (INT32)i;
|
||||
else if (fastcmp(word, "DEFAULTTIMELIMIT"))
|
||||
newgttimelimit = (INT32)i;
|
||||
// Rankings type
|
||||
else if (fastcmp(word, "RANKINGTYPE"))
|
||||
{
|
||||
// Case insensitive
|
||||
newgtrankingstype = (int)get_number(word2);
|
||||
}
|
||||
// Intermission type
|
||||
else if (fastcmp(word, "INTERMISSIONTYPE"))
|
||||
{
|
||||
|
|
@ -765,37 +758,36 @@ void readgametype(MYFILE *f, char *gtname)
|
|||
Z_Free(word2lwr);
|
||||
|
||||
// Ran out of gametype slots
|
||||
if (gametypecount == NUMGAMETYPEFREESLOTS)
|
||||
if (numgametypes == GT_LASTFREESLOT)
|
||||
{
|
||||
I_Error("Out of Gametype Freeslots while allocating \"%s\"\nLoad less addons to fix this.", gtname);
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the new gametype
|
||||
newgtidx = G_AddGametype(newgtrules);
|
||||
G_AddGametypeTOL(newgtidx, newgttol);
|
||||
newgametype = Z_Calloc(sizeof (gametype_t), PU_STATIC, NULL);
|
||||
if (!newgametype)
|
||||
{
|
||||
I_Error("Out of memory allocating gametype \"%s\"", gtname);
|
||||
}
|
||||
|
||||
// Not covered by G_AddGametype alone.
|
||||
if (newgtrankingstype == -1)
|
||||
newgtrankingstype = newgtidx;
|
||||
gametyperankings[newgtidx] = newgtrankingstype;
|
||||
intermissiontypes[newgtidx] = newgtinttype;
|
||||
pointlimits[newgtidx] = newgtpointlimit;
|
||||
timelimits[newgtidx] = newgttimelimit;
|
||||
gametypecolor[newgtidx] = newgtcolor;
|
||||
|
||||
// Write the new gametype name.
|
||||
Gametype_Names[newgtidx] = Z_StrDup((const char *)gtname);
|
||||
|
||||
// Write the constant name.
|
||||
if (gtconst[0] == '\0')
|
||||
strncpy(gtconst, gtname, MAXLINELEN);
|
||||
G_AddGametypeConstant(newgtidx, (const char *)gtconst);
|
||||
|
||||
newgametype->name = Z_StrDup((const char *)gtname);
|
||||
newgametype->rules = newgtrules;
|
||||
newgametype->constant = G_PrepareGametypeConstant((const char *)gtconst);
|
||||
newgametype->tol = newgttol;
|
||||
newgametype->intermission = newgtinttype;
|
||||
newgametype->pointlimit = newgtpointlimit;
|
||||
newgametype->timelimit = newgttimelimit;
|
||||
newgametype->color = newgtcolor;
|
||||
|
||||
gametypes[numgametypes++] = newgametype;
|
||||
|
||||
// Update gametype_cons_t accordingly.
|
||||
G_UpdateGametypeSelections();
|
||||
|
||||
CONS_Printf("Added gametype %s\n", Gametype_Names[newgtidx]);
|
||||
CONS_Printf("Added gametype %s\n", gtname);
|
||||
}
|
||||
|
||||
static mapheader_lighting_t *usemaplighting(INT32 mapnum, const char *word)
|
||||
|
|
@ -4497,7 +4489,7 @@ menudrawer_f *get_menudrawer(const char *word)
|
|||
return atoi(word);
|
||||
if (fastncmp("GT_",word,3))
|
||||
word += 3; // take off the GT_
|
||||
for (i = 0; i < NUMGAMETYPES; i++)
|
||||
for (i = 0; i < MAXGAMETYPES; i++)
|
||||
if (fastcmp(word, Gametype_ConstantNames[i]+3))
|
||||
return i;
|
||||
deh_warning("Couldn't find gametype named 'GT_%s'",word);
|
||||
|
|
|
|||
|
|
@ -146,11 +146,6 @@ extern boolean addedtogame; // true after the server has added you
|
|||
// Only true if >1 player. netgame => multiplayer but not (multiplayer=>netgame)
|
||||
extern boolean multiplayer;
|
||||
|
||||
extern INT16 gametype;
|
||||
|
||||
extern UINT32 gametyperules;
|
||||
extern INT16 gametypecount;
|
||||
|
||||
extern UINT8 splitscreen;
|
||||
extern int r_splitscreen;
|
||||
|
||||
|
|
@ -458,7 +453,7 @@ extern mapheader_t** mapheaderinfo;
|
|||
extern INT32 nummapheaders, mapallocsize;
|
||||
|
||||
// Gametypes
|
||||
#define NUMGAMETYPEFREESLOTS (NUMGAMETYPES-GT_FIRSTFREESLOT)
|
||||
#define NUMGAMETYPEFREESLOTS (MAXGAMETYPES-GT_FIRSTFREESLOT)
|
||||
|
||||
enum GameType
|
||||
{
|
||||
|
|
@ -467,9 +462,29 @@ enum GameType
|
|||
|
||||
GT_FIRSTFREESLOT,
|
||||
GT_LASTFREESLOT = 127, // Previously (GT_FIRSTFREESLOT + NUMGAMETYPEFREESLOTS - 1) - it would be necessary to rewrite VOTEMODIFIER_ENCORE to go higher than this.
|
||||
NUMGAMETYPES
|
||||
MAXGAMETYPES
|
||||
};
|
||||
// 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 defaultgametypes and *gametypes in g_game.c
|
||||
#define MAXTOL (1<<31)
|
||||
#define NUMBASETOLNAMES (10)
|
||||
#define NUMTOLNAMES (NUMBASETOLNAMES + NUMGAMETYPEFREESLOTS)
|
||||
|
||||
struct gametype_t
|
||||
{
|
||||
const char *name;
|
||||
const char *constant;
|
||||
UINT32 rules;
|
||||
UINT32 tol;
|
||||
UINT8 intermission;
|
||||
INT32 pointlimit;
|
||||
INT32 timelimit;
|
||||
INT32 color;
|
||||
};
|
||||
|
||||
extern gametype_t *gametypes[MAXGAMETYPES+1];
|
||||
extern INT16 numgametypes;
|
||||
|
||||
extern INT16 gametype;
|
||||
|
||||
// Gametype rules
|
||||
enum GameTypeRules
|
||||
|
|
@ -516,13 +531,8 @@ enum GameTypeRules
|
|||
// free: to and including 1<<31
|
||||
};
|
||||
|
||||
// String names for gametypes
|
||||
extern const char *Gametype_Names[NUMGAMETYPES];
|
||||
extern const char *Gametype_ConstantNames[NUMGAMETYPES];
|
||||
|
||||
// Point and time limits for every gametype
|
||||
extern INT32 pointlimits[NUMGAMETYPES];
|
||||
extern INT32 timelimits[NUMGAMETYPES];
|
||||
// TODO: replace every instance
|
||||
#define gametyperules (gametypes[gametype]->rules)
|
||||
|
||||
// TypeOfLevel things
|
||||
enum TypeOfLevel
|
||||
|
|
@ -545,10 +555,6 @@ enum TypeOfLevel
|
|||
TOL_TV = 0x0200 ///< Midnight Channel specific: draw TV like overlay on HUD
|
||||
};
|
||||
|
||||
#define MAXTOL (1<<31)
|
||||
#define NUMBASETOLNAMES (10)
|
||||
#define NUMTOLNAMES (NUMBASETOLNAMES + NUMGAMETYPEFREESLOTS)
|
||||
|
||||
struct tolinfo_t
|
||||
{
|
||||
const char *name;
|
||||
|
|
|
|||
167
src/g_game.c
167
src/g_game.c
|
|
@ -3846,28 +3846,55 @@ void G_FinishExitLevel(void)
|
|||
}
|
||||
}
|
||||
|
||||
// See also the enum GameType in doomstat.h
|
||||
const char *Gametype_Names[NUMGAMETYPES] =
|
||||
static gametype_t defaultgametypes[] =
|
||||
{
|
||||
"Race", // GT_RACE
|
||||
"Battle" // GT_BATTLE
|
||||
// GT_RACE
|
||||
{
|
||||
"Race",
|
||||
"GT_RACE",
|
||||
GTR_CIRCUIT|GTR_BOTS|GTR_RINGS|GTR_ENCORE|GTR_RACEODDS,
|
||||
TOL_RACE,
|
||||
int_race,
|
||||
0,
|
||||
0,
|
||||
V_SKYMAP,
|
||||
},
|
||||
{
|
||||
"Battle",
|
||||
"GT_BATTLE",
|
||||
GTR_BUMPERS|GTR_POINTS|GTR_RINGS|GTR_KARMA|GTR_WANTED|GTR_WANTEDSPB|GTR_ITEMARROWS|GTR_ITEMBREAKER|GTR_BATTLESTARTS|GTR_TIMELIMIT|GTR_POINTLIMIT|GTR_BATTLEODDS|GTR_CLOSERPLAYERS|GTR_BATTLEBOXES|GTR_BATTLESPEED,
|
||||
TOL_BATTLE,
|
||||
int_battle,
|
||||
0,
|
||||
2,
|
||||
V_REDMAP,
|
||||
},
|
||||
};
|
||||
|
||||
// For dehacked
|
||||
const char *Gametype_ConstantNames[NUMGAMETYPES] =
|
||||
gametype_t *gametypes[MAXGAMETYPES+1] =
|
||||
{
|
||||
"GT_RACE", // GT_RACE
|
||||
"GT_BATTLE" // GT_BATTLE
|
||||
&defaultgametypes[GT_RACE],
|
||||
&defaultgametypes[GT_BATTLE],
|
||||
};
|
||||
|
||||
// Gametype rules
|
||||
UINT32 gametypedefaultrules[NUMGAMETYPES] =
|
||||
//
|
||||
// G_GetGametypeByName
|
||||
//
|
||||
// Returns the number for the given gametype name string, or -1 if not valid.
|
||||
//
|
||||
INT32 G_GetGametypeByName(const char *gametypestr)
|
||||
{
|
||||
// Race
|
||||
GTR_CIRCUIT|GTR_BOTS|GTR_RINGS|GTR_ENCORE|GTR_RACEODDS,
|
||||
// Battle
|
||||
GTR_BUMPERS|GTR_POINTS|GTR_RINGS|GTR_KARMA|GTR_WANTED|GTR_WANTEDSPB|GTR_ITEMARROWS|GTR_ITEMBREAKER|GTR_BATTLESTARTS|GTR_TIMELIMIT|GTR_POINTLIMIT|GTR_BATTLEODDS|GTR_CLOSERPLAYERS|GTR_BATTLEBOXES|GTR_BATTLESPEED
|
||||
};
|
||||
INT32 i = 0;
|
||||
|
||||
while (gametypes[i] != NULL)
|
||||
{
|
||||
if (!stricmp(gametypestr, gametypes[i]->name))
|
||||
return i;
|
||||
i++;
|
||||
}
|
||||
|
||||
return -1; // unknown gametype
|
||||
}
|
||||
|
||||
//
|
||||
// G_SetGametype
|
||||
|
|
@ -3876,41 +3903,26 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] =
|
|||
//
|
||||
void G_SetGametype(INT16 gtype)
|
||||
{
|
||||
if (gtype < 0 || gtype > numgametypes)
|
||||
{
|
||||
I_Error("G_SetGametype: Bad gametype change %d (was %d/\"%s\")", gtype, gametype, gametypes[gametype]->name);
|
||||
}
|
||||
|
||||
gametype = gtype;
|
||||
gametyperules = gametypedefaultrules[gametype];
|
||||
}
|
||||
|
||||
//
|
||||
// G_AddGametype
|
||||
//
|
||||
// Add a gametype. Returns the new gametype number.
|
||||
//
|
||||
INT16 G_AddGametype(UINT32 rules)
|
||||
{
|
||||
INT16 newgtype = gametypecount;
|
||||
gametypecount++;
|
||||
|
||||
// Set gametype rules.
|
||||
gametypedefaultrules[newgtype] = rules;
|
||||
Gametype_Names[newgtype] = "???";
|
||||
|
||||
// Update gametype_cons_t accordingly.
|
||||
G_UpdateGametypeSelections();
|
||||
|
||||
return newgtype;
|
||||
}
|
||||
|
||||
//
|
||||
// G_AddGametypeConstant
|
||||
// G_PrepareGametypeConstant
|
||||
//
|
||||
// Self-explanatory. Filters out "bad" characters.
|
||||
//
|
||||
void G_AddGametypeConstant(INT16 gtype, const char *newgtconst)
|
||||
char *G_PrepareGametypeConstant(const char *newgtconst)
|
||||
{
|
||||
size_t r = 0; // read
|
||||
size_t w = 0; // write
|
||||
char *gtconst = Z_Calloc(strlen(newgtconst) + 4, PU_STATIC, NULL);
|
||||
char *tmpconst = Z_Calloc(strlen(newgtconst) + 1, PU_STATIC, NULL);
|
||||
size_t len = strlen(newgtconst);
|
||||
char *gtconst = Z_Calloc(len + 4, PU_STATIC, NULL);
|
||||
char *tmpconst = Z_Calloc(len + 1, PU_STATIC, NULL);
|
||||
|
||||
// Copy the gametype name.
|
||||
strcpy(tmpconst, newgtconst);
|
||||
|
|
@ -3932,7 +3944,7 @@ void G_AddGametypeConstant(INT16 gtype, const char *newgtconst)
|
|||
case ' ':
|
||||
case '@':
|
||||
case '?':
|
||||
// Used for operations
|
||||
// Used for operations
|
||||
case '+':
|
||||
case '-':
|
||||
case '*':
|
||||
|
|
@ -3941,7 +3953,7 @@ void G_AddGametypeConstant(INT16 gtype, const char *newgtconst)
|
|||
case '^':
|
||||
case '&':
|
||||
case '!':
|
||||
// Part of Lua's syntax
|
||||
// Part of Lua's syntax
|
||||
case '#':
|
||||
case '=':
|
||||
case '~':
|
||||
|
|
@ -3970,8 +3982,8 @@ void G_AddGametypeConstant(INT16 gtype, const char *newgtconst)
|
|||
// Free the temporary string.
|
||||
Z_Free(tmpconst);
|
||||
|
||||
// Finally, set the constant string.
|
||||
Gametype_ConstantNames[gtype] = gtconst;
|
||||
// Finally, return the constant string.
|
||||
return gtconst;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -3982,36 +3994,15 @@ void G_AddGametypeConstant(INT16 gtype, const char *newgtconst)
|
|||
void G_UpdateGametypeSelections(void)
|
||||
{
|
||||
INT32 i;
|
||||
for (i = 0; i < gametypecount; i++)
|
||||
for (i = 0; i < numgametypes; 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].strvalue = NULL;
|
||||
gametype_cons_t[numgametypes].value = 0;
|
||||
gametype_cons_t[numgametypes].strvalue = NULL;
|
||||
}
|
||||
|
||||
INT32 gametypecolor[NUMGAMETYPES] =
|
||||
{
|
||||
V_SKYMAP,
|
||||
V_REDMAP,
|
||||
};
|
||||
|
||||
// Gametype rankings
|
||||
INT16 gametyperankings[NUMGAMETYPES] =
|
||||
{
|
||||
GT_RACE,
|
||||
GT_BATTLE,
|
||||
};
|
||||
|
||||
// Gametype to TOL (Type Of Level)
|
||||
UINT32 gametypetol[NUMGAMETYPES] =
|
||||
{
|
||||
TOL_RACE, // Race
|
||||
TOL_BATTLE, // Battle
|
||||
TOL_TV, // Midnight Channel effect
|
||||
};
|
||||
|
||||
tolinfo_t TYPEOFLEVEL[NUMTOLNAMES] = {
|
||||
{"RACE",TOL_RACE},
|
||||
{"BATTLE",TOL_BATTLE},
|
||||
|
|
@ -4052,32 +4043,6 @@ void G_AddTOL(UINT32 newtol, const char *tolname)
|
|||
TYPEOFLEVEL[i].flag = newtol;
|
||||
}
|
||||
|
||||
//
|
||||
// G_AddGametypeTOL
|
||||
//
|
||||
// Assigns a type of level to a gametype.
|
||||
//
|
||||
void G_AddGametypeTOL(INT16 gtype, UINT32 newtol)
|
||||
{
|
||||
gametypetol[gtype] = newtol;
|
||||
}
|
||||
|
||||
//
|
||||
// G_GetGametypeByName
|
||||
//
|
||||
// Returns the number for the given gametype name string, or -1 if not valid.
|
||||
//
|
||||
INT32 G_GetGametypeByName(const char *gametypestr)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < gametypecount; i++)
|
||||
if (fasticmp(gametypestr, Gametype_Names[i]))
|
||||
return i;
|
||||
|
||||
return -1; // unknown gametype
|
||||
}
|
||||
|
||||
//
|
||||
// G_IsSpecialStage
|
||||
//
|
||||
|
|
@ -4168,7 +4133,7 @@ INT16 G_SometimesGetDifferentGametype(UINT8 prefgametype)
|
|||
// This is so a server CAN continue playing a gametype if they like the taste of it.
|
||||
// The encore check needs prefgametype so can't use G_RaceGametype...
|
||||
boolean encorepossible = ((M_SecretUnlocked(SECRET_ENCORE) || encorescramble == 1)
|
||||
&& ((gametyperules|gametypedefaultrules[prefgametype]) & GTR_CIRCUIT));
|
||||
&& (gametypes[prefgametype]->rules & GTR_CIRCUIT));
|
||||
UINT8 encoremodifier = 0;
|
||||
|
||||
// -- the below is only necessary if you want to use randmaps.mapbuffer here
|
||||
|
|
@ -4248,8 +4213,8 @@ UINT8 G_GetGametypeColor(INT16 gt)
|
|||
|| gamestate == GS_TIMEATTACK)
|
||||
return orangemap[0];
|
||||
|
||||
if (gametypecolor[gt])
|
||||
return *V_GetStringColormap(gametypecolor[gt]);
|
||||
if (gametypes[gt]->color)
|
||||
return *V_GetStringColormap(gametypes[gt]->color);
|
||||
|
||||
return yellowmap[0]; // FALLBACK
|
||||
}
|
||||
|
|
@ -4261,7 +4226,9 @@ UINT8 G_GetGametypeColor(INT16 gt)
|
|||
*/
|
||||
UINT32 G_TOLFlag(INT32 pgametype)
|
||||
{
|
||||
return gametypetol[pgametype];
|
||||
if (pgametype >= 0 && pgametype < numgametypes)
|
||||
return gametypes[pgametype]->tol;
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT16 G_GetFirstMapOfGametype(UINT8 pgametype)
|
||||
|
|
@ -4269,7 +4236,7 @@ INT16 G_GetFirstMapOfGametype(UINT8 pgametype)
|
|||
INT16 mapnum = NEXTMAP_INVALID;
|
||||
|
||||
/* G: not sure what to do with this
|
||||
if ((gametypedefaultrules[pgametype] & GTR_CAMPAIGN) && kartcupheaders)
|
||||
if ((gametypes[pgametype]->rules & GTR_CAMPAIGN) && kartcupheaders)
|
||||
{
|
||||
mapnum = kartcupheaders->cachedlevels[0];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -202,18 +202,11 @@ void G_SaveGame(UINT32 slot, INT16 mapnum);
|
|||
|
||||
void G_SaveGameOver(UINT32 slot, boolean modifylives);
|
||||
|
||||
extern UINT32 gametypedefaultrules[NUMGAMETYPES];
|
||||
extern UINT32 gametypetol[NUMGAMETYPES];
|
||||
extern INT32 gametypecolor[NUMGAMETYPES];
|
||||
extern INT16 gametyperankings[NUMGAMETYPES];
|
||||
|
||||
void G_SetGametype(INT16 gametype);
|
||||
INT16 G_AddGametype(UINT32 rules);
|
||||
void G_AddGametypeConstant(INT16 gtype, const char *newgtconst);
|
||||
char *G_PrepareGametypeConstant(const char *newgtconst);
|
||||
void G_UpdateGametypeSelections(void);
|
||||
void G_SetGametypeColor(INT16 gtype,INT32 color);
|
||||
void G_AddTOL(UINT32 newtol, const char *tolname);
|
||||
void G_AddGametypeTOL(INT16 gtype, UINT32 newtol);
|
||||
INT32 G_GetGametypeByName(const char *gametypestr);
|
||||
boolean G_IsSpecialStage(INT32 mapnum);
|
||||
boolean G_GametypeUsesLives(void);
|
||||
|
|
|
|||
|
|
@ -2527,8 +2527,8 @@ static void HU_DrawRankings(void)
|
|||
hilicol = V_ORANGEMAP;
|
||||
else
|
||||
{
|
||||
if (gametypecolor[gametype])
|
||||
hilicol = gametypecolor[gametype];
|
||||
if (gametypes[gametype]->color)
|
||||
hilicol = gametypes[gametype]->color;
|
||||
else
|
||||
hilicol = V_YELLOWMAP;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ void K_TimerInit(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
timelimitintics = timelimits[gametype] * (60*TICRATE);
|
||||
timelimitintics = gametypes[gametype]->timelimit * (60*TICRATE);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -3209,16 +3209,16 @@ static int lib_gAddGametype(lua_State *L)
|
|||
const char *k;
|
||||
lua_Integer i;
|
||||
|
||||
gametype_t *newgametype = NULL;
|
||||
|
||||
const char *gtname = NULL;
|
||||
const char *gtconst = NULL;
|
||||
INT16 newgtidx = 0;
|
||||
UINT32 newgtrules = 0;
|
||||
UINT32 newgttol = 0;
|
||||
INT32 newgtpointlimit = 0;
|
||||
INT32 newgttimelimit = 0;
|
||||
INT16 newgtrankingstype = -1;
|
||||
INT32 newgtcolor = V_YELLOWMAP;
|
||||
int newgtinttype = 0;
|
||||
UINT8 newgtinttype = 0;
|
||||
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
lua_settop(L, 1); // Clear out all other possible arguments, leaving only the first one.
|
||||
|
|
@ -3227,8 +3227,10 @@ static int lib_gAddGametype(lua_State *L)
|
|||
return luaL_error(L, "This function cannot be called from within a hook or coroutine!");
|
||||
|
||||
// Ran out of gametype slots
|
||||
if (gametypecount == NUMGAMETYPEFREESLOTS)
|
||||
return luaL_error(L, "Ran out of free gametype slots!");
|
||||
if (numgametypes == GT_LASTFREESLOT)
|
||||
{
|
||||
I_Error("Out of Gametype Freeslots while allocating \"%s\"\nLoad less addons to fix this.", gtname);
|
||||
}
|
||||
|
||||
#define FIELDERROR(f, e) luaL_error(L, "bad value for " LUA_QL(f) " in table passed to " LUA_QL("G_AddGametype") " (%s)", e);
|
||||
#define TYPEERROR(f, t) FIELDERROR(f, va("%s expected, got %s", lua_typename(L, t), luaL_typename(L, -1)))
|
||||
|
|
@ -3261,23 +3263,19 @@ static int lib_gAddGametype(lua_State *L)
|
|||
if (!lua_isnumber(L, 3))
|
||||
TYPEERROR("typeoflevel", LUA_TNUMBER)
|
||||
newgttol = (UINT32)lua_tointeger(L, 3);
|
||||
} else if (i == 5 || (k && fasticmp(k, "rankingtype"))) {
|
||||
if (!lua_isnumber(L, 3))
|
||||
TYPEERROR("rankingtype", LUA_TNUMBER)
|
||||
newgtrankingstype = (INT16)lua_tointeger(L, 3);
|
||||
} else if (i == 6 || (k && fasticmp(k, "intermissiontype"))) {
|
||||
} else if (i == 5 || (k && fasticmp(k, "intermissiontype"))) {
|
||||
if (!lua_isnumber(L, 3))
|
||||
TYPEERROR("intermissiontype", LUA_TNUMBER)
|
||||
newgtinttype = (int)lua_tointeger(L, 3);
|
||||
} else if (i == 7 || (k && fasticmp(k, "defaultpointlimit"))) {
|
||||
} else if (i == 6 || (k && fasticmp(k, "defaultpointlimit"))) {
|
||||
if (!lua_isnumber(L, 3))
|
||||
TYPEERROR("defaultpointlimit", LUA_TNUMBER)
|
||||
newgtpointlimit = (INT32)lua_tointeger(L, 3);
|
||||
} else if (i == 8 || (k && fasticmp(k, "defaulttimelimit"))) {
|
||||
} else if (i == 7 || (k && fasticmp(k, "defaulttimelimit"))) {
|
||||
if (!lua_isnumber(L, 3))
|
||||
TYPEERROR("defaulttimelimit", LUA_TNUMBER)
|
||||
newgttimelimit = (INT32)lua_tointeger(L, 3);
|
||||
} else if (i == 9 || (k && fasticmp(k, "menucolor"))) {
|
||||
} else if (i == 8 || (k && fasticmp(k, "menucolor"))) {
|
||||
if (!lua_isnumber(L, 3))
|
||||
TYPEERROR("menucolor", LUA_TNUMBER)
|
||||
{
|
||||
|
|
@ -3300,31 +3298,32 @@ static int lib_gAddGametype(lua_State *L)
|
|||
gtname = Z_StrDup("Unnamed gametype");
|
||||
|
||||
// Add the new gametype
|
||||
newgtidx = G_AddGametype(newgtrules);
|
||||
G_AddGametypeTOL(newgtidx, newgttol);
|
||||
|
||||
// Not covered by G_AddGametype alone.
|
||||
if (newgtrankingstype == -1)
|
||||
newgtrankingstype = newgtidx;
|
||||
gametyperankings[newgtidx] = newgtrankingstype;
|
||||
intermissiontypes[newgtidx] = newgtinttype;
|
||||
pointlimits[newgtidx] = newgtpointlimit;
|
||||
timelimits[newgtidx] = newgttimelimit;
|
||||
gametypecolor[newgtidx] = newgtcolor;
|
||||
|
||||
// Write the new gametype name.
|
||||
Gametype_Names[newgtidx] = gtname;
|
||||
newgametype = Z_Calloc(sizeof (gametype_t), PU_STATIC, NULL);
|
||||
if (!newgametype)
|
||||
{
|
||||
I_Error("Out of memory allocating gametype \"%s\"", gtname);
|
||||
}
|
||||
|
||||
// Write the constant name.
|
||||
if (gtconst == NULL)
|
||||
gtconst = gtname;
|
||||
G_AddGametypeConstant(newgtidx, gtconst);
|
||||
|
||||
newgametype->name = gtname;
|
||||
newgametype->rules = newgtrules;
|
||||
newgametype->constant = G_PrepareGametypeConstant(gtconst);
|
||||
newgametype->tol = newgttol;
|
||||
newgametype->intermission = newgtinttype;
|
||||
newgametype->pointlimit = newgtpointlimit;
|
||||
newgametype->timelimit = newgttimelimit;
|
||||
newgametype->color = newgtcolor;
|
||||
|
||||
gametypes[numgametypes++] = newgametype;
|
||||
|
||||
// Update gametype_cons_t accordingly.
|
||||
G_UpdateGametypeSelections();
|
||||
|
||||
// done
|
||||
CONS_Printf("Added gametype %s\n", Gametype_Names[newgtidx]);
|
||||
CONS_Printf("Added gametype %s\n", gtname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
10
src/m_menu.c
10
src/m_menu.c
|
|
@ -454,7 +454,7 @@ consvar_t cv_skinselectsort = CVAR_INIT ("skinselectsort", "Name", CV_SAVE|CV_CA
|
|||
|
||||
// This gametype list is integral for many different reasons.
|
||||
// When you add gametypes here, don't forget to update them in dehacked.c and doomstat.h!
|
||||
CV_PossibleValue_t gametype_cons_t[NUMGAMETYPES+1];
|
||||
CV_PossibleValue_t gametype_cons_t[MAXGAMETYPES+1];
|
||||
|
||||
consvar_t cv_newgametype = CVAR_INIT ("newgametype", "Race", CV_HIDEN|CV_CALL|CV_NOINIT, gametype_cons_t, Levelplatter_OnChange);
|
||||
|
||||
|
|
@ -613,19 +613,19 @@ inline static void M_GetGametypeColor(void)
|
|||
|
||||
if (gt == GT_BATTLE || levellistmode == LLM_BOSS)
|
||||
{
|
||||
highlightflags = gametypecolor[gt];
|
||||
highlightflags = gametypes[gt]->color;
|
||||
warningflags = V_ORANGEMAP;
|
||||
return;
|
||||
}
|
||||
if (gt == GT_RACE)
|
||||
{
|
||||
highlightflags = gametypecolor[gt];
|
||||
highlightflags = gametypes[gt]->color;
|
||||
return;
|
||||
}
|
||||
|
||||
if (gametypecolor[gt])
|
||||
if (gametypes[gt]->color)
|
||||
{
|
||||
highlightflags = gametypecolor[gt];
|
||||
highlightflags = gametypes[gt]->color;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8747,7 +8747,6 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
|
||||
// This is needed. Don't touch.
|
||||
maptol = mapheaderinfo[gamemap-1]->typeoflevel;
|
||||
gametyperules = gametypedefaultrules[gametype];
|
||||
|
||||
CON_Drawer(); // let the user know what we are going to do
|
||||
I_FinishUpdate(); // page flip or blit buffer
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ TYPEDEF (textpage_t);
|
|||
TYPEDEF (textprompt_t);
|
||||
TYPEDEF (mappoint_t);
|
||||
TYPEDEF (customoption_t);
|
||||
TYPEDEF (gametype_t);
|
||||
TYPEDEF (mapheader_t);
|
||||
TYPEDEF (tolinfo_t);
|
||||
TYPEDEF (cupheader_t);
|
||||
|
|
|
|||
|
|
@ -115,7 +115,6 @@ static INT32 listscroll_delay = 0;
|
|||
static fixed_t xscroll = 0;
|
||||
|
||||
intertype_t intertype = int_none;
|
||||
intertype_t intermissiontypes[NUMGAMETYPES];
|
||||
|
||||
static huddrawlist_h luahuddrawlist_intermission;
|
||||
static huddrawlist_h luahuddrawlist_vote;
|
||||
|
|
@ -464,8 +463,8 @@ void Y_IntermissionDrawer(void)
|
|||
hilicol = V_ORANGEMAP;
|
||||
else
|
||||
{
|
||||
if (gametypecolor[gametype])
|
||||
hilicol = gametypecolor[gametype];
|
||||
if (gametypes[gametype]->color)
|
||||
hilicol = gametypes[gametype]->color;
|
||||
else
|
||||
hilicol = V_YELLOWMAP;
|
||||
}
|
||||
|
|
@ -1052,12 +1051,11 @@ void Y_Ticker(void)
|
|||
//
|
||||
void Y_DetermineIntermissionType(void)
|
||||
{
|
||||
// set to int_none initially
|
||||
intertype = int_none;
|
||||
// set initially
|
||||
intertype = gametypes[gametype]->intermission;
|
||||
|
||||
if (gametype == GT_RACE)
|
||||
intertype = int_race;
|
||||
else if (gametype == GT_BATTLE)
|
||||
// TODO: special cases
|
||||
if (gametype == GT_BATTLE)
|
||||
{
|
||||
if (grandprixinfo.gp == true && bossinfo.boss == false)
|
||||
intertype = int_none;
|
||||
|
|
@ -1073,8 +1071,6 @@ void Y_DetermineIntermissionType(void)
|
|||
intertype = (nump < 2 ? int_battletime : int_battle);
|
||||
}
|
||||
}
|
||||
else //if (intermissiontypes[gametype] != int_none)
|
||||
intertype = intermissiontypes[gametype];
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -1132,9 +1128,6 @@ void Y_StartIntermission(void)
|
|||
sorttic = max((timer/2) - 2*TICRATE, 2*TICRATE);
|
||||
}
|
||||
|
||||
if (intermissiontypes[gametype] != int_none)
|
||||
intertype = intermissiontypes[gametype];
|
||||
|
||||
// We couldn't display the intermission even if we wanted to.
|
||||
// But we still need to give the players their score bonuses, dummy.
|
||||
//if (dedicated) return;
|
||||
|
|
@ -1808,8 +1801,8 @@ void Y_VoteDrawer(void)
|
|||
hilicol = cons_menuhighlight.value;
|
||||
else
|
||||
{
|
||||
if (gametypecolor[gametype])
|
||||
hilicol = gametypecolor[gametype];
|
||||
if (gametypes[gametype]->color)
|
||||
hilicol = gametypes[gametype]->color;
|
||||
else
|
||||
hilicol = V_YELLOWMAP;
|
||||
}
|
||||
|
|
@ -2231,7 +2224,7 @@ void Y_StartVote(void)
|
|||
// set up the gtc and gts
|
||||
levelinfo[i].gtc = G_GetGametypeColor(g_voteLevels[i][1]);
|
||||
if (i == 2 && g_voteLevels[i][1] != g_voteLevels[0][1])
|
||||
levelinfo[i].gts = gametype_cons_t[g_voteLevels[i][1]].strvalue;
|
||||
levelinfo[i].gts = gametypes[g_voteLevels[i][1]]->name;
|
||||
else
|
||||
levelinfo[i].gts = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ typedef enum
|
|||
} intertype_t;
|
||||
|
||||
extern intertype_t intertype;
|
||||
extern intertype_t intermissiontypes[NUMGAMETYPES];
|
||||
|
||||
// Votescreen stuff
|
||||
typedef struct
|
||||
|
|
|
|||
Loading…
Reference in a new issue