1
0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-06-02 19:13:31 +02:00

Refactor scriptclass::startgamemode

This overhauls scriptclass::gamemode massively.

The first change is that it now uses an enum, and enforces using that
enum via using its type instead of an int. This is because whenever
you're reading any calls to startgamemode, you have no idea what magic
number actually corresponds to what unless you read startgamemode
itself. And when you do read it, not every case is commented adequately,
so you'd have to do more work to figure out what each case is. With the
enum, it's obvious and self-evident, and that also removes the need for
all the comments in the function too. Some math is still done on mode
variables (to simplify time trial code), but it's okay, we can just cast
between int and the enum as needed.

The second is that common code is now de-duplicated. There was a lot of
code that every case does, such as calling hardreset, setting Flip Mode,
resetting the player, calling gotoroom and so on.

Now some code may be duplicated between cases, so I've tried to group up
similar cases where possible (most notable example is grouping up the
main game and No Death Mode cases together). But some code still might
be duplicated in the end. Which is okay - I could've tried to
de-duplicate it further but that just results in logic relevant to a
specific case that's located far from the actual case itself. It's much
better to leave things like setting fademode or loading scripts in the
case itself.

This also fixes a bug since 2.3 where playing No Death Mode (and never
opening and closing the options menu) and beating it would also give you
the Flip Mode trophy, since turning on the flag to invalidate Flip Mode
in startgamemode only happened for the main game cases and in previous
versions the game relied upon this flag being set when using a
teleporter for some reason (which I removed in 2.3). Now instead of
specifying it per case, I just do a !map.custommode check instead so it
covers every single case at once.
This commit is contained in:
Misa 2022-12-29 14:01:36 -08:00
parent 6768a33f2d
commit 69e9a32e1b
5 changed files with 268 additions and 554 deletions

View File

@ -2796,7 +2796,7 @@ void editorinput(void)
graphics.backgrounddrawn=false;
ed.returneditoralpha = 1000; // Let's start it higher than 255 since it gets clamped
ed.oldreturneditoralpha = 1000;
script.startgamemode(21);
script.startgamemode(Start_EDITORPLAYTESTING);
}
}
}

View File

@ -279,9 +279,9 @@ static void toggleflipmode(void)
static bool fadetomode = false;
static int fadetomodedelay = 0;
static int gotomode = 0;
static enum StartMode gotomode = Start_MAINGAME;
static void startmode(const int mode)
static void startmode(const enum StartMode mode)
{
gotomode = mode;
graphics.fademode = FADE_START_FADEOUT;
@ -387,7 +387,7 @@ static void menuactionpress(void)
{
//No saves exist, just start a new game
music.playef(11);
startmode(0);
startmode(Start_MAINGAME);
}
else
{
@ -475,7 +475,7 @@ static void menuactionpress(void)
std::string name = "saves/" + cl.ListOfMetaData[game.playcustomlevel].filename.substr(7) + ".vvv";
tinyxml2::XMLDocument doc;
if (!FILESYSTEM_loadTiXml2Document(name.c_str(), doc)){
startmode(22);
startmode(Start_CUSTOM);
}else{
game.createmenu(Menu::quickloadlevel);
map.nexttowercolour();
@ -489,11 +489,11 @@ static void menuactionpress(void)
{
case 0: //continue save
music.playef(11);
startmode(23);
startmode(Start_CUSTOM_QUICKSAVE);
break;
case 1:
music.playef(11);
startmode(22);
startmode(Start_CUSTOM);
break;
case 2:
music.playef(11);
@ -550,7 +550,7 @@ static void menuactionpress(void)
case 1:
//LEVEL EDITOR HOOK
music.playef(11);
startmode(20);
startmode(Start_EDITOR);
ed.filename="";
break;
#endif
@ -682,7 +682,7 @@ static void menuactionpress(void)
case 0:
//bye!
music.playef(2);
startmode(100);
startmode(Start_QUIT);
break;
default:
music.playef(11);
@ -1433,19 +1433,19 @@ static void menuactionpress(void)
{
//You have no saves but have something unlocked, or you couldn't have gotten here
music.playef(11);
startmode(0);
startmode(Start_MAINGAME);
}
else if (game.telesummary == "")
{
//You at least have a quicksave, or you couldn't have gotten here
music.playef(11);
startmode(2);
startmode(Start_MAINGAME_QUICKSAVE);
}
else if (game.quicksummary == "")
{
//You at least have a telesave, or you couldn't have gotten here
music.playef(11);
startmode(1);
startmode(Start_MAINGAME_TELESAVE);
}
else
{
@ -1458,7 +1458,7 @@ static void menuactionpress(void)
else if (game.currentmenuoption == 1 && game.unlock[8])
{
music.playef(11);
startmode(11);
startmode(Start_SECRETLAB);
}
else if (game.currentmenuoption == sloffset+2)
{
@ -1489,7 +1489,7 @@ static void menuactionpress(void)
case 0:
//yep
music.playef(11);
startmode(0);
startmode(Start_MAINGAME);
game.deletequick();
game.deletetele();
break;
@ -1602,11 +1602,11 @@ static void menuactionpress(void)
{
case 0: //start no death mode, disabling cutscenes
music.playef(11);
startmode(10);
startmode(Start_NODEATHMODE_NOCUTSCENES);
break;
case 1:
music.playef(11);
startmode(9);
startmode(Start_NODEATHMODE_WITHCUTSCENES);
break;
case 2:
//back
@ -1621,11 +1621,11 @@ static void menuactionpress(void)
{
case 0:
music.playef(11);
startmode(1);
startmode(Start_MAINGAME_TELESAVE);
break;
case 1:
music.playef(11);
startmode(2);
startmode(Start_MAINGAME_QUICKSAVE);
break;
case 2:
//back
@ -1663,19 +1663,19 @@ static void menuactionpress(void)
{
case 0:
music.playef(11);
startmode(12);
startmode(Start_INTERMISSION1_VITELLARY);
break;
case 1:
music.playef(11);
startmode(13);
startmode(Start_INTERMISSION1_VERMILION);
break;
case 2:
music.playef(11);
startmode(14);
startmode(Start_INTERMISSION1_VERDIGRIS);
break;
case 3:
music.playef(11);
startmode(15);
startmode(Start_INTERMISSION1_VICTORIA);
break;
case 4:
//back
@ -1690,19 +1690,19 @@ static void menuactionpress(void)
{
case 0:
music.playef(11);
startmode(16);
startmode(Start_INTERMISSION2_VITELLARY);
break;
case 1:
music.playef(11);
startmode(17);
startmode(Start_INTERMISSION2_VERMILION);
break;
case 2:
music.playef(11);
startmode(18);
startmode(Start_INTERMISSION2_VERDIGRIS);
break;
case 3:
music.playef(11);
startmode(19);
startmode(Start_INTERMISSION2_VICTORIA);
break;
case 4:
//back
@ -1730,37 +1730,37 @@ static void menuactionpress(void)
map.nexttowercolour();
break;
case Menu::timetrials:
if (game.currentmenuoption == 0 && game.unlock[9]) //space station 1
if (game.currentmenuoption == 0 && game.unlock[9])
{
music.playef(11);
startmode(3);
startmode(Start_TIMETRIAL_SPACESTATION1);
}
else if (game.currentmenuoption == 1 && game.unlock[10]) //lab
else if (game.currentmenuoption == 1 && game.unlock[10])
{
music.playef(11);
startmode(4);
startmode(Start_TIMETRIAL_LABORATORY);
}
else if (game.currentmenuoption == 2 && game.unlock[11]) //tower
else if (game.currentmenuoption == 2 && game.unlock[11])
{
music.playef(11);
startmode(5);
startmode(Start_TIMETRIAL_TOWER);
}
else if (game.currentmenuoption == 3 && game.unlock[12]) //station 2
else if (game.currentmenuoption == 3 && game.unlock[12])
{
music.playef(11);
startmode(6);
startmode(Start_TIMETRIAL_SPACESTATION2);
}
else if (game.currentmenuoption == 4 && game.unlock[13]) //warp
else if (game.currentmenuoption == 4 && game.unlock[13])
{
music.playef(11);
startmode(7);
startmode(Start_TIMETRIAL_WARPZONE);
}
else if (game.currentmenuoption == 5 && game.unlock[14]) //final
else if (game.currentmenuoption == 5 && game.unlock[14])
{
music.playef(11);
startmode(8);
startmode(Start_TIMETRIAL_FINALLEVEL);
}
else if (game.currentmenuoption == 6) //go to the time trial menu
else if (game.currentmenuoption == 6)
{
//back
music.playef(11);
@ -1784,37 +1784,9 @@ static void menuactionpress(void)
map.nexttowercolour();
break;
case 1:
//duplicate the above based on given time trial level!
if (game.timetriallevel == 0) //space station 1
{
music.playef(11);
startmode(3);
}
else if (game.timetriallevel == 1) //lab
{
music.playef(11);
startmode(4);
}
else if (game.timetriallevel == 2) //tower
{
music.playef(11);
startmode(5);
}
else if (game.timetriallevel == 3) //station 2
{
music.playef(11);
startmode(6);
}
else if (game.timetriallevel == 4) //warp
{
music.playef(11);
startmode(7);
}
else if (game.timetriallevel == 5) //final
{
music.playef(11);
startmode(8);
}
/* Replay time trial */
music.playef(11);
startmode((enum StartMode) (game.timetriallevel + Start_FIRST_TIMETRIAL));
break;
}
break;
@ -2078,7 +2050,7 @@ void gameinput(void)
{
//restart the time trial
game.quickrestartkludge = false;
script.startgamemode(game.timetriallevel + 3);
script.startgamemode((enum StartMode) (game.timetriallevel + Start_FIRST_TIMETRIAL));
game.deathseq = -1;
game.completestop = false;
game.hascontrol = false;

View File

@ -14,6 +14,7 @@
#include "KeyPoll.h"
#include "Map.h"
#include "Music.h"
#include "Unreachable.h"
#include "UtilityClass.h"
#include "Vlogging.h"
#include "Xoshiro.h"
@ -2380,490 +2381,206 @@ static void gotoerrorloadinglevel(void)
music.play(6); /* title screen music */
}
void scriptclass::startgamemode( int t )
#define DECLARE_MODE_FUNC(funcname, modename) \
static bool funcname(const enum StartMode mode) \
{ \
return mode >= Start_FIRST_##modename && mode <= Start_LAST_##modename; \
}
DECLARE_MODE_FUNC(is_no_death_mode, NODEATHMODE)
DECLARE_MODE_FUNC(is_intermission_1, INTERMISSION1)
DECLARE_MODE_FUNC(is_intermission_2, INTERMISSION2)
#undef DECLARE_MODE_FUNC
void scriptclass::startgamemode(const enum StartMode mode)
{
switch(t)
if (mode == Start_QUIT)
{
VVV_exit(0);
}
hardreset();
if (mode == Start_EDITOR)
{
game.gamestate = EDITORMODE;
}
else
{
case 0: //Normal new game
game.gamestate = GAMEMODE;
hardreset();
}
game.jumpheld = true;
switch (mode)
{
case Start_MAINGAME:
case Start_MAINGAME_TELESAVE:
case Start_MAINGAME_QUICKSAVE:
case Start_NODEATHMODE_WITHCUTSCENES:
case Start_NODEATHMODE_NOCUTSCENES:
game.nodeathmode = is_no_death_mode(mode);
game.nocutscenes = (mode == Start_NODEATHMODE_NOCUTSCENES);
game.start();
game.jumpheld = true;
graphics.showcutscenebars = true;
graphics.setbars(320);
//set flipmode
if (graphics.setflipmode) graphics.flipmode = true;
else obj.flags[73] = true;
if(obj.entities.empty())
switch (mode)
{
obj.createentity(game.savex, game.savey, 0, 0); //In this game, constant, never destroyed
case Start_MAINGAME_TELESAVE:
game.loadtele();
graphics.fademode = FADE_START_FADEIN;
break;
case Start_MAINGAME_QUICKSAVE:
game.loadquick();
graphics.fademode = FADE_START_FADEIN;
break;
default:
graphics.showcutscenebars = true;
graphics.setbars(320);
load("intro");
}
map.resetplayer();
map.gotoroom(game.saverx, game.savery);
map.initmapdata();
load("intro");
break;
case 1:
game.gamestate = GAMEMODE;
hardreset();
game.start();
game.loadtele();
game.gravitycontrol = game.savegc;
game.jumpheld = true;
//set flipmode
if (graphics.setflipmode) graphics.flipmode = true;
else obj.flags[73] = true;
if(obj.entities.empty())
{
obj.createentity(game.savex, game.savey, 0, 0); //In this game, constant, never destroyed
}
map.resetplayer();
map.gotoroom(game.saverx, game.savery);
map.initmapdata();
graphics.fademode = FADE_START_FADEIN;
break;
case 2: //Load Quicksave
game.gamestate = GAMEMODE;
hardreset();
game.start();
game.loadquick();
game.gravitycontrol = game.savegc;
game.jumpheld = true;
//set flipmode
if (graphics.setflipmode) graphics.flipmode = true;
else obj.flags[73] = true;
if(obj.entities.empty())
{
obj.createentity(game.savex, game.savey, 0, 0); //In this game, constant, never destroyed
}
map.resetplayer();
map.gotoroom(game.saverx, game.savery);
map.initmapdata();
//a very special case for here needs to ensure that the tower is set correctly
if (map.towermode)
{
map.resetplayer();
i = obj.getplayer();
if (INBOUNDS_VEC(i, obj.entities))
{
map.ypos = obj.entities[i].yp - 120;
map.oldypos = map.ypos;
}
map.setbgobjlerp(graphics.towerbg);
map.cameramode = 0;
map.colsuperstate = 0;
}
graphics.fademode = FADE_START_FADEIN;
break;
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
//Start Time Trial
case Start_TIMETRIAL_SPACESTATION1:
case Start_TIMETRIAL_LABORATORY:
case Start_TIMETRIAL_TOWER:
case Start_TIMETRIAL_SPACESTATION2:
case Start_TIMETRIAL_WARPZONE:
case Start_TIMETRIAL_FINALLEVEL:
music.fadeout();
hardreset();
game.nocutscenes = true;
game.intimetrial = true;
game.timetrialcountdown = 150;
game.timetrialparlost = false;
game.timetriallevel = t - 3;
game.timetriallevel = mode - Start_FIRST_TIMETRIAL;
switch (t)
switch (mode)
{
case 3:
case Start_TIMETRIAL_SPACESTATION1:
game.timetrialpar = 75;
game.timetrialshinytarget = 2;
break;
case 4:
case Start_TIMETRIAL_LABORATORY:
game.timetrialpar = 165;
game.timetrialshinytarget = 4;
break;
case 5:
case Start_TIMETRIAL_TOWER:
game.timetrialpar = 105;
game.timetrialshinytarget = 2;
break;
case 6:
case Start_TIMETRIAL_SPACESTATION2:
game.timetrialpar = 200;
game.timetrialshinytarget = 5;
break;
case 7:
case Start_TIMETRIAL_WARPZONE:
game.timetrialpar = 120;
game.timetrialshinytarget = 1;
break;
case 8:
case Start_TIMETRIAL_FINALLEVEL:
game.timetrialpar = 135;
game.timetrialshinytarget = 1;
map.finalmode = true; //Enable final level mode
map.finalmode = true;
map.final_colormode = false;
map.final_mapcol = 0;
map.final_colorframe = 0;
break;
default:
VVV_unreachable();
}
game.gamestate = GAMEMODE;
game.starttrial(game.timetriallevel);
game.jumpheld = true;
if (graphics.setflipmode) graphics.flipmode = true;//set flipmode
if (obj.entities.empty())
{
obj.createentity(game.savex, game.savey, 0, 0); //In this game, constant, never destroyed
}
map.resetplayer();
map.gotoroom(game.saverx, game.savery);
map.initmapdata();
graphics.fademode = FADE_START_FADEIN;
break;
case 9:
game.gamestate = GAMEMODE;
hardreset();
game.nodeathmode = true;
game.start();
game.jumpheld = true;
graphics.showcutscenebars = true;
graphics.setbars(320);
//set flipmode
if (graphics.setflipmode) graphics.flipmode = true;
if(obj.entities.empty())
{
obj.createentity(game.savex, game.savey, 0, 0); //In this game, constant, never destroyed
}
map.resetplayer();
map.gotoroom(game.saverx, game.savery);
map.initmapdata();
load("intro");
break;
case 10:
game.gamestate = GAMEMODE;
hardreset();
game.nodeathmode = true;
game.nocutscenes = true;
game.start();
game.jumpheld = true;
graphics.showcutscenebars = true;
graphics.setbars(320);
//set flipmode
if (graphics.setflipmode) graphics.flipmode = true;
if(obj.entities.empty())
{
obj.createentity(game.savex, game.savey, 0, 0); //In this game, constant, never destroyed
}
map.resetplayer();
map.gotoroom(game.saverx, game.savery);
map.initmapdata();
load("intro");
break;
case 11:
game.gamestate = GAMEMODE;
hardreset();
case Start_SECRETLAB:
game.startspecial(0);
game.jumpheld = true;
//Secret lab, so reveal the map, give them all 20 trinkets
/* Unlock the entire map */
SDL_memset(obj.collect, true, sizeof(obj.collect[0]) * 20);
/* Give all 20 trinkets */
SDL_memset(map.explored, true, sizeof(map.explored));
i = 400; /* previously a nested for-loop set this */
game.insecretlab = true;
map.showteleporters = true;
//set flipmode
if (graphics.setflipmode) graphics.flipmode = true;
if(obj.entities.empty())
{
obj.createentity(game.savex, game.savey, 0, 0); //In this game, constant, never destroyed
}
map.resetplayer();
map.gotoroom(game.saverx, game.savery);
map.initmapdata();
music.play(11);
graphics.fademode = FADE_START_FADEIN;
break;
case 12:
game.gamestate = GAMEMODE;
hardreset();
case Start_INTERMISSION1_VITELLARY:
case Start_INTERMISSION1_VERMILION:
case Start_INTERMISSION1_VERDIGRIS:
case Start_INTERMISSION1_VICTORIA:
case Start_INTERMISSION2_VITELLARY:
case Start_INTERMISSION2_VERMILION:
case Start_INTERMISSION2_VERDIGRIS:
case Start_INTERMISSION2_VICTORIA:
music.fadeout();
game.lastsaved = 2;
switch (mode)
{
case Start_INTERMISSION1_VITELLARY:
case Start_INTERMISSION2_VITELLARY:
game.lastsaved = 2;
break;
case Start_INTERMISSION1_VERMILION:
case Start_INTERMISSION2_VERMILION:
game.lastsaved = 3;
break;
case Start_INTERMISSION1_VERDIGRIS:
case Start_INTERMISSION2_VERDIGRIS:
game.lastsaved = 4;
break;
case Start_INTERMISSION1_VICTORIA:
case Start_INTERMISSION2_VICTORIA:
game.lastsaved = 5;
break;
default:
VVV_unreachable();
}
game.crewstats[game.lastsaved] = true;
game.inintermission = true;
game.companion = 11;
game.supercrewmate = true;
game.scmprogress = 0;
if (is_intermission_1(mode))
{
game.companion = 11;
game.supercrewmate = true;
game.scmprogress = 0;
}
map.finalmode = true;
map.final_colormode = false;
map.final_mapcol = 0;
map.final_colorframe = 0;
game.startspecial(1);
game.jumpheld = true;
//set flipmode
if (graphics.setflipmode) graphics.flipmode = true;
if(obj.entities.empty())
if (is_intermission_1(mode))
{
obj.createentity(game.savex, game.savey, 0, 0); //In this game, constant, never destroyed
load("intermission_1");
}
map.resetplayer();
map.gotoroom(game.saverx, game.savery);
map.initmapdata();
load("intermission_1");
break;
case 13:
game.gamestate = GAMEMODE;
hardreset();
music.fadeout();
game.lastsaved = 3;
game.crewstats[game.lastsaved] = true;
game.inintermission = true;
game.companion = 11;
game.supercrewmate = true;
game.scmprogress = 0;
map.finalmode = true;
map.final_colormode = false;
map.final_mapcol = 0;
map.final_colorframe = 0;
game.startspecial(1);
game.jumpheld = true;
//set flipmode
if (graphics.setflipmode) graphics.flipmode = true;
if(obj.entities.empty())
else if (is_intermission_2(mode))
{
obj.createentity(game.savex, game.savey, 0, 0); //In this game, constant, never destroyed
load("intermission_2");
}
map.resetplayer();
map.gotoroom(game.saverx, game.savery);
map.initmapdata();
load("intermission_1");
break;
case 14:
game.gamestate = GAMEMODE;
hardreset();
music.fadeout();
game.lastsaved = 4;
game.crewstats[game.lastsaved] = true;
game.inintermission = true;
game.companion = 11;
game.supercrewmate = true;
game.scmprogress = 0;
map.finalmode = true;
map.final_colormode = false;
map.final_mapcol = 0;
map.final_colorframe = 0;
game.startspecial(1);
game.jumpheld = true;
//set flipmode
if (graphics.setflipmode) graphics.flipmode = true;
if(obj.entities.empty())
{
obj.createentity(game.savex, game.savey, 0, 0); //In this game, constant, never destroyed
}
map.resetplayer();
map.gotoroom(game.saverx, game.savery);
map.initmapdata();
load("intermission_1");
break;
case 15:
game.gamestate = GAMEMODE;
hardreset();
music.fadeout();
game.lastsaved = 5;
game.crewstats[game.lastsaved] = true;
game.inintermission = true;
game.companion = 11;
game.supercrewmate = true;
game.scmprogress = 0;
map.finalmode = true;
map.final_colormode = false;
map.final_mapcol = 0;
map.final_colorframe = 0;
game.startspecial(1);
game.jumpheld = true;
//set flipmode
if (graphics.setflipmode) graphics.flipmode = true;
if(obj.entities.empty())
{
obj.createentity(game.savex, game.savey, 0, 0); //In this game, constant, never destroyed
}
map.resetplayer();
map.gotoroom(game.saverx, game.savery);
map.initmapdata();
load("intermission_1");
break;
case 16:
game.gamestate = GAMEMODE;
hardreset();
music.fadeout();
game.lastsaved = 2;
game.crewstats[game.lastsaved] = true;
game.inintermission = true;
map.finalmode = true;
map.final_colormode = false;
map.final_mapcol = 0;
map.final_colorframe = 0;
game.startspecial(1);
game.jumpheld = true;
//set flipmode
if (graphics.setflipmode) graphics.flipmode = true;
if(obj.entities.empty())
{
obj.createentity(game.savex, game.savey, 0, 0); //In this game, constant, never destroyed
}
map.resetplayer();
map.gotoroom(game.saverx, game.savery);
map.initmapdata();
load("intermission_2");
break;
case 17:
game.gamestate = GAMEMODE;
hardreset();
music.fadeout();
game.lastsaved = 3;
game.crewstats[game.lastsaved] = true;
game.inintermission = true;
map.finalmode = true;
map.final_colormode = false;
map.final_mapcol = 0;
map.final_colorframe = 0;
game.startspecial(1);
game.jumpheld = true;
//set flipmode
if (graphics.setflipmode) graphics.flipmode = true;
if(obj.entities.empty())
{
obj.createentity(game.savex, game.savey, 0, 0); //In this game, constant, never destroyed
}
map.resetplayer();
map.gotoroom(game.saverx, game.savery);
map.initmapdata();
load("intermission_2");
break;
case 18:
game.gamestate = GAMEMODE;
hardreset();
music.fadeout();
game.lastsaved = 4;
game.crewstats[game.lastsaved] = true;
game.inintermission = true;
map.finalmode = true;
map.final_colormode = false;
map.final_mapcol = 0;
map.final_colorframe = 0;
game.startspecial(1);
game.jumpheld = true;
//set flipmode
if (graphics.setflipmode) graphics.flipmode = true;
if(obj.entities.empty())
{
obj.createentity(game.savex, game.savey, 0, 0); //In this game, constant, never destroyed
}
map.resetplayer();
map.gotoroom(game.saverx, game.savery);
map.initmapdata();
load("intermission_2");
break;
case 19:
game.gamestate = GAMEMODE;
hardreset();
music.fadeout();
game.lastsaved = 5;
game.crewstats[game.lastsaved] = true;
game.inintermission = true;
map.finalmode = true;
map.final_colormode = false;
map.final_mapcol = 0;
map.final_colorframe = 0;
game.startspecial(1);
game.jumpheld = true;
//set flipmode
if (graphics.setflipmode) graphics.flipmode = true;
if(obj.entities.empty())
{
obj.createentity(game.savex, game.savey, 0, 0); //In this game, constant, never destroyed
}
map.resetplayer();
map.gotoroom(game.saverx, game.savery);
map.initmapdata();
load("intermission_2");
break;
#ifndef NO_CUSTOM_LEVELS
# ifndef NO_EDITOR
case 20:
//Level editor
hardreset();
case Start_EDITOR:
cl.reset();
ed.reset();
music.fadeout();
map.custommode = true;
map.custommodeforreal = false;
game.gamestate = EDITORMODE;
game.jumpheld = true;
if (graphics.setflipmode) graphics.flipmode = true;//set flipmode
if(obj.entities.empty())
{
obj.createentity(game.savex, game.savey, 0, 0); //In this game, constant, never destroyed
}
map.resetplayer();
map.gotoroom(game.saverx, game.savery);
map.initmapdata();
graphics.fademode = FADE_START_FADEIN;
break;
case 21: //play custom level (in editor)
game.gamestate = GAMEMODE;
case Start_EDITORPLAYTESTING:
music.fadeout();
hardreset();
//If warpdir() is used during playtesting, we need to set it back after!
for (int j = 0; j < cl.maxheight; j++)
{
@ -2872,25 +2589,12 @@ void scriptclass::startgamemode( int t )
ed.kludgewarpdir[i+(j*cl.maxwidth)]=cl.roomproperties[i+(j*cl.maxwidth)].warpdir;
}
}
game.customstart();
game.jumpheld = true;
game.customstart();
ed.ghosts.clear();
map.custommode = true;
//set flipmode
if (graphics.setflipmode) graphics.flipmode = true;
if(obj.entities.empty())
{
obj.createentity(game.savex, game.savey, 0, 0); //In this game, constant, never destroyed
}
map.resetplayer();
map.gotoroom(game.saverx, game.savery);
map.initmapdata();
cl.generatecustomminimap();
map.custommodeforreal = false;
map.customshowmm = true;
if (cl.levmusic > 0)
@ -2903,10 +2607,10 @@ void scriptclass::startgamemode( int t )
}
break;
# endif /* NO_EDITOR */
case 22: //play custom level (in game)
case Start_CUSTOM:
case Start_CUSTOM_QUICKSAVE:
{
//Initilise the level
//First up, find the start point
std::string filename = std::string(cl.ListOfMetaData[game.playcustomlevel].filename);
if (!cl.load(filename))
{
@ -2915,78 +2619,78 @@ void scriptclass::startgamemode( int t )
}
cl.findstartpoint();
game.gamestate = GAMEMODE;
music.fadeout();
hardreset();
game.customstart();
game.jumpheld = true;
map.custommodeforreal = true;
map.custommode = true;
map.customshowmm = true;
//set flipmode
if (graphics.setflipmode) graphics.flipmode = true;
music.fadeout();
game.customstart();
if(obj.entities.empty())
switch (mode)
{
obj.createentity(game.savex, game.savey, 0, 0); //In this game, constant, never destroyed
}
map.resetplayer();
map.gotoroom(game.saverx, game.savery);
map.initmapdata();
cl.generatecustomminimap();
map.customshowmm=true;
if(cl.levmusic>0){
music.play(cl.levmusic);
}else{
music.currentsong=-1;
}
graphics.fademode = FADE_START_FADEIN;
break;
}
case 23: //Continue in custom level
{
//Initilise the level
//First up, find the start point
std::string filename = std::string(cl.ListOfMetaData[game.playcustomlevel].filename);
if (!cl.load(filename))
{
gotoerrorloadinglevel();
case Start_CUSTOM:
if (cl.levmusic > 0)
{
music.play(cl.levmusic);
}
else
{
music.currentsong = -1;
}
break;
case Start_CUSTOM_QUICKSAVE:
game.customloadquick(cl.ListOfMetaData[game.playcustomlevel].filename);
break;
default:
VVV_unreachable();
}
cl.findstartpoint();
game.gamestate = GAMEMODE;
music.fadeout();
hardreset();
map.custommodeforreal = true;
map.custommode = true;
game.customstart();
game.customloadquick(cl.ListOfMetaData[game.playcustomlevel].filename);
game.jumpheld = true;
game.gravitycontrol = game.savegc;
//set flipmode
if (graphics.setflipmode) graphics.flipmode = true;
if(obj.entities.empty())
{
obj.createentity(game.savex, game.savey, 0, 0); //In this game, constant, never destroyed
}
map.resetplayer();
map.gotoroom(game.saverx, game.savery);
map.initmapdata();
cl.generatecustomminimap();
graphics.fademode = FADE_START_FADEIN;
break;
}
#endif /* NO_CUSTOM_LEVELS */
case 100:
VVV_exit(0);
break;
case Start_QUIT:
VVV_unreachable();
}
game.gravitycontrol = game.savegc;
graphics.flipmode = graphics.setflipmode;
if (!map.custommode && !graphics.setflipmode)
{
/* Invalidate Flip Mode trophy */
obj.flags[73] = true;
}
if (obj.entities.empty())
{
obj.createentity(game.savex, game.savey, 0, 0); //In this game, constant, never destroyed
}
map.resetplayer();
map.gotoroom(game.saverx, game.savery);
map.initmapdata();
#ifndef NO_CUSTOM_LEVELS
if (map.custommode)
{
cl.generatecustomminimap();
}
#endif
/* If we are spawning in a tower, ensure variables are set correctly */
if (map.towermode)
{
map.resetplayer();
i = obj.getplayer();
if (INBOUNDS_VEC(i, obj.entities))
{
map.ypos = obj.entities[i].yp - 120;
map.oldypos = map.ypos;
}
map.setbgobjlerp(graphics.towerbg);
map.cameramode = 0;
map.colsuperstate = 0;
}
}

View File

@ -17,6 +17,44 @@ struct Script
#define NUM_SCRIPT_ARGS 40
enum StartMode
{
Start_MAINGAME,
Start_MAINGAME_TELESAVE,
Start_MAINGAME_QUICKSAVE,
Start_TIMETRIAL_SPACESTATION1,
Start_TIMETRIAL_LABORATORY,
Start_TIMETRIAL_TOWER,
Start_TIMETRIAL_SPACESTATION2,
Start_TIMETRIAL_WARPZONE,
Start_TIMETRIAL_FINALLEVEL,
Start_NODEATHMODE_WITHCUTSCENES,
Start_NODEATHMODE_NOCUTSCENES,
Start_SECRETLAB,
Start_INTERMISSION1_VITELLARY,
Start_INTERMISSION1_VERMILION,
Start_INTERMISSION1_VERDIGRIS,
Start_INTERMISSION1_VICTORIA,
Start_INTERMISSION2_VITELLARY,
Start_INTERMISSION2_VERMILION,
Start_INTERMISSION2_VERDIGRIS,
Start_INTERMISSION2_VICTORIA,
Start_EDITOR,
Start_EDITORPLAYTESTING,
Start_CUSTOM,
Start_CUSTOM_QUICKSAVE,
Start_QUIT,
Start_FIRST_NODEATHMODE = Start_NODEATHMODE_WITHCUTSCENES,
Start_LAST_NODEATHMODE = Start_NODEATHMODE_NOCUTSCENES,
Start_FIRST_INTERMISSION1 = Start_INTERMISSION1_VITELLARY,
Start_LAST_INTERMISSION1 = Start_INTERMISSION1_VICTORIA,
Start_FIRST_INTERMISSION2 = Start_INTERMISSION2_VITELLARY,
Start_LAST_INTERMISSION2 = Start_INTERMISSION2_VICTORIA,
Start_FIRST_TIMETRIAL = Start_TIMETRIAL_SPACESTATION1
};
class scriptclass
{
public:
@ -41,7 +79,7 @@ public:
void resetgametomenu(void);
void startgamemode(int t);
void startgamemode(enum StartMode mode);
void teleport(void);

View File

@ -697,9 +697,9 @@ int main(int argc, char *argv[])
game.playgc = savegc;
game.playmusic = savemusic;
game.cliplaytest = true;
script.startgamemode(23);
script.startgamemode(Start_CUSTOM_QUICKSAVE);
} else {
script.startgamemode(22);
script.startgamemode(Start_CUSTOM);
}
graphics.fademode = FADE_NONE;