Dehardcode menu gametype selection, part 2

- Add "Gametype" toggle option to pause menu for admins
    - A/Confirm button on any gametype other than current to do random map in new gametype
    - C/Extra button to return to current gametype
    - A/Confirm button on current gametype does a funny noise and nothing else right now, idk what to do
- `randomlevel` supports the same `-gametype` parameter as `map`
- Both `randomlevel` and `map`'s `-gametype` parameter prohibits `GTR_FORBIDMP` mask gametype changes in netgames
- `randomlevel` properly sets encore based on `cv_kartencore`'s value (and permitting `GTR_ENCORE`)
- Split out `menugametype` change functions
- `yellowmap` now remaps all intermediary shades of grey to match funny pause menu remaps
This commit is contained in:
toaster 2022-12-30 20:34:35 +00:00
parent 3ee8713e46
commit ebb2a79666
6 changed files with 196 additions and 62 deletions

View file

@ -358,7 +358,22 @@ static void CON_SetupColormaps(void)
*memorysrc = (UINT8)(i & 0xFF); // remap each color to itself...
purplemap[0] = (UINT8)163;
yellowmap[0] = (UINT8)73;
yellowmap[1] = (UINT8)73;
yellowmap[3] = (UINT8)74;
yellowmap[6] = (UINT8)74;
yellowmap[7] = (UINT8)190;
yellowmap[8] = (UINT8)190;
yellowmap[10] = (UINT8)190;
yellowmap[12] = (UINT8)190;
yellowmap[14] = (UINT8)149;
yellowmap[15] = (UINT8)149;
yellowmap[16] = (UINT8)149;
yellowmap[21] = (UINT8)152;
yellowmap[23] = (UINT8)173;
yellowmap[24] = (UINT8)167;
greenmap[0] = (UINT8)98;
bluemap[0] = (UINT8)148;
redmap[0] = (UINT8)34; // battle

View file

@ -2739,15 +2739,6 @@ static void Command_Map_f(void)
if (option_gametype)
{
#if 0
if (!multiplayer)
{
CONS_Printf(M_GetText(
"You can't switch gametypes in single player!\n"));
return;
}
else
#endif //#if 0
if (COM_Argc() < option_gametype + 2)/* no argument after? */
{
CONS_Alert(CONS_ERROR,
@ -2823,13 +2814,23 @@ static void Command_Map_f(void)
else
{
CONS_Alert(CONS_ERROR,
"'%s' is not a gametype.\n",
"'%s' is not a valid gametype.\n",
gametypename);
Z_Free(realmapname);
Z_Free(mapname);
return;
}
}
if (Playing() && netgame && (gametypes[newgametype]->rules & GTR_FORBIDMP))
{
CONS_Alert(CONS_ERROR,
"'%s' is not a net-compatible gametype.\n",
gametypename);
Z_Free(realmapname);
Z_Free(mapname);
return;
}
}
else if (!Playing())
{
@ -3061,9 +3062,10 @@ static void Command_RandomMap(void)
{
INT32 oldmapnum;
INT32 newmapnum;
INT32 newgametype;
boolean newencoremode;
INT32 newgametype = (Playing() ? gametype : menugametype);
boolean newencore = false;
boolean newresetplayers;
size_t option_gametype;
if (client && !IsPlayerAdmin(consoleplayer))
{
@ -3071,13 +3073,69 @@ static void Command_RandomMap(void)
return;
}
if ((option_gametype = COM_CheckPartialParm("-g")))
{
const char *gametypename;
if (COM_Argc() < option_gametype + 2)/* no argument after? */
{
CONS_Alert(CONS_ERROR,
"No gametype name follows parameter '%s'.\n",
COM_Argv(option_gametype));
return;
}
// new gametype value
// use current one by default
gametypename = COM_Argv(option_gametype + 1);
newgametype = G_GetGametypeByName(gametypename);
if (newgametype == -1) // reached end of the list with no match
{
/* Did they give us a gametype number? That's okay too! */
if (isdigit(gametypename[0]))
{
INT16 d = atoi(gametypename);
if (d >= 0 && d < numgametypes)
newgametype = d;
else
{
CONS_Alert(CONS_ERROR,
"Gametype number %d is out of range. Use a number between"
" 0 and %d inclusive. ...Or just use the name. :v\n",
d,
numgametypes-1);
return;
}
}
else
{
CONS_Alert(CONS_ERROR,
"'%s' is not a valid gametype.\n",
gametypename);
return;
}
}
if (Playing() && netgame && (gametypes[newgametype]->rules & GTR_FORBIDMP))
{
CONS_Alert(CONS_ERROR,
"'%s' is not a net-compatible gametype.\n",
gametypename);
return;
}
}
// TODO: Handle singleplayer conditions.
// The existing ones are way too annoyingly complicated and "anti-cheat" for my tastes.
if (Playing())
{
newgametype = gametype;
newencoremode = encoremode;
if (cv_kartencore.value == 1 && (gametypes[newgametype]->rules & GTR_ENCORE))
{
newencore = true;
}
newresetplayers = false;
if (gamestate == GS_LEVEL)
@ -3091,14 +3149,12 @@ static void Command_RandomMap(void)
}
else
{
newgametype = menugametype;
newencoremode = false;
newresetplayers = true;
oldmapnum = -1;
}
newmapnum = G_RandMap(G_TOLFlag(newgametype), oldmapnum, 0, 0, false, NULL) + 1;
D_MapChange(newmapnum, newgametype, newencoremode, newresetplayers, 0, false, false);
D_MapChange(newmapnum, newgametype, newencore, newresetplayers, 0, false, false);
}
static void Command_RestartLevel(void)

View file

@ -116,7 +116,8 @@ struct menucolor_t {
extern menucolor_t *menucolorhead, *menucolortail;
extern INT16 menugametype;
void M_HandleMenuGametype(INT32 choice);
void M_HandleHostMenuGametype(INT32 choice);
void M_HandlePauseMenuGametype(INT32 choice);
//
// MENU TYPEDEFS
@ -414,6 +415,7 @@ extern menu_t MISC_StatisticsDef;
typedef enum
{
mpause_addons = 0,
mpause_changegametype,
mpause_switchmap,
mpause_restartmap,
mpause_tryagain,

View file

@ -363,7 +363,7 @@ menuitem_t PLAY_MP_Host[] =
NULL, {.cvar = &cv_maxplayers}, 0, 0},
{IT_STRING | IT_KEYHANDLER, "Gamemode", "Choose the type of play on your server.",
NULL, {.routine = M_HandleMenuGametype}, 0, 0},
NULL, {.routine = M_HandleHostMenuGametype}, 0, 0},
{IT_STRING | IT_CALL, "GO", "Select a map with the currently selected gamemode",
NULL, {.routine = M_MPSetupNetgameMapSelect}, 0, 0},
@ -1593,6 +1593,9 @@ menuitem_t PAUSE_Main[] =
{IT_STRING | IT_CALL, "ADDONS", "M_ICOADD",
NULL, {.routine = M_Addons}, 0, 0},
{IT_STRING | IT_KEYHANDLER, "GAMETYPE", "M_ICOGAM",
NULL, {.routine = M_HandlePauseMenuGametype}, 0, 0},
{IT_STRING | IT_SUBMENU, "CHANGE MAP", "M_ICOMAP",
NULL, {.submenu = &PAUSE_GamemodesDef}, 0, 0},

View file

@ -2468,7 +2468,7 @@ void M_DrawMPHost(void)
}
case IT_KEYHANDLER:
{
if (currentMenu->menuitems[i].itemaction.routine != M_HandleMenuGametype)
if (currentMenu->menuitems[i].itemaction.routine != M_HandleHostMenuGametype)
break;
w = V_ThinStringWidth(gametypes[menugametype]->name, V_6WIDTHSPACE);
@ -3778,12 +3778,26 @@ void M_DrawPause(void)
word1[word1len] = '\0';
word2[word2len] = '\0';
// If there's no 2nd word, take this opportunity to center this line of text.
if (word1len)
V_DrawCenteredLSTitleHighString(220 + offset*2, 75 + (!word2len ? 10 : 0), 0, word1);
if (itemOn == mpause_changegametype)
{
INT32 w = V_LSTitleLowStringWidth(gametypes[menugametype]->name, 0)/2;
if (word2len)
V_DrawCenteredLSTitleLowString(220 + offset*2, 103, 0, word2);
if (word1len)
V_DrawCenteredLSTitleHighString(220 + offset*2, 75, 0, word1);
V_DrawLSTitleLowString(220-w + offset*2, 103, V_YELLOWMAP, gametypes[menugametype]->name);
V_DrawCharacter(220-w + offset*2 - 8 - (skullAnimCounter/5), 103+6, '\x1C' | V_YELLOWMAP, false); // left arrow
V_DrawCharacter(220+w + offset*2 + 4 + (skullAnimCounter/5), 103+6, '\x1D' | V_YELLOWMAP, false); // right arrow
}
else
{
// If there's no 2nd word, take this opportunity to center this line of text.
if (word1len)
V_DrawCenteredLSTitleHighString(220 + offset*2, 75 + (!word2len ? 10 : 0), 0, word1);
if (word2len)
V_DrawCenteredLSTitleLowString(220 + offset*2, 103, 0, word2);
}
}
tic_t playback_last_menu_interaction_leveltime = 0;

View file

@ -4162,10 +4162,37 @@ void M_MPHostInit(INT32 choice)
itemOn = mhost_go;
}
void M_HandleMenuGametype(INT32 choice)
static void M_NextMenuGametype(UINT32 forbidden)
{
const INT16 currentmenugametype = menugametype;
do
{
menugametype++;
if (menugametype >= numgametypes)
menugametype = 0;
if (!(gametypes[menugametype]->rules & forbidden))
break;
} while (menugametype != currentmenugametype);
}
static void M_PrevMenuGametype(UINT32 forbidden)
{
const INT16 currentmenugametype = menugametype;
do
{
if (menugametype == 0)
menugametype = numgametypes;
menugametype--;
if (!(gametypes[menugametype]->rules & forbidden))
break;
} while (menugametype != currentmenugametype);
}
void M_HandleHostMenuGametype(INT32 choice)
{
const UINT8 pid = 0;
const INT16 currentmenugametype = menugametype;
UINT32 forbidden = GTR_FORBIDMP;
(void)choice;
@ -4173,42 +4200,24 @@ void M_HandleMenuGametype(INT32 choice)
if (currentMenu->menuitems[itemOn].mvar1 != 0)
forbidden = currentMenu->menuitems[itemOn].mvar1;
if (menucmd[pid].dpad_lr > 0 || M_MenuConfirmPressed(pid))
if (M_MenuBackPressed(pid))
{
do
{
menugametype++;
if (menugametype >= numgametypes)
menugametype = 0;
if (!(gametypes[menugametype]->rules & forbidden))
break;
} while (menugametype != currentmenugametype);
M_GoBack(0);
M_SetMenuDelay(pid);
return;
}
else if (menucmd[pid].dpad_lr > 0 || M_MenuConfirmPressed(pid))
{
M_NextMenuGametype(forbidden);
S_StartSound(NULL, sfx_s3k5b);
M_SetMenuDelay(pid);
}
else if (menucmd[pid].dpad_lr < 0)
{
do
{
if (menugametype == 0)
menugametype = numgametypes;
menugametype--;
if (!(gametypes[menugametype]->rules & forbidden))
break;
} while (menugametype != currentmenugametype);
M_PrevMenuGametype(forbidden);
S_StartSound(NULL, sfx_s3k5b);
M_SetMenuDelay(pid);
}
else if (M_MenuBackPressed(pid))
{
M_GoBack(0);
M_SetMenuDelay(pid);
return;
}
if (menucmd[pid].dpad_ud > 0)
{
@ -6150,6 +6159,7 @@ void M_OpenPauseMenu(void)
// By default, disable anything sensitive:
PAUSE_Main[mpause_addons].status = IT_DISABLED;
PAUSE_Main[mpause_changegametype].status = IT_DISABLED;
PAUSE_Main[mpause_switchmap].status = IT_DISABLED;
PAUSE_Main[mpause_restartmap].status = IT_DISABLED;
PAUSE_Main[mpause_tryagain].status = IT_DISABLED;
@ -6171,14 +6181,8 @@ void M_OpenPauseMenu(void)
if (server || IsPlayerAdmin(consoleplayer))
{
PAUSE_Main[mpause_switchmap].status = IT_STRING | IT_SUBMENU;
for (i = 0; i < PAUSE_GamemodesDef.numitems; i++)
{
if (PAUSE_GamemodesMenu[i].mvar2 != gametype)
continue;
PAUSE_GamemodesDef.lastOn = i;
break;
}
PAUSE_Main[mpause_changegametype].status = IT_STRING | IT_KEYHANDLER;
PAUSE_Main[mpause_switchmap].status = IT_STRING | IT_CALL;
PAUSE_Main[mpause_restartmap].status = IT_STRING | IT_CALL;
PAUSE_Main[mpause_addons].status = IT_STRING | IT_CALL;
}
@ -6279,6 +6283,46 @@ boolean M_PauseInputs(INT32 ch)
return false;
}
// Change gametype
void M_HandlePauseMenuGametype(INT32 choice)
{
const UINT8 pid = 0;
UINT32 forbidden = GTR_FORBIDMP;
(void)choice;
if (M_MenuConfirmPressed(pid))
{
if (menugametype != gametype)
{
M_ClearMenus(true);
COM_ImmedExecute(va("randommap -gt %s", gametypes[menugametype]->name));
return;
}
M_SetMenuDelay(pid);
S_StartSound(NULL, sfx_s3k7b);
}
else if (M_MenuExtraPressed(pid))
{
menugametype = gametype;
M_SetMenuDelay(pid);
S_StartSound(NULL, sfx_s3k7b);
}
else if (menucmd[pid].dpad_lr > 0)
{
M_NextMenuGametype(forbidden);
S_StartSound(NULL, sfx_s3k5b);
M_SetMenuDelay(pid);
}
else if (menucmd[pid].dpad_lr < 0)
{
M_PrevMenuGametype(forbidden);
S_StartSound(NULL, sfx_s3k5b);
M_SetMenuDelay(pid);
}
}
// Restart map
void M_RestartMap(INT32 choice)
{