Cup definitions, updated menu to use them

This commit is contained in:
TehRealSalt 2019-10-04 22:44:19 -04:00
parent 94e8fddd46
commit 32bdd10dbf
7 changed files with 313 additions and 59 deletions

View file

@ -1397,6 +1397,100 @@ static void readlevelheader(MYFILE *f, INT32 num)
Z_Free(s); Z_Free(s);
} }
static void readcupheader(MYFILE *f, cupheader_t *cup)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
char *word;
char *word2;
char *tmp;
INT32 i;
do
{
if (myfgets(s, MAXLINELEN, f))
{
if (s[0] == '\n')
break;
// First remove trailing newline, if there is one
tmp = strchr(s, '\n');
if (tmp)
*tmp = '\0';
tmp = strchr(s, '#');
if (tmp)
*tmp = '\0';
if (s == tmp)
continue; // Skip comment lines, but don't break.
// Set / reset word, because some things (Lua.) move it
word = s;
// Get the part before the " = "
tmp = strchr(s, '=');
if (tmp)
*(tmp-1) = '\0';
else
break;
strupr(word);
// Now get the part after
word2 = tmp += 2;
i = atoi(word2); // used for numerical settings
strupr(word2);
if (fastcmp(word, "ICON"))
{
deh_strlcpy(cup->icon, word2,
sizeof(cup->icon), va("%s Cup: icon", cup->name));
}
else if (fastcmp(word, "LEVELLIST"))
{
cup->numlevels = 0;
tmp = strtok(word2,",");
do {
INT32 map = atoi(tmp);
if (tmp[0] >= 'A' && tmp[0] <= 'Z' && tmp[2] == '\0')
map = M_MapNumber(tmp[0], tmp[1]);
if (!map)
break;
if (cup->numlevels >= MAXLEVELLIST)
deh_warning("%s Cup: reached max levellist (%d)\n", cup->name, MAXLEVELLIST);
cup->levellist[cup->numlevels] = map;
cup->numlevels++;
} while((tmp = strtok(NULL,",")) != NULL);
}
else if (fastcmp(word, "BONUSGAME"))
{
// Convert to map number
if (word2[0] >= 'A' && word2[0] <= 'Z' && word2[2] == '\0')
i = M_MapNumber(word2[0], word2[1]);
cup->bonusgame = (INT16)i;
}
else if (fastcmp(word, "SPECIALSTAGE"))
{
// Convert to map number
if (word2[0] >= 'A' && word2[0] <= 'Z' && word2[2] == '\0')
i = M_MapNumber(word2[0], word2[1]);
cup->specialstage = (INT16)i;
}
else if (fastcmp(word, "EMERALDNUM"))
{
cup->emeraldnum = (INT16)i;
}
else
deh_warning("%s Cup: unknown word '%s'", cup->name, word);
}
} while (!myfeof(f)); // finish when the line is empty
Z_Free(s);
}
static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum)
{ {
char *s = Z_Calloc(MAXLINELEN, PU_STATIC, NULL); char *s = Z_Calloc(MAXLINELEN, PU_STATIC, NULL);
@ -3558,6 +3652,42 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
} }
DEH_WriteUndoline(word, word2, UNDO_HEADER); DEH_WriteUndoline(word, word2, UNDO_HEADER);
} }
else if (fastcmp(word, "CUP"))
{
cupheader_t *cup = kartcupheaders;
cupheader_t *prev = NULL;
while (cup)
{
if (fastcmp(cup->name, word2))
{
// mark as a major mod if it replaces an already-existing cup
G_SetGameModified(multiplayer, true);
break;
}
prev = cup;
cup = cup->next;
}
// Nothing found, add to the end.
if (!cup)
{
cup = Z_Calloc(sizeof (cupheader_t), PU_STATIC, NULL);
cup->id = numkartcupheaders;
deh_strlcpy(cup->name, word2,
sizeof(cup->name), va("Cup header %s: name", word2));
if (prev != NULL)
prev->next = cup;
if (kartcupheaders == NULL)
kartcupheaders = cup;
numkartcupheaders++;
CONS_Printf("Added cup %d ('%s')\n", cup->id, cup->name);
}
readcupheader(f, cup);
DEH_WriteUndoline(word, word2, UNDO_HEADER);
}
else if (fastcmp(word, "CUTSCENE")) else if (fastcmp(word, "CUTSCENE"))
{ {
if (i > 0 && i < 129) if (i > 0 && i < 129)

View file

@ -291,6 +291,24 @@ typedef struct
extern mapheader_t* mapheaderinfo[NUMMAPS]; extern mapheader_t* mapheaderinfo[NUMMAPS];
#define MAXLEVELLIST 5
typedef struct cupheader_s
{
UINT16 id; ///< Cup ID
char name[15]; ///< Cup title (14 chars)
char icon[9]; ///< Name of the icon patch
INT16 levellist[MAXLEVELLIST]; ///< List of levels that belong to this cup
UINT8 numlevels; ///< Number of levels defined in levellist
INT16 bonusgame; ///< Map number to use for bonus game
INT16 specialstage; ///< Map number to use for special stage
UINT8 emeraldnum; ///< ID of Emerald to use for special stage (1-7 for Chaos Emeralds, 8-14 for Super Emeralds, 0 for no emerald)
struct cupheader_s *next; ///< Next cup in linked list
} cupheader_t;
extern cupheader_t *kartcupheaders; // Start of cup linked list
extern UINT16 numkartcupheaders;
enum TypeOfLevel enum TypeOfLevel
{ {
TOL_SP = 0x01, ///< Single Player TOL_SP = 0x01, ///< Single Player

View file

@ -153,6 +153,10 @@ struct quake quake;
// Map Header Information // Map Header Information
mapheader_t* mapheaderinfo[NUMMAPS] = {NULL}; mapheader_t* mapheaderinfo[NUMMAPS] = {NULL};
// Kart cup definitions
cupheader_t *kartcupheaders = NULL;
UINT16 numkartcupheaders = 0;
static boolean exitgame = false; static boolean exitgame = false;
static boolean retrying = false; static boolean retrying = false;

View file

@ -292,26 +292,33 @@ boolean M_CharacterSelectQuit(void);
#define CUPS_MAX (NUMMAPS / CUPS_MAPSPERCUP) #define CUPS_MAX (NUMMAPS / CUPS_MAPSPERCUP)
#define CUPS_PAGES (CUPS_MAX / (CUPS_COLUMNS * CUPS_ROWS)) #define CUPS_PAGES (CUPS_MAX / (CUPS_COLUMNS * CUPS_ROWS))
#define CUPID (levellist_cupgrid.x + (levellist_cupgrid.y * CUPS_COLUMNS))
extern cupheader_t *selectedcup;
extern INT16 selectedcupnum;
extern struct levellist_cupgrid_s { extern struct levellist_cupgrid_s {
UINT8 numcups; UINT8 numcups;
SINT8 x, y; SINT8 x, y;
SINT8 pageno; SINT8 pageno;
tic_t previewanim; tic_t previewanim;
boolean grandprix; // Setup grand prix server after picking
} levellist_cupgrid; } levellist_cupgrid;
extern struct levellist_scroll_s { extern struct levellist_scroll_s {
SINT8 cupid;
SINT8 cursor; SINT8 cursor;
UINT16 y; UINT16 y;
UINT16 dest; UINT16 dest;
boolean timeattack; // Setup time attack menu after picking
} levellist_scroll; } levellist_scroll;
boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt); boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
void M_LevelSelectInit(INT32 choice); INT32 M_CountLevelsToShowInList(INT32 gt);
INT32 M_GetFirstLevelInList(INT32 gt);
void M_LevelSelectInit(INT32 choice);
void M_CupSelectHandler(INT32 choice); void M_CupSelectHandler(INT32 choice);
void M_CupSelectTick(void); void M_CupSelectTick(void);
void M_LevelSelectHandler(INT32 choice); void M_LevelSelectHandler(INT32 choice);
void M_LevelSelectTick(void); void M_LevelSelectTick(void);

View file

@ -85,13 +85,13 @@ menu_t PLAY_GamemodesDef = KARTGAMEMODEMENU(PLAY_GamemodesMenu, &PLAY_MainDef);
menuitem_t PLAY_RaceGamemodesMenu[] = menuitem_t PLAY_RaceGamemodesMenu[] =
{ {
{IT_STRING | IT_CALL, "Grand Prix", "Compete for the best rank over five races!", {IT_STRING | IT_CALL, "Grand Prix", "Compete for the best rank over five races!",
NULL, M_LevelSelectInit, 0, 0}, NULL, M_LevelSelectInit, 2, GT_RACE},
{IT_STRING | IT_CALL, "Match Race", "Play by your own rules in a specialized, single race!", {IT_STRING | IT_CALL, "Match Race", "Play by your own rules in a specialized, single race!",
NULL, M_LevelSelectInit, 1, 0}, NULL, M_LevelSelectInit, 0, GT_RACE},
{IT_STRING | IT_CALL, "Time Attack", "Record your best time on any track!", {IT_STRING | IT_CALL, "Time Attack", "Record your best time on any track!",
NULL, M_LevelSelectInit, 2, 0}, NULL, M_LevelSelectInit, 1, GT_RACE},
{IT_STRING | IT_CALL, "Back", NULL, NULL, M_GoBack, 0, 0}, {IT_STRING | IT_CALL, "Back", NULL, NULL, M_GoBack, 0, 0},
}; };
@ -157,10 +157,10 @@ menu_t PLAY_TimeAttackDef = {
menuitem_t PLAY_BattleGamemodesMenu[] = menuitem_t PLAY_BattleGamemodesMenu[] =
{ {
{IT_STRING | IT_CALL, "Survival", "It's last hedgehog standing in this free-for-all!", {IT_STRING | IT_CALL, "Survival", "It's last hedgehog standing in this free-for-all!",
NULL, M_LevelSelectInit, 3, 0}, NULL, M_LevelSelectInit, 0, GT_MATCH},
{IT_STRING | IT_CALL, "Time Attack", "Bust up all of the capsules in record time!", {IT_STRING | IT_CALL, "Time Attack", "Bust up all of the capsules in record time!",
NULL, M_LevelSelectInit, 4, 0}, NULL, M_LevelSelectInit, 1, GT_MATCH},
{IT_STRING | IT_CALL, "Back", NULL, NULL, M_GoBack, 0, 0}, {IT_STRING | IT_CALL, "Back", NULL, NULL, M_GoBack, 0, 0},
}; };

View file

@ -875,20 +875,18 @@ void M_DrawCharacterSelect(void)
// LEVEL SELECT // LEVEL SELECT
static void M_DrawCupPreview(INT16 y, UINT8 cupnum) static void M_DrawCupPreview(INT16 y, cupheader_t *cup)
{ {
UINT8 i; UINT8 i;
INT16 x = -(levellist_cupgrid.previewanim % 82); INT16 x = -(levellist_cupgrid.previewanim % 82);
V_DrawFill(0, y, BASEVIDWIDTH, 54, 31); for (i = 0; i < cup->numlevels; i++)
for (i = 0; i < 5; i++)
{ {
lumpnum_t lumpnum; lumpnum_t lumpnum;
patch_t *PictureOfLevel; patch_t *PictureOfLevel;
UINT8 lvloff = (i + (levellist_cupgrid.previewanim / 82)) % 5; UINT8 lvloff = (i + (levellist_cupgrid.previewanim / 82)) % cup->numlevels;
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(1 + (cupnum * 5) + lvloff))); lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cup->levellist[lvloff] )));
if (lumpnum != LUMPERROR) if (lumpnum != LUMPERROR)
PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE); PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE);
else else
@ -901,6 +899,14 @@ static void M_DrawCupPreview(INT16 y, UINT8 cupnum)
void M_DrawCupSelect(void) void M_DrawCupSelect(void)
{ {
UINT8 i, j; UINT8 i, j;
cupheader_t *cup = kartcupheaders;
while (cup)
{
if (cup->id == CUPID)
break;
cup = cup->next;
}
for (i = 0; i < CUPS_COLUMNS; i++) for (i = 0; i < CUPS_COLUMNS; i++)
{ {
@ -915,10 +921,14 @@ void M_DrawCupSelect(void)
0, W_CachePatchName("CUPCURS", PU_CACHE) 0, W_CachePatchName("CUPCURS", PU_CACHE)
); );
V_DrawFill(0, 146 + (12*menutransition.tics), BASEVIDWIDTH, 54, 31);
V_DrawScaledPatch(0, 120 - (12*menutransition.tics), 0, W_CachePatchName("MENUHINT", PU_CACHE)); V_DrawScaledPatch(0, 120 - (12*menutransition.tics), 0, W_CachePatchName("MENUHINT", PU_CACHE));
M_DrawCupPreview(146 + (12*menutransition.tics), levellist_cupgrid.x + (levellist_cupgrid.y * CUPS_COLUMNS));
V_DrawCenteredLSTitleLowString(BASEVIDWIDTH/2, 126 - (12*menutransition.tics), 0, "SNEAKER CUP"); if (cup)
{
M_DrawCupPreview(146 + (12*menutransition.tics), cup);
V_DrawCenteredLSTitleLowString(BASEVIDWIDTH/2, 126 - (12*menutransition.tics), 0, va("%s Cup", cup->name));
}
} }
static void M_DrawHighLowLevelTitle(INT16 x, INT16 y, INT16 map) static void M_DrawHighLowLevelTitle(INT16 x, INT16 y, INT16 map)
@ -930,7 +940,7 @@ static void M_DrawHighLowLevelTitle(INT16 x, INT16 y, INT16 map)
INT16 x2 = x; INT16 x2 = x;
UINT8 i; UINT8 i;
if (!mapheaderinfo[map]->lvlttl[0]) if (!mapheaderinfo[map] || !mapheaderinfo[map]->lvlttl[0])
return; return;
if (mapheaderinfo[map]->zonttl[0]) if (mapheaderinfo[map]->zonttl[0])
@ -1035,7 +1045,8 @@ static void M_DrawLevelSelectBlock(INT16 x, INT16 y, INT16 map, boolean redblink
void M_DrawLevelSelect(void) void M_DrawLevelSelect(void)
{ {
UINT8 i; INT16 i;
INT16 start = M_GetFirstLevelInList(cv_newgametype.value)-1;
INT16 t = (32*menutransition.tics), tay = 0; INT16 t = (32*menutransition.tics), tay = 0;
INT16 y = 80 - (12 * levellist_scroll.y); INT16 y = 80 - (12 * levellist_scroll.y);
boolean tatransition = (menutransition.startmenu == &PLAY_TimeAttackDef || menutransition.endmenu == &PLAY_TimeAttackDef); boolean tatransition = (menutransition.startmenu == &PLAY_TimeAttackDef || menutransition.endmenu == &PLAY_TimeAttackDef);
@ -1046,10 +1057,16 @@ void M_DrawLevelSelect(void)
tay = t/2; tay = t/2;
} }
for (i = 0; i < 5; i++) for (i = 0; i < M_CountLevelsToShowInList(cv_newgametype.value); i++)
{ {
INT16 map = 1 + (levellist_scroll.cupid * 5) + i;
INT16 lvlx = t, lvly = y; INT16 lvlx = t, lvly = y;
INT16 map = start + i;
while (!M_CanShowLevelInList(map, cv_newgametype.value) && map < NUMMAPS)
map++;
if (map >= NUMMAPS)
break;
if (i == levellist_scroll.cursor && tatransition) if (i == levellist_scroll.cursor && tatransition)
{ {
@ -1066,7 +1083,10 @@ void M_DrawLevelSelect(void)
} }
V_DrawScaledPatch(0, tay, 0, W_CachePatchName("MENUHINT", PU_CACHE)); V_DrawScaledPatch(0, tay, 0, W_CachePatchName("MENUHINT", PU_CACHE));
V_DrawCenteredLSTitleLowString(BASEVIDWIDTH/2, 6+tay, 0, "SNEAKER CUP"); if (selectedcup)
V_DrawCenteredLSTitleLowString(BASEVIDWIDTH/2, 6+tay, 0, va("%s Cup", selectedcup->name));
else
V_DrawCenteredLSTitleLowString(BASEVIDWIDTH/2, 6+tay, 0, va("%s Mode", Gametype_Names[cv_newgametype.value]));
} }
void M_DrawTimeAttack(void) void M_DrawTimeAttack(void)

View file

@ -2017,16 +2017,6 @@ boolean M_CharacterSelectQuit(void)
// LEVEL SELECT // LEVEL SELECT
#if 0
// Call before showing any level-select menus
static void M_PrepareLevelSelect(void)
{
if (levellistmode != LLM_CREATESERVER)
CV_SetValue(&cv_nextmap, M_GetFirstLevelInList());
else
Newgametype_OnChange(); // Make sure to start on an appropriate map if wads have been added
}
// //
// M_CanShowLevelInList // M_CanShowLevelInList
// //
@ -2055,10 +2045,17 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt)
if (gt == GT_RACE && (mapheaderinfo[mapnum]->typeoflevel & TOL_RACE)) if (gt == GT_RACE && (mapheaderinfo[mapnum]->typeoflevel & TOL_RACE))
{ {
if (levellist_cup != -1) if (selectedcup && selectedcup->numlevels)
{ {
if (mapnum < (1 + ((levellist_cup-1) * 5)) UINT8 i;
|| mapnum > (6 + ((levellist_cup-1) * 5))
for (i = 0; i < selectedcup->numlevels; i++)
{
if (mapnum == selectedcup->levellist[i])
break;
}
if (i == selectedcup->numlevels)
return false; return false;
} }
@ -2069,75 +2066,95 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt)
return false; return false;
} }
static INT32 M_CountLevelsToShowInList(void) INT32 M_CountLevelsToShowInList(INT32 gt)
{ {
INT32 mapnum, count = 0; INT32 mapnum, count = 0;
for (mapnum = 0; mapnum < NUMMAPS; mapnum++) for (mapnum = 0; mapnum < NUMMAPS; mapnum++)
if (M_CanShowLevelInList(mapnum, -1)) if (M_CanShowLevelInList(mapnum, gt))
count++; count++;
return count; return count;
} }
static INT32 M_GetFirstLevelInList(void) INT32 M_GetFirstLevelInList(INT32 gt)
{ {
INT32 mapnum; INT32 mapnum;
for (mapnum = 0; mapnum < NUMMAPS; mapnum++) for (mapnum = 0; mapnum < NUMMAPS; mapnum++)
if (M_CanShowLevelInList(mapnum, -1)) if (M_CanShowLevelInList(mapnum, gt))
return mapnum + 1; return mapnum + 1;
return 1; return 1;
} }
#endif
cupheader_t *selectedcup = NULL;
struct levellist_cupgrid_s levellist_cupgrid; struct levellist_cupgrid_s levellist_cupgrid;
struct levellist_scroll_s levellist_scroll; struct levellist_scroll_s levellist_scroll;
static void M_LevelSelectScrollDest(void) static void M_LevelSelectScrollDest(void)
{ {
UINT16 m = M_CountLevelsToShowInList(cv_newgametype.value)-1;
levellist_scroll.dest = (6*levellist_scroll.cursor); levellist_scroll.dest = (6*levellist_scroll.cursor);
if (levellist_scroll.dest < 3) if (levellist_scroll.dest < 3)
levellist_scroll.dest = 3; levellist_scroll.dest = 3;
if (levellist_scroll.dest > (6*4)-3) if (levellist_scroll.dest > (6*m)-3)
levellist_scroll.dest = (6*4)-3; levellist_scroll.dest = (6*m)-3;
} }
void M_LevelSelectInit(INT32 choice) void M_LevelSelectInit(INT32 choice)
{ {
UINT8 selecttype = currentMenu->menuitems[itemOn].mvar1;
(void)choice; (void)choice;
switch (selecttype) switch (currentMenu->menuitems[itemOn].mvar1)
{ {
case 0:
levellist_cupgrid.grandprix = false;
levellist_scroll.timeattack = false;
break;
case 1:
levellist_cupgrid.grandprix = false;
levellist_scroll.timeattack = true;
break;
case 2: case 2:
CV_StealthSetValue(&cv_newgametype, GT_RACE); levellist_cupgrid.grandprix = true;
levellist_scroll.timeattack = false;
break; break;
default: default:
break; CONS_Alert(CONS_WARNING, "Bad level select init\n");
return;
} }
CV_StealthSetValue(&cv_newgametype, currentMenu->menuitems[itemOn].mvar2);
PLAY_CupSelectDef.prevMenu = currentMenu; PLAY_CupSelectDef.prevMenu = currentMenu;
if (cv_newgametype.value != GT_RACE) if (cv_newgametype.value == GT_RACE)
{
PLAY_LevelSelectDef.prevMenu = currentMenu;
M_SetupNextMenu(&PLAY_LevelSelectDef, false);
}
else
{ {
PLAY_LevelSelectDef.prevMenu = &PLAY_CupSelectDef; PLAY_LevelSelectDef.prevMenu = &PLAY_CupSelectDef;
M_SetupNextMenu(&PLAY_CupSelectDef, false); M_SetupNextMenu(&PLAY_CupSelectDef, false);
} }
else
{
selectedcup = NULL;
PLAY_LevelSelectDef.prevMenu = currentMenu;
M_SetupNextMenu(&PLAY_LevelSelectDef, false);
}
} }
void M_CupSelectHandler(INT32 choice) void M_CupSelectHandler(INT32 choice)
{ {
UINT8 selcup = levellist_cupgrid.x + (levellist_cupgrid.y * CUPS_COLUMNS); cupheader_t *newcup = kartcupheaders;
while (newcup)
{
CONS_Printf("%d == %d?\n", newcup->id, CUPID);
if (newcup->id == CUPID)
break;
newcup = newcup->next;
}
switch (choice) switch (choice)
{ {
@ -2178,10 +2195,13 @@ void M_CupSelectHandler(INT32 choice)
S_StartSound(NULL, sfx_s3k5b); S_StartSound(NULL, sfx_s3k5b);
break; break;
case KEY_ENTER: case KEY_ENTER:
if (levellist_scroll.cupid != selcup) // Keep cursor position if you select the same cup again if (!newcup)
break;
if (!selectedcup || newcup->id != selectedcup->id) // Keep cursor position if you select the same cup again
{ {
levellist_scroll.cursor = 0; levellist_scroll.cursor = 0;
levellist_scroll.cupid = selcup; selectedcup = newcup;
} }
M_LevelSelectScrollDest(); M_LevelSelectScrollDest();
@ -2208,6 +2228,10 @@ void M_CupSelectTick(void)
void M_LevelSelectHandler(INT32 choice) void M_LevelSelectHandler(INT32 choice)
{ {
INT16 start = M_GetFirstLevelInList(cv_newgametype.value)-1;
INT16 maxlevels = M_CountLevelsToShowInList(cv_newgametype.value);
INT16 map = start;
if (levellist_scroll.y != levellist_scroll.dest) if (levellist_scroll.y != levellist_scroll.dest)
return; return;
@ -2216,18 +2240,69 @@ void M_LevelSelectHandler(INT32 choice)
case KEY_UPARROW: case KEY_UPARROW:
levellist_scroll.cursor--; levellist_scroll.cursor--;
if (levellist_scroll.cursor < 0) if (levellist_scroll.cursor < 0)
levellist_scroll.cursor = 4; levellist_scroll.cursor = maxlevels-1;
S_StartSound(NULL, sfx_s3k5b); S_StartSound(NULL, sfx_s3k5b);
break; break;
case KEY_DOWNARROW: case KEY_DOWNARROW:
levellist_scroll.cursor++; levellist_scroll.cursor++;
if (levellist_scroll.cursor > 4) if (levellist_scroll.cursor >= maxlevels)
levellist_scroll.cursor = 0; levellist_scroll.cursor = 0;
S_StartSound(NULL, sfx_s3k5b); S_StartSound(NULL, sfx_s3k5b);
break; break;
case KEY_ENTER: case KEY_ENTER:
CV_SetValue(&cv_nextmap, 1 + (levellist_scroll.cupid * 5) + levellist_scroll.cursor); map = start + levellist_scroll.cursor;
M_SetupNextMenu(&PLAY_TimeAttackDef, false);
while (!M_CanShowLevelInList(map, cv_newgametype.value) && map < NUMMAPS)
map++;
if (map >= NUMMAPS)
break;
CV_SetValue(&cv_nextmap, map);
if (levellist_scroll.timeattack)
M_SetupNextMenu(&PLAY_TimeAttackDef, false);
else
{
UINT8 ssplayers = cv_splitplayers.value-1;
netgame = false;
multiplayer = true;
strncpy(connectedservername, cv_servername.string, MAXSERVERNAME);
// Still need to reset devmode
cv_debug = 0;
if (strlen(cv_dummyjoinpassword.string) > 0)
D_SetJoinPassword(cv_dummyjoinpassword.string);
else
joinpasswordset = false;
if (demo.playback)
G_StopDemo();
if (metalrecording)
G_StopMetalDemo();
if (!cv_nextmap.value)
CV_SetValue(&cv_nextmap, G_RandMap(G_TOLFlag(cv_newgametype.value), -1, false, 0, false, NULL)+1);
if (cv_maxplayers.value < ssplayers+1)
CV_SetValue(&cv_maxplayers, ssplayers+1);
if (splitscreen != ssplayers)
{
splitscreen = ssplayers;
SplitScreen_OnChange();
}
paused = false;
SV_StartSinglePlayerServer();
multiplayer = true; // yeah, SV_StartSinglePlayerServer clobbers this...
D_MapChange(cv_nextmap.value, cv_newgametype.value, (cv_kartencore.value == 1), 1, 1, false, false);
M_ClearMenus(true);
}
S_StartSound(NULL, sfx_s3k63); S_StartSound(NULL, sfx_s3k63);
break; break;
case KEY_ESCAPE: case KEY_ESCAPE: