Add menu for selecting cup & other options

This commit is contained in:
Sally Coolatta 2020-05-09 20:03:14 -04:00
parent 06002beb65
commit 4ae81ff236
7 changed files with 210 additions and 112 deletions

View file

@ -75,6 +75,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
#include "fastcmp.h"
#include "keys.h"
#include "filesrch.h" // refreshdirmenu
#include "k_grandprix.h"
#ifdef CMAKECONFIG
#include "config.h"
@ -774,7 +775,9 @@ void D_StartTitle(void)
// In case someone exits out at the same time they start a time attack run,
// reset modeattacking
modeattacking = ATTACKING_NONE;
grandprixmatch = 0;
// Reset GP
memset(&grandprixinfo, 0, sizeof(struct grandprixinfo));
// empty maptol so mario/etc sounds don't play in sound test when they shouldn't
maptol = 0;

View file

@ -50,6 +50,7 @@
#include "k_battle.h"
#include "k_pwrlv.h"
#include "y_inter.h"
#include "k_grandprix.h"
#ifdef NETGAME_DEVMODE
#define CV_RESTRICT CV_NETVAR
@ -2760,6 +2761,12 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pencoremode, boolean r
if (netgame || multiplayer)
FLS = false;
if (grandprixinfo.roundnum != 0)
{
// Too lazy to change the input value for every instance of this function.......
pencoremode = grandprixinfo.encore;
}
if (delay != 2)
{
UINT8 flags = 0;
@ -2983,7 +2990,6 @@ static void Command_Map_f(void)
// new encoremode value
// use cvar by default
newencoremode = (cv_kartencore.value == 1);
if (COM_CheckParm("-encore"))
@ -6314,7 +6320,7 @@ static void Command_ShowTime_f(void)
// SRB2Kart: On change messages
static void BaseNumLaps_OnChange(void)
{
if (gamestate == GS_LEVEL)
if (gamestate == GS_LEVEL && grandprixinfo.roundnum == 0)
{
if (cv_basenumlaps.value)
CONS_Printf(M_GetText("Number of laps will be changed to %d next round.\n"), cv_basenumlaps.value);
@ -6344,7 +6350,7 @@ static void KartSpeed_OnChange(void)
return;
}
if (G_RaceGametype())
if (G_RaceGametype() && grandprixinfo.roundnum == 0)
{
if ((gamestate == GS_LEVEL && leveltime < starttime) && (cv_kartspeed.value != KARTSPEED_AUTO))
{
@ -6360,7 +6366,7 @@ static void KartSpeed_OnChange(void)
static void KartEncore_OnChange(void)
{
if (G_RaceGametype())
if (G_RaceGametype() && grandprixinfo.roundnum == 0)
{
if ((cv_kartencore.value == 1) != encoremode && gamestate == GS_LEVEL /*&& leveltime > starttime*/)
CONS_Printf(M_GetText("Encore Mode will be set to %s next round.\n"), cv_kartencore.string);
@ -6385,6 +6391,6 @@ static void KartComeback_OnChange(void)
static void KartEliminateLast_OnChange(void)
{
if (G_RaceGametype() && cv_karteliminatelast.value)
if (G_RaceGametype() && cv_karteliminatelast.value && grandprixinfo.roundnum == 0)
P_CheckRacers();
}

View file

@ -50,6 +50,7 @@
#include "k_kart.h" // SRB2kart
#include "k_battle.h"
#include "k_pwrlv.h"
#include "k_grandprix.h"
gameaction_t gameaction;
gamestate_t gamestate = GS_NULL;
@ -3628,7 +3629,6 @@ void G_AddMapToBuffer(INT16 map)
static void G_DoCompleted(void)
{
INT32 i, j = 0;
boolean gottoken = false;
SINT8 powertype = PWRLV_DISABLED;
tokenlist = 0; // Reset the list
@ -3669,11 +3669,25 @@ static void G_DoCompleted(void)
// go to next level
// nextmap is 0-based, unlike gamemap
if (nextmapoverride != 0)
{
nextmap = (INT16)(nextmapoverride-1);
else if (mapheaderinfo[gamemap-1]->nextlevel == 1101) // SRB2Kart: !!! WHENEVER WE GET GRAND PRIX, GO TO AWARDS MAP INSTEAD !!!
nextmap = (INT16)(mapheaderinfo[gamemap] ? gamemap : (spstage_start-1)); // (gamemap-1)+1 == gamemap :V
}
else if (grandprixinfo.roundnum != 0)
{
if (grandprixinfo.roundnum >= grandprixinfo.cup->numlevels)
{
nextmap = 1101; // ceremonymap
}
else
{
nextmap = grandprixinfo.cup->levellist[grandprixinfo.roundnum];
grandprixinfo.roundnum++;
}
}
else
{
nextmap = (INT16)(mapheaderinfo[gamemap-1]->nextlevel-1);
}
// Remember last map for when you come out of the special stage.
if (!G_IsSpecialStage(gamemap))
@ -3683,8 +3697,7 @@ static void G_DoCompleted(void)
// a map of the proper gametype -- skip levels that don't support
// the current gametype. (Helps avoid playing boss levels in Race,
// for instance).
if (!token && !G_IsSpecialStage(gamemap) && !modeattacking
&& (nextmap >= 0 && nextmap < NUMMAPS))
if (!modeattacking && (grandprixinfo.roundnum == 0) && (nextmap >= 0 && nextmap < NUMMAPS))
{
register INT16 cm = nextmap;
INT16 tolflag = G_TOLFlag(gametype);
@ -3728,44 +3741,18 @@ static void G_DoCompleted(void)
if (nextmap < 0 || (nextmap >= NUMMAPS && nextmap < 1100-1) || nextmap > 1102-1)
I_Error("Followed map %d to invalid map %d\n", prevmap + 1, nextmap + 1);
// wrap around in race
if (nextmap >= 1100-1 && nextmap <= 1102-1 && G_RaceGametype())
nextmap = (INT16)(spstage_start-1);
if (gametype == GT_COOP && token)
{
token--;
gottoken = true;
if (!(emeralds & EMERALD1))
nextmap = (INT16)(sstage_start - 1); // Special Stage 1
else if (!(emeralds & EMERALD2))
nextmap = (INT16)(sstage_start); // Special Stage 2
else if (!(emeralds & EMERALD3))
nextmap = (INT16)(sstage_start + 1); // Special Stage 3
else if (!(emeralds & EMERALD4))
nextmap = (INT16)(sstage_start + 2); // Special Stage 4
else if (!(emeralds & EMERALD5))
nextmap = (INT16)(sstage_start + 3); // Special Stage 5
else if (!(emeralds & EMERALD6))
nextmap = (INT16)(sstage_start + 4); // Special Stage 6
else if (!(emeralds & EMERALD7))
nextmap = (INT16)(sstage_start + 5); // Special Stage 7
else
gottoken = false;
}
if (G_IsSpecialStage(gamemap) && !gottoken)
nextmap = lastmap; // Exiting from a special stage? Go back to the game. Tails 08-11-2001
automapactive = false;
if (gametype != GT_COOP)
{
if (cv_advancemap.value == 0) // Stay on same map.
{
nextmap = prevmap;
}
else if (cv_advancemap.value == 2) // Go to random map.
{
nextmap = G_RandMap(G_TOLFlag(gametype), prevmap, false, 0, false, NULL);
}
}
// We are committed to this map now.
@ -3842,7 +3829,7 @@ void G_NextLevel(void)
{
if (gamestate != GS_VOTING)
{
if ((cv_advancemap.value == 3) && !modeattacking && !skipstats && (multiplayer || netgame))
if ((cv_advancemap.value == 3) && grandprixinfo.roundnum == 0 && !modeattacking && !skipstats && (multiplayer || netgame))
{
UINT8 i;
for (i = 0; i < MAXPLAYERS; i++)
@ -4508,7 +4495,7 @@ void G_SaveGame(UINT32 savegameslot)
void G_DeferedInitNew(boolean pencoremode, const char *mapname, INT32 pickedchar, UINT8 ssplayers, boolean FLS)
{
INT32 i;
UINT8 color = 0;
//UINT8 color = 0;
paused = false;
if (demo.playback)
@ -4528,23 +4515,20 @@ void G_DeferedInitNew(boolean pencoremode, const char *mapname, INT32 pickedchar
// this leave the actual game if needed
SV_StartSinglePlayerServer();
if (savedata.lives > 0)
{
color = savedata.skincolor;
}
else if (splitscreen != ssplayers)
if (splitscreen != ssplayers)
{
splitscreen = ssplayers;
SplitScreen_OnChange();
}
if (!color && !modeattacking)
color = skins[pickedchar].prefcolor;
//if (!color)
//color = skins[pickedchar].prefcolor;
SetPlayerSkinByNum(consoleplayer, pickedchar);
CV_StealthSet(&cv_skin, skins[pickedchar].name);
if (color)
CV_StealthSetValue(&cv_playercolor, color);
//if (color)
//CV_StealthSetValue(&cv_playercolor, color);
if (mapname)
D_MapChange(M_MapNumber(mapname[3], mapname[4]), gametype, pencoremode, true, 1, false, FLS);

View file

@ -19,8 +19,7 @@
#include "m_random.h"
#include "r_things.h"
UINT8 grandprixmatch = 0;
boolean initgpbots = false;
struct grandprixinfo grandprixinfo;
void K_InitGrandPrixBots(void)
{
@ -43,11 +42,6 @@ void K_InitGrandPrixBots(void)
UINT8 newplayernum = 0;
UINT8 i;
if (initgpbots != true)
{
return;
}
memset(difficultylevels, MAXBOTDIFFICULTY, sizeof (difficultylevels));
memset(competitors, MAXPLAYERS, sizeof (competitors));
memset(botskinlist, defaultbotskin, sizeof (botskinlist));
@ -163,6 +157,4 @@ void K_InitGrandPrixBots(void)
break;
}
}
initgpbots = false;
}

View file

@ -1,18 +1,20 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 2007-2016 by John "JTE" Muniz.
// Copyright (C) 2012-2018 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file k_grandprix.h
/// \brief Grand Prix mode specific code
#ifndef __K_GRANDPRIX__
#define __K_GRANDPRIX__
#include "doomdef.h"
#include "doomstat.h"
extern UINT8 grandprixmatch;
extern boolean initgpbots;
extern struct grandprixinfo
{
UINT8 roundnum; ///< Round number -- if 0, then we're not in a Grand Prix.
cupheader_t *cup; ///< Which cup are we playing?
UINT8 gamespeed; ///< Copy of gamespeed, just to make sure you can't cheat it with cvars
boolean encore; ///< Ditto, but for encore mode
boolean masterbots; ///< If true, all bots should be max difficulty (Master Mode)
boolean initbots; ///< If true, we need to initialize the bots that are competing.
} grandprixinfo;
void K_InitGrandPrixBots(void);
#endif

View file

@ -226,6 +226,7 @@ menu_t SP_MainDef, MP_MainDef, OP_MainDef;
menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef, MISC_ChangeSpectateDef;
// Single Player
static void M_GrandPrixTemp(INT32 choice);
static void M_StartGrandPrix(INT32 choice);
static void M_TimeAttack(INT32 choice);
static boolean M_QuitTimeAttackMenu(void);
@ -240,6 +241,7 @@ static void M_ModeAttackEndGame(INT32 choice);
static void M_SetGuestReplay(INT32 choice);
//static void M_ChoosePlayer(INT32 choice);
menu_t SP_LevelStatsDef;
static menu_t SP_GrandPrixTempDef;
static menu_t SP_TimeAttackDef, SP_ReplayDef, SP_GuestReplayDef, SP_GhostDef;
//static menu_t SP_NightsAttackDef, SP_NightsReplayDef, SP_NightsGuestReplayDef, SP_NightsGhostDef;
@ -466,6 +468,13 @@ static consvar_t cv_dummycontinues = {"dummycontinues", "0", CV_HIDEN, liveslimi
//static consvar_t cv_dummymares = {"dummymares", "Overall", CV_HIDEN|CV_CALL, dummymares_cons_t, Dummymares_OnChange, 0, NULL, NULL, 0, 0, NULL};
static consvar_t cv_dummystaff = {"dummystaff", "0", CV_HIDEN|CV_CALL, dummystaff_cons_t, Dummystaff_OnChange, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t dummygpdifficulty_cons_t[] = {{0, "Easy"}, {1, "Normal"}, {2, "Hard"}, {3, "Master"}, {0, NULL}};
static CV_PossibleValue_t dummygpcup_cons_t[50] = {{1, "TEMP"}}; // A REALLY BIG NUMBER, SINCE THIS IS TEMP UNTIL NEW MENUS
static consvar_t cv_dummygpdifficulty = {"dummygpdifficulty", "Normal", CV_HIDEN, dummygpdifficulty_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static consvar_t cv_dummygpencore = {"dummygpencore", "Off", CV_HIDEN, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static consvar_t cv_dummygpcup = {"dummygpcup", "TEMP", CV_HIDEN, dummygpcup_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// ==========================================================================
// ORGANIZATION START.
// ==========================================================================
@ -804,7 +813,7 @@ static menuitem_t SR_EmblemHintMenu[] =
// Single Player Main
static menuitem_t SP_MainMenu[] =
{
{IT_CALL | IT_STRING, NULL, "Grand Prix", M_StartGrandPrix, 92},
{IT_STRING|IT_CALL, NULL, "Grand Prix", M_GrandPrixTemp, 92},
{IT_SECRET, NULL, "Time Attack", M_TimeAttack, 100},
{IT_SECRET, NULL, "Break the Capsules", M_BreakTheCapsules, 108},
};
@ -817,17 +826,17 @@ enum
};
// Single Player Load Game
/*static menuitem_t SP_LoadGameMenu[] =
static menuitem_t SP_GrandPrixPlaceholderMenu[] =
{
{IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandleLoadSave, '\0'}, // dummy menuitem for the control func
};
{IT_STRING|IT_CVAR, NULL, "Character", &cv_chooseskin, 10},
{IT_STRING|IT_CVAR, NULL, "Color", &cv_playercolor, 20},
// Single Player Level Select
static menuitem_t SP_LevelSelectMenu[] =
{
{IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 78},
{IT_WHITESTRING|IT_CALL, NULL, "Start", M_LevelSelectWarp, 130},
};*/
{IT_STRING|IT_CVAR, NULL, "Difficulty", &cv_dummygpdifficulty, 40},
{IT_STRING|IT_CVAR, NULL, "Encore Mode", &cv_dummygpencore, 50},
{IT_STRING|IT_CVAR, NULL, "Cup", &cv_dummygpcup, 70},
{IT_STRING|IT_CALL, NULL, "Start", M_StartGrandPrix, 80},
};
// Single Player Time Attack
static menuitem_t SP_TimeAttackMenu[] =
@ -1830,6 +1839,8 @@ menu_t SP_LevelStatsDef =
NULL
};
static menu_t SP_GrandPrixTempDef = DEFAULTMENUSTYLE(NULL, SP_GrandPrixPlaceholderMenu, &MainDef, 60, 30);
static menu_t SP_TimeAttackDef =
{
"M_ATTACK",
@ -3277,6 +3288,10 @@ void M_Init(void)
//CV_RegisterVar(&cv_dummymares);
CV_RegisterVar(&cv_dummystaff);
CV_RegisterVar(&cv_dummygpdifficulty);
CV_RegisterVar(&cv_dummygpencore);
CV_RegisterVar(&cv_dummygpcup);
quitmsg[QUITMSG] = M_GetText("Eggman's tied explosives\nto your girlfriend, and\nwill activate them if\nyou press the 'Y' key!\nPress 'N' to save her!\n\n(Press 'Y' to quit)");
quitmsg[QUITMSG1] = M_GetText("What would Tails say if\nhe saw you quitting the game?\n\n(Press 'Y' to quit)");
quitmsg[QUITMSG2] = M_GetText("Hey!\nWhere do ya think you're goin'?\n\n(Press 'Y' to quit)");
@ -4147,6 +4162,35 @@ static void M_PatchSkinNameTable(void)
return;
}
//
// M_PrepareCupList
//
static void M_PrepareCupList(void)
{
cupheader_t *cup = kartcupheaders;
INT32 i = 0;
memset(dummygpcup_cons_t, 0, sizeof (dummygpcup_cons_t));
while (cup != NULL)
{
dummygpcup_cons_t[i].strvalue = cup->name;
dummygpcup_cons_t[i].value = i+1;
// this will probably crash or do something stupid at over 50 cups,
// but this is all behavior that gets completely overwritten in new-menus, so I'm not worried
i++;
cup = cup->next;
}
for (; i < 50; i++)
{
dummygpcup_cons_t[i].strvalue = NULL;
dummygpcup_cons_t[i].value = 0;
}
CV_SetValue(&cv_dummygpcup, 1); // This causes crash sometimes?!
}
// Call before showing any level-select menus
static void M_PrepareLevelSelect(void)
{
@ -7455,6 +7499,77 @@ static void M_HandleLevelStats(INT32 choice)
}
}
static void M_GrandPrixTemp(INT32 choice)
{
(void)choice;
M_PatchSkinNameTable();
M_PrepareCupList();
M_SetupNextMenu(&SP_GrandPrixTempDef);
}
// Start Grand Prix!
static void M_StartGrandPrix(INT32 choice)
{
cupheader_t *gpcup = kartcupheaders;
(void)choice;
if (gpcup == NULL)
{
// welp
I_Error("No cup definitions for GP\n");
return;
}
M_ClearMenus(true);
memset(&grandprixinfo, 0, sizeof(struct grandprixinfo));
switch (cv_dummygpdifficulty.value)
{
case 0:
grandprixinfo.gamespeed = KARTSPEED_EASY;
break;
case 1:
default:
grandprixinfo.gamespeed = KARTSPEED_NORMAL;
break;
case 2:
grandprixinfo.gamespeed = KARTSPEED_HARD;
break;
case 3:
grandprixinfo.gamespeed = KARTSPEED_HARD;
grandprixinfo.masterbots = true;
break;
}
grandprixinfo.encore = (boolean)(cv_dummygpencore.value);
while (gpcup != NULL && gpcup->id != cv_dummygpcup.value-1)
{
gpcup = gpcup->next;
}
if (gpcup == NULL)
{
gpcup = kartcupheaders;
}
grandprixinfo.cup = gpcup;
grandprixinfo.roundnum = 1;
grandprixinfo.initbots = true;
G_DeferedInitNew(
false,
G_BuildMapName(grandprixinfo.cup->levellist[0] + 1),
(UINT8)(cv_chooseskin.value - 1),
(UINT8)(cv_splitplayers.value - 1),
false
);
}
// ===========
// MODE ATTACK
// ===========
@ -7649,20 +7764,6 @@ void M_DrawTimeAttackMenu(void)
}
}
// Start Grand Prix!
static void M_StartGrandPrix(INT32 choice)
{
(void)choice;
M_ClearMenus(true);
grandprixmatch = 1;
initgpbots = true;
G_DeferedInitNew(false, "MAP01", (UINT8)(cv_chooseskin.value-1), 0, false); // G_BuildMapName(startmap)
}
// Going to Time Attack menu...
static void M_TimeAttack(INT32 choice)
{

View file

@ -2401,8 +2401,23 @@ static void P_LevelInitStuff(void)
}
// SRB2Kart: map load variables
if (modeattacking) // Just play it safe and set everything
if (grandprixinfo.roundnum != 0)
{
if (G_BattleGametype())
{
gamespeed = KARTSPEED_EASY;
}
else
{
gamespeed = grandprixinfo.gamespeed;
}
franticitems = false;
comeback = true;
}
else if (modeattacking)
{
// Just play it safe and set everything
gamespeed = KARTSPEED_HARD;
franticitems = false;
comeback = true;
@ -2611,12 +2626,6 @@ static void P_ForceCharacter(const char *forcecharskin)
}
SetPlayerSkin(consoleplayer, forcecharskin);
// normal player colors in single player
if ((unsigned)cv_playercolor.value != skins[players[consoleplayer].skin].prefcolor && !modeattacking)
{
CV_StealthSetValue(&cv_playercolor, skins[players[consoleplayer].skin].prefcolor);
players[consoleplayer].skincolor = skins[players[consoleplayer].skin].prefcolor;
}
}
}
@ -3366,17 +3375,18 @@ boolean P_SetupLevel(boolean skipprecip)
// NOW you can try to spawn in the Battle capsules, if there's not enough players for a match
K_SpawnBattleCapsules();
if (grandprixmatch == 0)
if (grandprixinfo.roundnum != 0)
{
K_UpdateMatchRaceBots();
if (grandprixinfo.initbots == true)
{
K_InitGrandPrixBots();
grandprixinfo.initbots = false;
}
}
else
{
if (initgpbots == true)
{
K_InitGrandPrixBots();
initgpbots = false;
}
// We're in a Match Race, use simplistic randomized bots.
K_UpdateMatchRaceBots();
}
return true;