Difficulty select before GP, match race & netgames

This commit is contained in:
SinnamonLat 2021-12-11 18:22:56 +01:00
parent 841649c7ea
commit cdb3b1ca98
4 changed files with 291 additions and 9 deletions

View file

@ -174,6 +174,9 @@ extern menu_t PLAY_GamemodesDef;
extern menuitem_t PLAY_RaceGamemodesMenu[];
extern menu_t PLAY_RaceGamemodesDef;
extern menuitem_t PLAY_RaceDifficulty[];
extern menu_t PLAY_RaceDifficultyDef;
extern menuitem_t PLAY_CupSelect[];
extern menu_t PLAY_CupSelectDef;
@ -478,6 +481,16 @@ void M_CupSelectTick(void);
void M_LevelSelectHandler(INT32 choice);
void M_LevelSelectTick(void);
// dummy consvars for GP & match race setup
extern consvar_t cv_dummygpdifficulty;
extern consvar_t cv_dummykartspeed;
extern consvar_t cv_dummygpencore;
extern consvar_t cv_dummymatchbots;
void M_SetupDifficultySelect(INT32 choice);
void M_SetupDifficultySelectMP(INT32 choice);
void M_DifficultySelectInputs(INT32 choice);
// Multiplayer menu stuff
// Keep track of multiplayer menu related data
@ -692,6 +705,8 @@ void M_DrawCupSelect(void);
void M_DrawLevelSelect(void);
void M_DrawTimeAttack(void);
void M_DrawRaceDifficulty(void);
// Multiplayer menu stuff
void M_DrawMPOptSelect(void);
void M_DrawMPHost(void);

View file

@ -100,10 +100,10 @@ menu_t PLAY_GamemodesDef = KARTGAMEMODEMENU(PLAY_GamemodesMenu, &PLAY_MainDef);
menuitem_t PLAY_RaceGamemodesMenu[] =
{
{IT_STRING | IT_CALL, "Grand Prix", "Compete for the best rank over five races!",
NULL, M_LevelSelectInit, 2, GT_RACE},
NULL, M_SetupDifficultySelect, 0, 0},
{IT_STRING | IT_CALL, "Match Race", "Play by your own rules in a specialized, single race!",
"MENIMG01", M_LevelSelectInit, 0, GT_RACE},
"MENIMG01", M_SetupDifficultySelect, 1, 0},
{IT_STRING | IT_CALL, "Time Attack", "Record your best time on any track!",
NULL, M_LevelSelectInit, 1, GT_RACE},
@ -113,6 +113,52 @@ menuitem_t PLAY_RaceGamemodesMenu[] =
menu_t PLAY_RaceGamemodesDef = KARTGAMEMODEMENU(PLAY_RaceGamemodesMenu, &PLAY_GamemodesDef);
// difficulty selection:
menuitem_t PLAY_RaceDifficulty[] =
{
// local play
{IT_STRING | IT_CVAR, "Difficulty", "Select the game difficulty",
NULL, &cv_dummygpdifficulty, 0, 0},
// netgames
{IT_STRING | IT_CVAR, "Difficulty", "Select the game speed",
NULL, &cv_dummykartspeed, 0, 0},
// DISABLE THAT OPTION OUTSIDE OF MATCH RACE
{IT_STRING2 | IT_CVAR, "CPU Players", "Enable or disable CPU players.", // 2 whitestring is used by the drawer to know to draw shitstring
NULL, &cv_dummymatchbots, 0, 0},
{IT_STRING2 | IT_CVAR, "Encore", "Enable or disable Encore mode", // 3
NULL, &cv_dummygpencore, 0, 0},
// For GP:
{IT_STRING | IT_CALL, "Cup Select", "Go on and select a cup!", NULL, M_LevelSelectInit, 2, GT_RACE}, // 4
// For Match Race:
{IT_STRING | IT_CALL, "Map Select", "Go on and select a race track!", NULL, M_LevelSelectInit, 0, GT_RACE}, // 5
// For Match Race in NETGAMES:
{IT_STRING | IT_CALL, "Map Select", "Go on and select a race track!", NULL, M_MPSetupNetgameMapSelect, 0, GT_RACE}, // 6
{IT_STRING | IT_CALL, "Back", NULL, NULL, M_GoBack, 0, 0},
};
menu_t PLAY_RaceDifficultyDef = {
sizeof(PLAY_RaceDifficulty) / sizeof(menuitem_t),
&PLAY_RaceGamemodesDef,
0,
PLAY_RaceDifficulty,
0, 0,
0, 0,
1, 10,
M_DrawRaceDifficulty,
NULL,
NULL,
NULL
};
menuitem_t PLAY_CupSelect[] =
{
{IT_NOTHING | IT_KEYHANDLER, NULL, NULL, NULL, M_CupSelectHandler, 0, 0},
@ -234,7 +280,7 @@ menuitem_t PLAY_MP_Host[] =
NULL, &cv_dummygametype, 0, 0},
{IT_STRING | IT_CALL, "GO", "Select a map with the currently selected gamemode",
NULL, M_MPSetupNetgameMapSelect, 0, 0},
NULL, M_SetupDifficultySelectMP, 0, 0},
};

View file

@ -1020,6 +1020,135 @@ void M_DrawCharacterSelect(void)
M_DrawCharSelectCursor(priority);
}
// DIFFICULTY SELECT
// This is a mix of K_DrawKartGamemodeMenu and the generic menu drawer depending on what we need.
// This is only ever used here (I hope because this is starting to pile up on hacks to look like the old m_menu.c lol...)
void M_DrawRaceDifficulty(void)
{
UINT8 n = currentMenu->numitems-4;
patch_t *box = W_CachePatchName("M_DBOX", PU_CACHE);
INT32 i;
INT32 x = 120;
INT32 y = 48;
M_DrawMenuTooltips();
// Draw the box for difficulty...
V_DrawFixedPatch((111 + 24*menutransition.tics)*FRACUNIT, 33*FRACUNIT, FRACUNIT, 0, box, NULL);
if (menutransition.tics)
{
x += 24 * menutransition.tics;
}
for (i = 0; i < currentMenu->numitems; i++)
{
if (i >= n)
{
x = GM_STARTX + (GM_XOFFSET * 5 / 2);
y = GM_STARTY + (GM_YOFFSET * 5 / 2);
if (i < currentMenu->numitems-1)
{
x -= GM_XOFFSET;
y -= GM_YOFFSET;
}
if (menutransition.tics)
{
x += 24 * menutransition.tics;
}
}
switch (currentMenu->menuitems[i].status & IT_DISPLAY)
{
// This is HACKY......
case IT_STRING2:
{
INT32 f = (i == itemOn) ? highlightflags : 0;
V_DrawString(140 + 24*menutransition.tics, y, f, currentMenu->menuitems[i].text);
if (currentMenu->menuitems[i].status & IT_CVAR)
{
// implicitely we'll only take care of normal cvars
INT32 cx = 260 + 24*menutransition.tics;
consvar_t *cv = (consvar_t *)currentMenu->menuitems[i].itemaction;
V_DrawCenteredString(cx, y, f, cv->string);
if (i == itemOn)
{
INT32 w = V_StringWidth(cv->string, 0)/2;
V_DrawCharacter(cx - 10 - w - (skullAnimCounter/5), y, '\x1C' | highlightflags, false); // left arrow
V_DrawCharacter(cx + w + 2 + (skullAnimCounter/5), y, '\x1D' | highlightflags, false); // right arrow
}
}
y += 12;
break;
}
case IT_STRING:
{
UINT8 *colormap = NULL;
if (i == itemOn)
{
colormap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PLAGUE, GTC_CACHE);
}
else
{
colormap = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_MOSS, GTC_CACHE);
}
if (currentMenu->menuitems[i].status & IT_CVAR)
{
INT32 fx = (x - 24*menutransition.tics);
INT32 centx = fx + (320-fx)/2 + (menutransition.tics*24); // undo the menutransition movement to redo it here otherwise the text won't move at the same speed lole.
// implicitely we'll only take care of normal consvars
consvar_t *cv = (consvar_t *)currentMenu->menuitems[i].itemaction;
V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT, 0, W_CachePatchName("MENUSHRT", PU_CACHE), colormap);
V_DrawCenteredGamemodeString(centx, y - 3, V_ALLOWLOWERCASE, colormap, cv->string);
if (i == itemOn)
{
patch_t *arr_r = W_CachePatchName("GM_ARRL", PU_CACHE);
patch_t *arr_l = W_CachePatchName("GM_ARRR", PU_CACHE);
V_DrawFixedPatch((centx-54 - arr_r->width - (skullAnimCounter/5))*FRACUNIT, (y-3)*FRACUNIT, FRACUNIT, 0, arr_r, colormap);
V_DrawFixedPatch((centx+54 + (skullAnimCounter/5))*FRACUNIT, (y-3)*FRACUNIT, FRACUNIT, 0, arr_l, colormap);
}
}
else // not a cvar
{
V_DrawFixedPatch(x*FRACUNIT, y*FRACUNIT, FRACUNIT, 0, W_CachePatchName("MENUPLTR", PU_CACHE), colormap);
V_DrawGamemodeString(x + 16, y - 3, V_ALLOWLOWERCASE, colormap, currentMenu->menuitems[i].text);
}
x += GM_XOFFSET;
y += GM_YOFFSET;
break;
}
}
}
}
// LEVEL SELECT
static void M_DrawCupPreview(INT16 y, cupheader_t *cup)

View file

@ -166,6 +166,9 @@ static CV_PossibleValue_t dummyscramble_cons_t[] = {{0, "Random"}, {1, "Points"}
static CV_PossibleValue_t dummystaff_cons_t[] = {{0, "MIN"}, {100, "MAX"}, {0, NULL}};
static CV_PossibleValue_t dummygametype_cons_t[] = {{0, "Race"}, {1, "Battle"}, {0, NULL}};
static CV_PossibleValue_t dummygpdifficulty_cons_t[] = {{0, "Easy"}, {1, "Normal"}, {2, "Hard"}, {3, "Master"}, {0, NULL}};
static CV_PossibleValue_t dummykartspeed_cons_t[] = {{-1, "Auto"}, {0, "Easy"}, {1, "Normal"}, {2, "Hard"}, {0, NULL}};
//static consvar_t cv_dummymenuplayer = CVAR_INIT ("dummymenuplayer", "P1", CV_HIDDEN|CV_CALL, dummymenuplayer_cons_t, Dummymenuplayer_OnChange);
static consvar_t cv_dummyteam = CVAR_INIT ("dummyteam", "Spectator", CV_HIDDEN, dummyteam_cons_t, NULL);
//static cv_dummyspectate = CVAR_INITconsvar_t ("dummyspectate", "Spectator", CV_HIDDEN, dummyspectate_cons_t, NULL);
@ -176,6 +179,26 @@ consvar_t cv_dummyip = CVAR_INIT ("dummyip", "", CV_HIDDEN, NULL, NULL);
consvar_t cv_dummymenuplayer = CVAR_INIT ("dummymenuplayer", "P1", CV_HIDDEN|CV_CALL, dummymenuplayer_cons_t, Dummymenuplayer_OnChange);
consvar_t cv_dummyspectate = CVAR_INIT ("dummyspectate", "Spectator", CV_HIDDEN, dummyspectate_cons_t, NULL);
consvar_t cv_dummygpdifficulty = CVAR_INIT ("dummygpdifficulty", "Normal", CV_HIDDEN, dummygpdifficulty_cons_t, NULL);
consvar_t cv_dummykartspeed = CVAR_INIT ("dummykartspeed", "Auto", CV_HIDDEN, dummykartspeed_cons_t, NULL);
consvar_t cv_dummygpencore = CVAR_INIT ("dummygpdifficulty", "No", CV_HIDDEN, CV_YesNo, NULL);
static CV_PossibleValue_t dummymatchbots_cons_t[] = {
{0, "Off"},
{1, "Lv.1"},
{2, "Lv.2"},
{3, "Lv.3"},
{4, "Lv.4"},
{5, "Lv.5"},
{6, "Lv.6"},
{7, "Lv.7"},
{8, "Lv.8"},
{9, "Lv.9"},
{0, NULL}
};
consvar_t cv_dummymatchbots = CVAR_INIT ("dummymatchbots", "Off", CV_HIDDEN|CV_SAVE, dummymatchbots_cons_t, NULL); // Save this one if you wanna test your stuff without bots for instance
// ==========================================================================
// CVAR ONCHANGE EVENTS GO HERE
// ==========================================================================
@ -1629,6 +1652,11 @@ void M_Init(void)
CV_RegisterVar(&cv_dummygametype);
CV_RegisterVar(&cv_dummyip);
CV_RegisterVar(&cv_dummygpdifficulty);
CV_RegisterVar(&cv_dummykartspeed);
CV_RegisterVar(&cv_dummygpencore);
CV_RegisterVar(&cv_dummymatchbots);
M_UpdateMenuBGImage(true);
#if 0
@ -2347,6 +2375,60 @@ boolean M_CharacterSelectQuit(void)
return true;
}
// DIFFICULTY SELECT
void M_SetupDifficultySelect(INT32 choice)
{
// check what we picked.
choice = currentMenu->menuitems[itemOn].mvar1;
// setup the difficulty menu and then remove choices depending on choice
PLAY_RaceDifficultyDef.prevMenu = currentMenu;
M_SetupNextMenu(&PLAY_RaceDifficultyDef, false);
PLAY_RaceDifficulty[0].status = IT_STRING|IT_CVAR;
PLAY_RaceDifficulty[1].status = IT_DISABLED;
PLAY_RaceDifficulty[2].status = IT_DISABLED;
PLAY_RaceDifficulty[3].status = IT_DISABLED;
PLAY_RaceDifficulty[4].status = IT_DISABLED;
PLAY_RaceDifficulty[5].status = IT_DISABLED;
PLAY_RaceDifficulty[6].status = IT_DISABLED;
if (choice) // Match Race
{
PLAY_RaceDifficulty[2].status = IT_STRING2|IT_CVAR; // CPUs on/off use string2 to signify not to use the normal gm font drawer
PLAY_RaceDifficulty[3].status = IT_STRING2|IT_CVAR; // Encore on/off use string2 to signify not to use the normal gm font drawer
PLAY_RaceDifficulty[5].status = IT_STRING|IT_CALL; // Level Select (Match Race)
itemOn = 5; // Select cup select by default.
}
else // GP
{
PLAY_RaceDifficulty[3].status = IT_STRING2|IT_CVAR; // Encore on/off use string2 to signify not to use the normal gm font drawer
PLAY_RaceDifficulty[4].status = IT_STRING|IT_CALL; // Level Select (GP)
itemOn = 4; // Select cup select by default.
}
}
// calls the above but changes the cvar we set
void M_SetupDifficultySelectMP(INT32 choice)
{
(void) choice;
PLAY_RaceDifficultyDef.prevMenu = currentMenu;
M_SetupNextMenu(&PLAY_RaceDifficultyDef, false);
PLAY_RaceDifficulty[0].status = IT_DISABLED;
PLAY_RaceDifficulty[1].status = IT_STRING|IT_CVAR;
PLAY_RaceDifficulty[2].status = IT_STRING2|IT_CVAR; // CPUs on/off use string2 to signify not to use the normal gm font drawer
PLAY_RaceDifficulty[3].status = IT_STRING2|IT_CVAR; // Encore on/off use string2 to signify not to use the normal gm font drawer
PLAY_RaceDifficulty[4].status = IT_DISABLED;
PLAY_RaceDifficulty[5].status = IT_DISABLED;
PLAY_RaceDifficulty[6].status = IT_STRING|IT_CALL;
itemOn = 6; // Select cup select by default.
}
// LEVEL SELECT
//
@ -2585,10 +2667,11 @@ void M_CupSelectHandler(INT32 choice)
memset(&grandprixinfo, 0, sizeof(struct grandprixinfo));
// TODO: game settings screen
grandprixinfo.gamespeed = KARTSPEED_NORMAL;
grandprixinfo.masterbots = false;
grandprixinfo.encore = false;
// read our dummy cvars
grandprixinfo.gamespeed = min(KARTSPEED_HARD, cv_dummygpdifficulty.value);
grandprixinfo.masterbots = (cv_dummygpdifficulty.value == 3);
grandprixinfo.encore = (boolean)cv_dummygpencore.value;
grandprixinfo.cup = newcup;
@ -2744,9 +2827,18 @@ void M_LevelSelectHandler(INT32 choice)
SV_StartSinglePlayerServer();
multiplayer = true; // yeah, SV_StartSinglePlayerServer clobbers this...
netgame = levellist.netgame; // ^ ditto.
}
D_MapChange(levellist.choosemap+1, levellist.newgametype, (cv_kartencore.value == 1), 1, 1, false, false);
// this is considered to be CV_CHEAT however...
CV_StealthSet(&cv_kartbot, cv_dummymatchbots.string); // Match the kartbot value to the dummy match bots value.
if (netgame) // check for the dummy kartspeed value
CV_StealthSet(&cv_kartspeed, cv_dummykartspeed.string);
D_MapChange(levellist.choosemap+1, levellist.newgametype, (cv_dummygpencore.value == 1), 1, 1, false, false);
}
else // directly do the map change
D_MapChange(levellist.choosemap+1, levellist.newgametype, (cv_kartencore.value == 1), 1, 1, false, false);
M_ClearMenus(true);
}