VVVVVV/desktop_version/src/Game.h

449 lines
9.4 KiB
C
Raw Normal View History

2020-01-01 21:29:24 +01:00
#ifndef GAME_H
#define GAME_H
#include <SDL.h>
#include <string>
#include <vector>
2020-01-01 21:29:24 +01:00
#include "ScreenSettings.h"
// Forward decl without including all of <tinyxml2.h>
namespace tinyxml2
{
class XMLDocument;
class XMLElement;
}
struct MenuOption
{
char text[161]; // 40 chars (160 bytes) covers the entire screen, + 1 more for null terminator
// WARNING: should match Game::menutextbytes below
bool active;
};
//Menu IDs
namespace Menu
{
enum MenuName
{
mainmenu,
playerworlds,
levellist,
quickloadlevel,
youwannaquit,
errornostart,
errorsavingsettings,
graphicoptions,
ed_settings,
ed_desc,
ed_music,
ed_quit,
options,
advancedoptions,
accessibility,
controller,
cleardatamenu,
setinvincibility,
setslowdown,
unlockmenu,
credits,
credits2,
credits25,
credits3,
credits4,
credits5,
credits6,
play,
unlocktimetrial,
unlocktimetrials,
unlocknodeathmode,
unlockintermission,
unlockflipmode,
newgamewarning,
playmodes,
intermissionmenu,
playint1,
playint2,
continuemenu,
startnodeathmode,
gameover,
gameover2,
unlockmenutrials,
timetrials,
nodeathmodecomplete,
nodeathmodecomplete2,
timetrialcomplete,
timetrialcomplete2,
timetrialcomplete3,
gamecompletecontinue,
};
};
struct MenuStackFrame
{
int option;
enum Menu::MenuName name;
};
struct CustomLevelStat
{
std::string name;
int score; //0 - not played, 1 - finished, 2 - all trinkets, 3 - finished, all trinkets
};
2020-01-01 21:29:24 +01:00
class Game
{
public:
Allow using help/graphics/music/game/key/map/obj everywhere This commit makes `help`, `graphics`, `music`, `game`, `key`, `map`, and `obj` essentially static global objects that can be used everywhere. This is useful in case we ever need to add a new function in the future, so we don't have to bother with passing a new argument in which means we have to pass a new argument in to the function that calls that function which means having to pass a new argument into the function that calls THAT function, etc. which is a real headache when working on fan mods of the source code. Note that this changes NONE of the existing function signatures, it merely just makes those variables accessible everywhere in the same way `script` and `ed` are. Also note that some classes had to be initialized after the filesystem was initialized, but C++ would keep initializing them before the filesystem got initialized, because I *had* to put them at the top of `main.cpp`, or else they wouldn't be global variables. The only way to work around this was to use entityclass's initialization style (which I'm pretty sure entityclass of all things doesn't need to be initialized this way), where you actually initialize the class in an `init()` function, and so then you do `graphics.init()` after the filesystem initialization, AFTER doing `Graphics graphics` up at the top. I've had to do this for `graphics` (but only because its child GraphicsResources `grphx` needs to be initialized this way), `music`, and `game`. I don't think this will affect anything. Other than that, `help`, `key`, and `map` are still using the C++-intended method of having ClassName::ClassName() functions.
2020-01-29 08:35:03 +01:00
void init(void);
2020-01-01 21:29:24 +01:00
int crewrescued();
std::string unrescued();
void resetgameclock();
2020-11-04 03:45:33 +01:00
bool customsavequick(std::string savfile);
bool savequick();
2020-01-01 21:29:24 +01:00
void gameclock();
std::string giventimestring(int hrs, int min, int sec);
2020-01-01 21:29:24 +01:00
std::string timestring();
2020-01-01 21:29:24 +01:00
std::string partimestring();
2020-01-01 21:29:24 +01:00
std::string resulttimestring();
2020-01-01 21:29:24 +01:00
std::string timetstring(int t);
2020-01-01 21:29:24 +01:00
void returnmenu();
void returntomenu(enum Menu::MenuName t);
void createmenu(enum Menu::MenuName t, bool samemenu = false);
2020-01-01 21:29:24 +01:00
void lifesequence();
2020-01-01 21:29:24 +01:00
void gethardestroom();
2020-01-01 21:29:24 +01:00
void updatestate();
2020-01-01 21:29:24 +01:00
void unlocknum(int t);
2020-01-01 21:29:24 +01:00
void loadstats(ScreenSettings* screen_settings);
2020-01-01 21:29:24 +01:00
bool savestats(const ScreenSettings* screen_settings);
bool savestats();
2020-01-01 21:29:24 +01:00
void deletestats();
2020-01-01 21:29:24 +01:00
void deserializesettings(tinyxml2::XMLElement* dataNode, ScreenSettings* screen_settings);
void serializesettings(tinyxml2::XMLElement* dataNode, const ScreenSettings* screen_settings);
void loadsettings(ScreenSettings* screen_settings);
bool savesettings(const ScreenSettings* screen_settings);
bool savesettings();
bool savestatsandsettings();
void savestatsandsettings_menu();
void deletesettings();
2020-01-01 21:29:24 +01:00
void deletequick();
bool savetele();
2020-01-01 21:29:24 +01:00
void loadtele();
2020-01-01 21:29:24 +01:00
void deletetele();
void customstart();
2020-01-01 21:29:24 +01:00
void start();
2020-01-01 21:29:24 +01:00
void startspecial(int t);
2020-01-01 21:29:24 +01:00
void starttrial(int t);
2020-01-01 21:29:24 +01:00
void swnpenalty();
void deathsequence();
2020-01-01 21:29:24 +01:00
void customloadquick(std::string savfile);
void loadquick();
2020-01-01 21:29:24 +01:00
void loadsummary();
2020-01-01 21:29:24 +01:00
void readmaingamesave(tinyxml2::XMLDocument& doc);
std::string writemaingamesave(tinyxml2::XMLDocument& doc);
void initteleportermode();
2020-01-01 21:29:24 +01:00
std::string saveFilePath;
2020-01-01 21:29:24 +01:00
int door_left;
int door_right;
int door_up;
int door_down;
int roomx, roomy, roomchangedir;
int prevroomx, prevroomy;
2020-01-01 21:29:24 +01:00
int savex, savey, saverx, savery;
int savegc, savedir;
//Added for port
int edsavex, edsavey, edsaverx, edsavery;
int edsavegc, edsavedir;
//State logic stuff
int state, statedelay;
bool glitchrunkludge;
2020-01-01 21:29:24 +01:00
int gamestate;
int prevgamestate; //only used sometimes
2020-01-01 21:29:24 +01:00
bool hascontrol, jumpheld;
int jumppressed;
int gravitycontrol;
bool muted;
int mutebutton;
bool musicmuted;
int musicmutebutton;
2020-01-01 21:29:24 +01:00
int tapleft, tapright;
//Menu interaction stuff
2020-12-28 23:23:35 +01:00
void mapmenuchange(const int newgamestate);
2020-01-01 21:29:24 +01:00
bool mapheld;
int menupage;
int lastsaved;
int deathcounts;
int frames, seconds, minutes, hours;
bool gamesaved;
2020-11-04 03:45:33 +01:00
bool gamesavefailed;
2020-01-01 21:29:24 +01:00
std::string savetime;
std::string savearea;
int savetrinkets;
bool startscript;
std::string newscript;
int mainmenu;
bool menustart;
//Teleporting
bool teleport_to_new_area;
int teleport_to_x, teleport_to_y;
std::string teleportscript;
bool useteleporter;
int teleport_to_teleporter;
//Main Menu Variables
std::vector<MenuOption> menuoptions;
int currentmenuoption ;
enum Menu::MenuName currentmenuname;
enum Menu::MenuName kludge_ingametemp;
int current_credits_list_index;
2020-01-01 21:29:24 +01:00
int menuxoff, menuyoff;
Make menus automatically centered and narrowed All menus had a hardcoded X position (offset to an arbitrary starting point of 110) and a hardcoded horizontal spacing for the "staircasing" (mostly 30 pixels, but for some specific menus hardcoded to 15, 20 or something else). Not all menus were centered, and seem to have been manually made narrower (with lower horizontal spacing) whenever text ran offscreen during development. This system may already be hard to work with in an English-only menu system, since you may need to adjust horizontal spacing or positioning when adding an option. The main reason I made this change is that it's even less optimal when menu options have to be translated, since maximum string lengths are hard to determine, and it's easy to have menu options running offscreen, especially when not all menus are checked for all languages and when options could be added in the middle of a menu after translations of that menu are already checked. Now, menus are automatically centered based on their options, and they are automatically made narrower if they won't fit with the default horizontal spacing of 30 pixels (with some padding). The game.menuxoff variable for the menu X position is now also offset to 0 instead of 110 The _default_ horizontal spacing can be changed on a per-menu basis, and most menus (not all) which already had a narrower spacing set, retain that as a maximum spacing, simply because they looked odd with 30 pixels of spacing (especially the main menu). They will be made even narrower automatically if needed. In the most extreme case, the spacing can go down to 0 and options will be displayed right below each other. This isn't in the usual style of the game, but at least we did the best we could to prevent options running offscreen. The only exception to automatic menu centering and narrowing is the list of player levels, because it's a special case and existing behavior would be better than automatic centering there.
2020-06-29 02:09:52 +02:00
int menuspacing;
static const int menutextbytes = 161; // this is just sizeof(MenuOption::text), but doing that is non-standard
std::vector<MenuStackFrame> menustack;
2020-01-01 21:29:24 +01:00
void inline option(const char* text, bool active = true)
{
MenuOption menuoption;
SDL_strlcpy(menuoption.text, text, sizeof(menuoption.text));
menuoption.active = active;
menuoptions.push_back(menuoption);
}
2020-01-01 21:29:24 +01:00
int menucountdown;
enum Menu::MenuName menudest;
2020-01-01 21:29:24 +01:00
int creditposx, creditposy, creditposdelay;
int oldcreditposx;
2020-01-01 21:29:24 +01:00
bool silence_settings_error;
2020-01-01 21:29:24 +01:00
//Sine Wave Ninja Minigame
bool swnmode;
int swngame, swnstate, swnstate2, swnstate3, swnstate4, swndelay, swndeaths;
int swntimer, swncolstate, swncoldelay;
int swnrecord, swnbestrank, swnrank, swnmessage;
//SuperCrewMate Stuff
bool supercrewmate, scmhurt, scmmoveme;
int scmprogress;
//Accessibility Options
bool colourblindmode;
bool noflashingmode;
int slowdown;
bool nodeathmode;
int gameoverdelay;
bool nocutscenes;
//Time Trials
bool intimetrial, timetrialparlost;
int timetrialcountdown, timetrialshinytarget, timetriallevel;
int timetrialpar, timetrialresulttime, timetrialresultframes, timetrialrank;
2020-01-01 21:29:24 +01:00
int creditposition;
int oldcreditposition;
2020-01-01 21:29:24 +01:00
bool insecretlab;
bool inintermission;
static const int numcrew = 6;
bool crewstats[numcrew];
2020-01-01 21:29:24 +01:00
bool alarmon;
int alarmdelay;
bool blackout;
bool tele_crewstats[numcrew];
2020-01-01 21:29:24 +01:00
bool quick_crewstats[numcrew];
2020-01-01 21:29:24 +01:00
static const int numunlock = 25;
bool unlock[numunlock];
bool unlocknotify[numunlock];
bool anything_unlocked();
2020-01-01 21:29:24 +01:00
int stat_trinkets;
int bestgamedeaths;
static const int numtrials = 6;
int besttimes[numtrials];
int bestframes[numtrials];
int besttrinkets[numtrials];
int bestlives[numtrials];
int bestrank[numtrials];
2020-01-01 21:29:24 +01:00
std::string tele_gametime;
int tele_trinkets;
std::string tele_currentarea;
std::string quick_gametime;
int quick_trinkets;
std::string quick_currentarea;
int mx, my;
int screenshake, flashlight;
bool advancetext, pausescript;
int deathseq, lifeseq;
int trinkets();
int crewmates();
int savepoint, teleportxpos;
bool teleport;
2020-01-01 21:29:24 +01:00
int edteleportent;
bool completestop;
float inertia;
int companion;
bool roomchange;
SDL_Rect teleblock;
bool activetele;
int readytotele;
int oldreadytotele;
2020-01-01 21:29:24 +01:00
int activity_r, activity_g, activity_b;
std::string activity_lastprompt;
std::string telesummary, quicksummary, customquicksummary;
bool save_exists();
2020-01-01 21:29:24 +01:00
bool backgroundtext;
int activeactivity, act_fade;
int prev_act_fade;
2020-01-01 21:29:24 +01:00
bool press_left, press_right, press_action, press_map;
//Some stats:
int totalflips;
std::string hardestroom;
int hardestroomdeaths, currentroomdeaths;
bool quickrestartkludge;
//Custom stuff
std::string customscript[50];
int customcol;
int levelpage;
int playcustomlevel;
std::string customleveltitle;
std::string customlevelfilename;
void clearcustomlevelstats();
void loadcustomlevelstats();
void savecustomlevelstats();
void updatecustomlevelstats(std::string clevel, int cscore);
std::vector<CustomLevelStat> customlevelstats;
2020-01-01 21:29:24 +01:00
bool customlevelstatsloaded;
std::vector<SDL_GameControllerButton> controllerButton_map;
std::vector<SDL_GameControllerButton> controllerButton_flip;
std::vector<SDL_GameControllerButton> controllerButton_esc;
std::vector<SDL_GameControllerButton> controllerButton_restart;
2020-01-01 21:29:24 +01:00
bool skipfakeload;
bool ghostsenabled;
bool cliplaytest;
int playx;
int playy;
int playrx;
int playry;
int playgc;
int playmusic;
std::string playassets;
void quittomenu();
void returntolab();
bool fadetomenu;
int fadetomenudelay;
bool fadetolab;
int fadetolabdelay;
#if !defined(NO_CUSTOM_LEVELS)
void returntoeditor();
bool shouldreturntoeditor;
#endif
int gametimer;
bool inline inspecial()
{
return inintermission || insecretlab || intimetrial || nodeathmode;
}
bool over30mode;
bool glitchrunnermode; // Have fun speedrunners! <3 Misa
bool ingame_titlemode;
void returntopausemenu();
2020-08-01 21:51:11 +02:00
void unlockAchievement(const char *name);
bool disablepause;
2020-01-01 21:29:24 +01:00
};
#ifndef GAME_DEFINITION
Allow using help/graphics/music/game/key/map/obj everywhere This commit makes `help`, `graphics`, `music`, `game`, `key`, `map`, and `obj` essentially static global objects that can be used everywhere. This is useful in case we ever need to add a new function in the future, so we don't have to bother with passing a new argument in which means we have to pass a new argument in to the function that calls that function which means having to pass a new argument into the function that calls THAT function, etc. which is a real headache when working on fan mods of the source code. Note that this changes NONE of the existing function signatures, it merely just makes those variables accessible everywhere in the same way `script` and `ed` are. Also note that some classes had to be initialized after the filesystem was initialized, but C++ would keep initializing them before the filesystem got initialized, because I *had* to put them at the top of `main.cpp`, or else they wouldn't be global variables. The only way to work around this was to use entityclass's initialization style (which I'm pretty sure entityclass of all things doesn't need to be initialized this way), where you actually initialize the class in an `init()` function, and so then you do `graphics.init()` after the filesystem initialization, AFTER doing `Graphics graphics` up at the top. I've had to do this for `graphics` (but only because its child GraphicsResources `grphx` needs to be initialized this way), `music`, and `game`. I don't think this will affect anything. Other than that, `help`, `key`, and `map` are still using the C++-intended method of having ClassName::ClassName() functions.
2020-01-29 08:35:03 +01:00
extern Game game;
#endif
Allow using help/graphics/music/game/key/map/obj everywhere This commit makes `help`, `graphics`, `music`, `game`, `key`, `map`, and `obj` essentially static global objects that can be used everywhere. This is useful in case we ever need to add a new function in the future, so we don't have to bother with passing a new argument in which means we have to pass a new argument in to the function that calls that function which means having to pass a new argument into the function that calls THAT function, etc. which is a real headache when working on fan mods of the source code. Note that this changes NONE of the existing function signatures, it merely just makes those variables accessible everywhere in the same way `script` and `ed` are. Also note that some classes had to be initialized after the filesystem was initialized, but C++ would keep initializing them before the filesystem got initialized, because I *had* to put them at the top of `main.cpp`, or else they wouldn't be global variables. The only way to work around this was to use entityclass's initialization style (which I'm pretty sure entityclass of all things doesn't need to be initialized this way), where you actually initialize the class in an `init()` function, and so then you do `graphics.init()` after the filesystem initialization, AFTER doing `Graphics graphics` up at the top. I've had to do this for `graphics` (but only because its child GraphicsResources `grphx` needs to be initialized this way), `music`, and `game`. I don't think this will affect anything. Other than that, `help`, `key`, and `map` are still using the C++-intended method of having ClassName::ClassName() functions.
2020-01-29 08:35:03 +01:00
2020-01-01 21:29:24 +01:00
#endif /* GAME_H */