mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 09:11:48 +00:00
Merge branch 'tutorial-time' into 'master'
Tutorial mode handling See merge request STJr/SRB2Internal!201
This commit is contained in:
commit
b6a0b2f1d9
11 changed files with 211 additions and 8 deletions
14
src/d_main.c
14
src/d_main.c
|
@ -71,6 +71,7 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
|
||||||
#include "fastcmp.h"
|
#include "fastcmp.h"
|
||||||
#include "keys.h"
|
#include "keys.h"
|
||||||
#include "filesrch.h" // refreshdirmenu, mainwadstally
|
#include "filesrch.h" // refreshdirmenu, mainwadstally
|
||||||
|
#include "g_input.h" // tutorial mode control scheming
|
||||||
|
|
||||||
#ifdef CMAKECONFIG
|
#ifdef CMAKECONFIG
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -733,6 +734,19 @@ void D_StartTitle(void)
|
||||||
// Reset the palette
|
// Reset the palette
|
||||||
if (rendermode != render_none)
|
if (rendermode != render_none)
|
||||||
V_SetPaletteLump("PLAYPAL");
|
V_SetPaletteLump("PLAYPAL");
|
||||||
|
|
||||||
|
// The title screen is obviously not a tutorial! (Unless I'm mistaken)
|
||||||
|
if (tutorialmode && tutorialgcs)
|
||||||
|
{
|
||||||
|
G_CopyControls(gamecontrol, gamecontroldefault[gcs_custom], gcl_tutorial_full, num_gcl_tutorial_full); // using gcs_custom as temp storage
|
||||||
|
CV_SetValue(&cv_usemouse, tutorialusemouse);
|
||||||
|
CV_SetValue(&cv_alwaysfreelook, tutorialfreelook);
|
||||||
|
CV_SetValue(&cv_mousemove, tutorialmousemove);
|
||||||
|
CV_SetValue(&cv_analog, tutorialanalog);
|
||||||
|
M_StartMessage("Do you want to \x82save the recommended \x82movement controls?\x80\n\nPress 'Y' or 'Enter' to confirm\nPress 'N' or any key to keep \nyour current controls",
|
||||||
|
M_TutorialSaveControlResponse, MM_YESNO);
|
||||||
|
}
|
||||||
|
tutorialmode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -712,6 +712,7 @@ void D_RegisterClientCommands(void)
|
||||||
CV_RegisterVar(&cv_crosshair2);
|
CV_RegisterVar(&cv_crosshair2);
|
||||||
CV_RegisterVar(&cv_alwaysfreelook);
|
CV_RegisterVar(&cv_alwaysfreelook);
|
||||||
CV_RegisterVar(&cv_alwaysfreelook2);
|
CV_RegisterVar(&cv_alwaysfreelook2);
|
||||||
|
CV_RegisterVar(&cv_tutorialprompt);
|
||||||
|
|
||||||
// g_input.c
|
// g_input.c
|
||||||
CV_RegisterVar(&cv_sideaxis);
|
CV_RegisterVar(&cv_sideaxis);
|
||||||
|
@ -1808,6 +1809,16 @@ static void Command_Map_f(void)
|
||||||
else
|
else
|
||||||
fromlevelselect = ((netgame || multiplayer) && ((gametype == newgametype) && (newgametype == GT_COOP)));
|
fromlevelselect = ((netgame || multiplayer) && ((gametype == newgametype) && (newgametype == GT_COOP)));
|
||||||
|
|
||||||
|
if (tutorialmode && tutorialgcs)
|
||||||
|
{
|
||||||
|
G_CopyControls(gamecontrol, gamecontroldefault[gcs_custom], gcl_tutorial_full, num_gcl_tutorial_full); // using gcs_custom as temp storage
|
||||||
|
CV_SetValue(&cv_usemouse, tutorialusemouse);
|
||||||
|
CV_SetValue(&cv_alwaysfreelook, tutorialfreelook);
|
||||||
|
CV_SetValue(&cv_mousemove, tutorialmousemove);
|
||||||
|
CV_SetValue(&cv_analog, tutorialanalog);
|
||||||
|
}
|
||||||
|
tutorialmode = false; // warping takes us out of tutorial mode
|
||||||
|
|
||||||
D_MapChange(newmapnum, newgametype, false, newresetplayers, 0, false, fromlevelselect);
|
D_MapChange(newmapnum, newgametype, false, newresetplayers, 0, false, fromlevelselect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2892,6 +2892,19 @@ static void readmaincfg(MYFILE *f)
|
||||||
startchar = (INT16)value;
|
startchar = (INT16)value;
|
||||||
char_on = -1;
|
char_on = -1;
|
||||||
}
|
}
|
||||||
|
else if (fastcmp(word, "TUTORIALMAP"))
|
||||||
|
{
|
||||||
|
// Support using the actual map name,
|
||||||
|
// i.e., Level AB, Level FZ, etc.
|
||||||
|
|
||||||
|
// Convert to map number
|
||||||
|
if (word2[0] >= 'A' && word2[0] <= 'Z')
|
||||||
|
value = M_MapNumber(word2[0], word2[1]);
|
||||||
|
else
|
||||||
|
value = get_number(word2);
|
||||||
|
|
||||||
|
tutorialmap = (INT16)value;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
deh_warning("Maincfg: unknown word '%s'", word);
|
deh_warning("Maincfg: unknown word '%s'", word);
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,6 +132,10 @@ extern INT16 bootmap; //bootmap for loading a map on startup
|
||||||
extern INT16 tutorialmap; // map to load for tutorial
|
extern INT16 tutorialmap; // map to load for tutorial
|
||||||
extern boolean tutorialmode; // are we in a tutorial right now?
|
extern boolean tutorialmode; // are we in a tutorial right now?
|
||||||
extern INT32 tutorialgcs; // which control scheme is loaded?
|
extern INT32 tutorialgcs; // which control scheme is loaded?
|
||||||
|
extern INT32 tutorialusemouse; // store cv_usemouse user value
|
||||||
|
extern INT32 tutorialfreelook; // store cv_alwaysfreelook user value
|
||||||
|
extern INT32 tutorialmousemove; // store cv_mousemove user value
|
||||||
|
extern INT32 tutorialanalog; // store cv_analog user value
|
||||||
|
|
||||||
extern boolean looptitle;
|
extern boolean looptitle;
|
||||||
|
|
||||||
|
|
|
@ -130,6 +130,10 @@ INT16 bootmap; //bootmap for loading a map on startup
|
||||||
INT16 tutorialmap = 0; // map to load for tutorial
|
INT16 tutorialmap = 0; // map to load for tutorial
|
||||||
boolean tutorialmode = false; // are we in a tutorial right now?
|
boolean tutorialmode = false; // are we in a tutorial right now?
|
||||||
INT32 tutorialgcs = gcs_custom; // which control scheme is loaded?
|
INT32 tutorialgcs = gcs_custom; // which control scheme is loaded?
|
||||||
|
INT32 tutorialusemouse = 0; // store cv_usemouse user value
|
||||||
|
INT32 tutorialfreelook = 0; // store cv_alwaysfreelook user value
|
||||||
|
INT32 tutorialmousemove = 0; // store cv_mousemove user value
|
||||||
|
INT32 tutorialanalog = 0; // store cv_analog user value
|
||||||
|
|
||||||
boolean looptitle = false;
|
boolean looptitle = false;
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@ extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard di
|
||||||
extern INT16 rw_maximums[NUM_WEAPONS];
|
extern INT16 rw_maximums[NUM_WEAPONS];
|
||||||
|
|
||||||
// used in game menu
|
// used in game menu
|
||||||
|
extern consvar_t cv_tutorialprompt;
|
||||||
extern consvar_t cv_crosshair, cv_crosshair2;
|
extern consvar_t cv_crosshair, cv_crosshair2;
|
||||||
extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_mousemove;
|
extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_mousemove;
|
||||||
extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_mousemove2;
|
extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_mousemove2;
|
||||||
|
|
139
src/m_menu.c
139
src/m_menu.c
|
@ -273,6 +273,7 @@ menu_t SP_MainDef, OP_MainDef;
|
||||||
menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef;
|
menu_t MISC_ScrambleTeamDef, MISC_ChangeTeamDef;
|
||||||
|
|
||||||
// Single Player
|
// Single Player
|
||||||
|
static void M_StartTutorial(INT32 choice);
|
||||||
static void M_LoadGame(INT32 choice);
|
static void M_LoadGame(INT32 choice);
|
||||||
static void M_TimeAttackLevelSelect(INT32 choice);
|
static void M_TimeAttackLevelSelect(INT32 choice);
|
||||||
static void M_TimeAttack(INT32 choice);
|
static void M_TimeAttack(INT32 choice);
|
||||||
|
@ -440,6 +441,9 @@ static CV_PossibleValue_t serversort_cons_t[] = {
|
||||||
};
|
};
|
||||||
consvar_t cv_serversort = {"serversort", "Ping", CV_HIDEN | CV_CALL, serversort_cons_t, M_SortServerList, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_serversort = {"serversort", "Ping", CV_HIDEN | CV_CALL, serversort_cons_t, M_SortServerList, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
// first time memory
|
||||||
|
consvar_t cv_tutorialprompt = {"tutorialprompt", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
// autorecord demos for time attack
|
// autorecord demos for time attack
|
||||||
static consvar_t cv_autorecord = {"autorecord", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
static consvar_t cv_autorecord = {"autorecord", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
|
@ -731,6 +735,7 @@ static menuitem_t SR_EmblemHintMenu[] =
|
||||||
// Single Player Main
|
// Single Player Main
|
||||||
static menuitem_t SP_MainMenu[] =
|
static menuitem_t SP_MainMenu[] =
|
||||||
{
|
{
|
||||||
|
{IT_CALL | IT_STRING, NULL, "Tutorial", M_StartTutorial, 84},
|
||||||
{IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 92},
|
{IT_CALL | IT_STRING, NULL, "Start Game", M_LoadGame, 92},
|
||||||
{IT_SECRET, NULL, "Record Attack", M_TimeAttack, 100},
|
{IT_SECRET, NULL, "Record Attack", M_TimeAttack, 100},
|
||||||
{IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 108},
|
{IT_SECRET, NULL, "NiGHTS Mode", M_NightsAttack, 108},
|
||||||
|
@ -739,6 +744,7 @@ static menuitem_t SP_MainMenu[] =
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
sptutorial,
|
||||||
sploadgame,
|
sploadgame,
|
||||||
sprecordattack,
|
sprecordattack,
|
||||||
spnightsmode,
|
spnightsmode,
|
||||||
|
@ -1554,7 +1560,18 @@ menu_t SR_EmblemHintDef =
|
||||||
};
|
};
|
||||||
|
|
||||||
// Single Player
|
// Single Player
|
||||||
menu_t SP_MainDef = CENTERMENUSTYLE(NULL, SP_MainMenu, &MainDef, 72);
|
menu_t SP_MainDef = //CENTERMENUSTYLE(NULL, SP_MainMenu, &MainDef, 72);
|
||||||
|
{
|
||||||
|
NULL,
|
||||||
|
sizeof(SP_MainMenu)/sizeof(menuitem_t),
|
||||||
|
&MainDef,
|
||||||
|
SP_MainMenu,
|
||||||
|
M_DrawCenteredMenu,
|
||||||
|
BASEVIDWIDTH/2, 72,
|
||||||
|
1, // start at "Start Game" on first entry
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
menu_t SP_LoadDef =
|
menu_t SP_LoadDef =
|
||||||
{
|
{
|
||||||
"M_PICKG",
|
"M_PICKG",
|
||||||
|
@ -6093,6 +6110,8 @@ static void M_CustomLevelSelect(INT32 choice)
|
||||||
static void M_SinglePlayerMenu(INT32 choice)
|
static void M_SinglePlayerMenu(INT32 choice)
|
||||||
{
|
{
|
||||||
(void)choice;
|
(void)choice;
|
||||||
|
SP_MainMenu[sptutorial].status =
|
||||||
|
tutorialmap ? IT_CALL|IT_STRING : IT_NOTHING|IT_DISABLED;
|
||||||
SP_MainMenu[sprecordattack].status =
|
SP_MainMenu[sprecordattack].status =
|
||||||
(M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET;
|
(M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET;
|
||||||
SP_MainMenu[spnightsmode].status =
|
SP_MainMenu[spnightsmode].status =
|
||||||
|
@ -6118,6 +6137,80 @@ static void M_LoadGameLevelSelect(INT32 choice)
|
||||||
M_SetupNextMenu(&SP_LevelSelectDef);
|
M_SetupNextMenu(&SP_LevelSelectDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void M_TutorialSaveControlResponse(INT32 ch)
|
||||||
|
{
|
||||||
|
if (ch == 'y' || ch == KEY_ENTER)
|
||||||
|
{
|
||||||
|
G_CopyControls(gamecontrol, gamecontroldefault[tutorialgcs], gcl_tutorial_full, num_gcl_tutorial_full);
|
||||||
|
CV_Set(&cv_usemouse, cv_usemouse.defaultvalue);
|
||||||
|
CV_Set(&cv_alwaysfreelook, cv_alwaysfreelook.defaultvalue);
|
||||||
|
CV_Set(&cv_mousemove, cv_mousemove.defaultvalue);
|
||||||
|
CV_Set(&cv_analog, cv_analog.defaultvalue);
|
||||||
|
S_StartSound(NULL, sfx_itemup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void M_TutorialControlResponse(INT32 ch)
|
||||||
|
{
|
||||||
|
if (ch != KEY_ESCAPE)
|
||||||
|
{
|
||||||
|
G_CopyControls(gamecontroldefault[gcs_custom], gamecontrol, NULL, 0); // using gcs_custom as temp storage for old controls
|
||||||
|
if (ch == 'y' || ch == KEY_ENTER)
|
||||||
|
{
|
||||||
|
tutorialgcs = gcs_fps;
|
||||||
|
tutorialusemouse = cv_usemouse.value;
|
||||||
|
tutorialfreelook = cv_alwaysfreelook.value;
|
||||||
|
tutorialmousemove = cv_mousemove.value;
|
||||||
|
tutorialanalog = cv_analog.value;
|
||||||
|
|
||||||
|
G_CopyControls(gamecontrol, gamecontroldefault[tutorialgcs], gcl_tutorial_full, num_gcl_tutorial_full);
|
||||||
|
CV_Set(&cv_usemouse, cv_usemouse.defaultvalue);
|
||||||
|
CV_Set(&cv_alwaysfreelook, cv_alwaysfreelook.defaultvalue);
|
||||||
|
CV_Set(&cv_mousemove, cv_mousemove.defaultvalue);
|
||||||
|
CV_Set(&cv_analog, cv_analog.defaultvalue);
|
||||||
|
|
||||||
|
//S_StartSound(NULL, sfx_itemup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tutorialgcs = gcs_custom;
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
}
|
||||||
|
M_StartTutorial(INT32_MAX);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
|
||||||
|
MessageDef.prevMenu = &SP_MainDef; // if FirstPrompt -> ControlsPrompt -> ESC, we would go to the main menu unless we force this
|
||||||
|
}
|
||||||
|
|
||||||
|
// Starts up the tutorial immediately (tbh I wasn't sure where else to put this)
|
||||||
|
static void M_StartTutorial(INT32 choice)
|
||||||
|
{
|
||||||
|
if (!tutorialmap)
|
||||||
|
return; // no map to go to, don't bother
|
||||||
|
|
||||||
|
if (choice != INT32_MAX && G_GetControlScheme(gamecontrol, gcl_tutorial_check, num_gcl_tutorial_check) != gcs_fps)
|
||||||
|
{
|
||||||
|
M_StartMessage("Do you want to try the \202recommended \202movement controls\x80?\n\nWe will set them just for this tutorial.\n\nPress 'Y' or 'Enter' to confirm\nPress 'N' or any key to keep \nyour current controls.\n",M_TutorialControlResponse,MM_YESNO);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (choice != INT32_MAX)
|
||||||
|
tutorialgcs = gcs_custom;
|
||||||
|
|
||||||
|
CV_SetValue(&cv_tutorialprompt, 0); // first-time prompt
|
||||||
|
|
||||||
|
tutorialmode = true; // turn on tutorial mode
|
||||||
|
|
||||||
|
emeralds = 0;
|
||||||
|
M_ClearMenus(true);
|
||||||
|
gamecomplete = false;
|
||||||
|
cursaveslot = 0;
|
||||||
|
G_DeferedInitNew(false, G_BuildMapName(tutorialmap), 0, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
// ==============
|
// ==============
|
||||||
// LOAD GAME MENU
|
// LOAD GAME MENU
|
||||||
// ==============
|
// ==============
|
||||||
|
@ -6725,6 +6818,26 @@ static void M_HandleLoadSave(INT32 choice)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void M_FirstTimeResponse(INT32 ch)
|
||||||
|
{
|
||||||
|
S_StartSound(NULL, sfx_menu1);
|
||||||
|
|
||||||
|
if (ch == KEY_ESCAPE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ch != 'y' && ch != KEY_ENTER)
|
||||||
|
{
|
||||||
|
CV_SetValue(&cv_tutorialprompt, 0);
|
||||||
|
M_ReadSaveStrings();
|
||||||
|
MessageDef.prevMenu = &SP_LoadDef; // calls M_SetupNextMenu
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
M_StartTutorial(0);
|
||||||
|
MessageDef.prevMenu = &MessageDef; // otherwise, the controls prompt won't fire
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Selected from SRB2 menu
|
// Selected from SRB2 menu
|
||||||
//
|
//
|
||||||
|
@ -6732,6 +6845,13 @@ static void M_LoadGame(INT32 choice)
|
||||||
{
|
{
|
||||||
(void)choice;
|
(void)choice;
|
||||||
|
|
||||||
|
if (tutorialmap && cv_tutorialprompt.value)
|
||||||
|
{
|
||||||
|
M_StartMessage("Do you want to \x82play a brief Tutorial\x80?\n\nWe highly recommend this because \nthe controls are slightly different \nfrom other games.\n\nPress 'Y' or 'Enter' to go\nPress 'N' or any key to skip\n",
|
||||||
|
M_FirstTimeResponse, MM_YESNO);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
M_ReadSaveStrings();
|
M_ReadSaveStrings();
|
||||||
M_SetupNextMenu(&SP_LoadDef);
|
M_SetupNextMenu(&SP_LoadDef);
|
||||||
}
|
}
|
||||||
|
@ -9198,9 +9318,17 @@ static void M_DrawControl(void)
|
||||||
// draw title (or big pic)
|
// draw title (or big pic)
|
||||||
M_DrawMenuTitle();
|
M_DrawMenuTitle();
|
||||||
|
|
||||||
M_CentreText(30,
|
if (tutorialmode && tutorialgcs)
|
||||||
(setupcontrols_secondaryplayer ? "SET CONTROLS FOR SECONDARY PLAYER" :
|
{
|
||||||
"PRESS ENTER TO CHANGE, BACKSPACE TO CLEAR"));
|
if ((gametic / TICRATE) % 2)
|
||||||
|
M_CentreText(30, "\202EXIT THE TUTORIAL TO CHANGE THE CONTROLS");
|
||||||
|
else
|
||||||
|
M_CentreText(30, "EXIT THE TUTORIAL TO CHANGE THE CONTROLS");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
M_CentreText(30,
|
||||||
|
(setupcontrols_secondaryplayer ? "SET CONTROLS FOR SECONDARY PLAYER" :
|
||||||
|
"PRESS ENTER TO CHANGE, BACKSPACE TO CLEAR"));
|
||||||
|
|
||||||
if (i)
|
if (i)
|
||||||
V_DrawString(currentMenu->x - 16, y-(skullAnimCounter/5), V_YELLOWMAP, "\x1A"); // up arrow
|
V_DrawString(currentMenu->x - 16, y-(skullAnimCounter/5), V_YELLOWMAP, "\x1A"); // up arrow
|
||||||
|
@ -9335,6 +9463,9 @@ static void M_ChangeControl(INT32 choice)
|
||||||
{
|
{
|
||||||
static char tmp[55];
|
static char tmp[55];
|
||||||
|
|
||||||
|
if (tutorialmode && tutorialgcs) // don't allow control changes if temp control override is active
|
||||||
|
return;
|
||||||
|
|
||||||
controltochange = currentMenu->menuitems[choice].alphaKey;
|
controltochange = currentMenu->menuitems[choice].alphaKey;
|
||||||
sprintf(tmp, M_GetText("Hit the new key for\n%s\nESC for Cancel"),
|
sprintf(tmp, M_GetText("Hit the new key for\n%s\nESC for Cancel"),
|
||||||
currentMenu->menuitems[choice].text);
|
currentMenu->menuitems[choice].text);
|
||||||
|
|
|
@ -240,6 +240,8 @@ extern INT16 char_on, startchar;
|
||||||
|
|
||||||
#define BwehHehHe() S_StartSound(NULL, sfx_bewar1+M_RandomKey(4)) // Bweh heh he
|
#define BwehHehHe() S_StartSound(NULL, sfx_bewar1+M_RandomKey(4)) // Bweh heh he
|
||||||
|
|
||||||
|
void M_TutorialSaveControlResponse(INT32 ch);
|
||||||
|
|
||||||
void M_ForceSaveSlotSelected(INT32 sslot);
|
void M_ForceSaveSlotSelected(INT32 sslot);
|
||||||
|
|
||||||
void M_CheatActivationResponder(INT32 ch);
|
void M_CheatActivationResponder(INT32 ch);
|
||||||
|
|
16
src/m_misc.c
16
src/m_misc.c
|
@ -539,7 +539,21 @@ void M_SaveConfig(const char *filename)
|
||||||
|
|
||||||
// FIXME: save key aliases if ever implemented..
|
// FIXME: save key aliases if ever implemented..
|
||||||
|
|
||||||
CV_SaveVariables(f);
|
if (tutorialmode && tutorialgcs)
|
||||||
|
{
|
||||||
|
CV_SetValue(&cv_usemouse, tutorialusemouse);
|
||||||
|
CV_SetValue(&cv_alwaysfreelook, tutorialfreelook);
|
||||||
|
CV_SetValue(&cv_mousemove, tutorialmousemove);
|
||||||
|
CV_SetValue(&cv_analog, tutorialanalog);
|
||||||
|
CV_SaveVariables(f);
|
||||||
|
CV_Set(&cv_usemouse, cv_usemouse.defaultvalue);
|
||||||
|
CV_Set(&cv_alwaysfreelook, cv_alwaysfreelook.defaultvalue);
|
||||||
|
CV_Set(&cv_mousemove, cv_mousemove.defaultvalue);
|
||||||
|
CV_Set(&cv_analog, cv_analog.defaultvalue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CV_SaveVariables(f);
|
||||||
|
|
||||||
if (!dedicated)
|
if (!dedicated)
|
||||||
{
|
{
|
||||||
if (tutorialmode && tutorialgcs)
|
if (tutorialmode && tutorialgcs)
|
||||||
|
|
13
src/p_user.c
13
src/p_user.c
|
@ -8785,7 +8785,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
|
|
||||||
cameranoclip = (player->powers[pw_carry] == CR_NIGHTSMODE || player->pflags & PF_NOCLIP) || (mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)); // Noclipping player camera noclips too!!
|
cameranoclip = (player->powers[pw_carry] == CR_NIGHTSMODE || player->pflags & PF_NOCLIP) || (mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)); // Noclipping player camera noclips too!!
|
||||||
|
|
||||||
if (!(player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD))
|
if (!(player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || tutorialmode))
|
||||||
{
|
{
|
||||||
if (player->spectator) // force cam off for spectators
|
if (player->spectator) // force cam off for spectators
|
||||||
return true;
|
return true;
|
||||||
|
@ -8848,7 +8848,16 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
||||||
if (P_CameraThinker(player, thiscam, resetcalled))
|
if (P_CameraThinker(player, thiscam, resetcalled))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (thiscam == &camera)
|
if (tutorialmode)
|
||||||
|
{
|
||||||
|
// force defaults because we have a camera look section
|
||||||
|
camspeed = (INT32)(atof(cv_cam_speed.defaultvalue) * FRACUNIT);
|
||||||
|
camstill = (!stricmp(cv_cam_still.defaultvalue, "off")) ? false : true;
|
||||||
|
camrotate = atoi(cv_cam_rotate.defaultvalue);
|
||||||
|
camdist = FixedMul((INT32)(atof(cv_cam_dist.defaultvalue) * FRACUNIT), mo->scale);
|
||||||
|
camheight = FixedMul((INT32)(atof(cv_cam_height.defaultvalue) * FRACUNIT), FixedMul(player->camerascale, mo->scale));
|
||||||
|
}
|
||||||
|
else if (thiscam == &camera)
|
||||||
{
|
{
|
||||||
camspeed = cv_cam_speed.value;
|
camspeed = cv_cam_speed.value;
|
||||||
camstill = cv_cam_still.value;
|
camstill = cv_cam_still.value;
|
||||||
|
|
|
@ -913,7 +913,7 @@ void R_SetupFrame(player_t *player, boolean skybox)
|
||||||
chasecam = (cv_chasecam.value != 0);
|
chasecam = (cv_chasecam.value != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || gamestate == GS_TITLESCREEN)
|
if (player->climbing || (player->powers[pw_carry] == CR_NIGHTSMODE) || player->playerstate == PST_DEAD || gamestate == GS_TITLESCREEN || tutorialmode)
|
||||||
chasecam = true; // force chasecam on
|
chasecam = true; // force chasecam on
|
||||||
else if (player->spectator) // no spectator chasecam
|
else if (player->spectator) // no spectator chasecam
|
||||||
chasecam = false; // force chasecam off
|
chasecam = false; // force chasecam off
|
||||||
|
|
Loading…
Reference in a new issue