1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-06-22 05:03:19 +00:00

restructured menus

This commit is contained in:
Zeno Rogue 2019-03-30 23:45:28 +01:00
parent bca98e9247
commit 54a32441a7
8 changed files with 411 additions and 439 deletions

View File

@ -709,25 +709,6 @@ void loadConfig() {
}
#endif
void showAllConfig() {
dialog::addBreak(50);
dialog::addBack();
#if CAP_CONFIG
dialog::addItem(XLAT("save the current config"), 's');
if(getcstat == 's')
mouseovers = XLAT("Config file: %1", conffile);
#endif
}
void handleAllConfig(int sym, int uni) {
if(sym == SDLK_F1 || uni == 'h') gotoHelp(help);
else if(uni == ' ' || sym == SDLK_ESCAPE) popScreen();
#if CAP_CONFIG
else if(uni == 's') saveConfig();
#endif
}
void add_cells_drawn(char c = 'C') {
dialog::addSelItem(XLAT("cells drawn"), its(cells_drawn), c);
dialog::add_action([] () {
@ -858,26 +839,8 @@ void showGraphConfig() {
dialog::addSelItem(XLAT("whatever"), fts(whatever), 'j');
#endif
const char *glyphsortnames[6] = {
"first on top", "first on bottom",
"last on top", "last on bottom",
"by land", "by number"
};
const char *glyphmodenames[3] = {"letters", "auto", "images"};
dialog::addSelItem(XLAT("inventory/kill sorting"), XLAT(glyphsortnames[glyphsortorder]), 'k');
dialog::addSelItem(XLAT("inventory/kill mode"), XLAT(glyphmodenames[vid.graphglyph]), 'd');
dialog::addSelItem(XLAT("font scale"), its(fontscale), 'b');
menuitem_sightrange();
dialog::addSelItem(XLAT("move by clicking on compass"), its(vid.mobilecompasssize), 'C');
dialog::addItem(XLAT("customize colors and aura"), 'c');
showAllConfig();
dialog::addBreak(50);
dialog::addBack();
dialog::display();
keyhandler = [] (int sym, int uni) {
@ -890,37 +853,30 @@ void showGraphConfig() {
if((uni >= 32 && uni < 64) || uni == 'L' || uni == 'C') xuni = uni;
if(xuni == 'u') vid.particles = !vid.particles;
if(xuni == 'd') vid.graphglyph = (1+vid.graphglyph)%3;
if(xuni == 'c') pushScreen(show_color_dialog);
if(xuni == 'j') {
else if(xuni == 'j') {
dialog::editNumber(whatever, -10, 10, 1, 0, XLAT("whatever"),
XLAT("Whatever."));
dialog::reaction = delayed_geo_reset;
}
if(xuni == 'a') dialog::editNumber(vid.sspeed, -5, 5, 1, 0,
else if(xuni == 'a') dialog::editNumber(vid.sspeed, -5, 5, 1, 0,
XLAT("scrolling speed"),
XLAT("+5 = center instantly, -5 = do not center the map")
+ "\n\n" +
XLAT("press Space or Home to center on the PC"));
if(xuni == 'm') dialog::editNumber(vid.mspeed, -5, 5, 1, 0,
else if(xuni == 'm') dialog::editNumber(vid.mspeed, -5, 5, 1, 0,
XLAT("movement animation speed"),
XLAT("+5 = move instantly"));
if(xuni == 'k') {
glyphsortorder = eGlyphsortorder((glyphsortorder+6+(shiftmul>0?1:-1)) % gsoMAX);
}
if(xuni == 'f') switchFullscreen();
else if(xuni == 'f') switchFullscreen();
#if CAP_GLORNOT
if(xuni == 'o' && shiftmul > 0) switchGL();
else if(xuni == 'o' && shiftmul > 0) switchGL();
#endif
if(xuni == 'o' && shiftmul < 0) {
else if(xuni == 'o' && shiftmul < 0) {
if(!vid.usingGL)
vid.antialias ^= AA_NOGL | AA_FONT;
else if(vid.antialias & AA_MULTI)
@ -938,7 +894,7 @@ void showGraphConfig() {
// if(xuni == 'b') vid.antialias ^= AA_LINEWIDTH;
if(xuni == 'w' && vid.usingGL) {
else if(xuni == 'w' && vid.usingGL) {
dialog::editNumber(vid.linewidth, 0, 10, 0.1, 1, XLAT("line width"), "");
dialog::extra_options = [] () {
dialog::addBoolItem("finer lines at the boundary", vid.antialias & AA_LINEWIDTH, 'O');
@ -946,37 +902,23 @@ void showGraphConfig() {
};
}
if(xuni == 'L') {
else if(xuni == 'L') {
dialog::editNumber(vid.linequality, -3, 5, 1, 1, XLAT("line quality"),
XLAT("Higher numbers make the curved lines smoother, but reduce the performance."));
dialog::reaction = delayed_geo_reset;
}
if(xuni == 'C') {
dialog::editNumber(vid.mobilecompasssize, 0, 100, 10, 20, XLAT("compass size"), XLAT("0 to disable"));
// we need to check the moves
dialog::reaction = checkmove;
dialog::bound_low(0);
}
#if CAP_FRAMELIMIT
if(xuni == 'l') {
else if(xuni == 'l') {
dialog::editNumber(vid.framelimit, 5, 300, 10, 300, XLAT("framerate limit"), "");
dialog::bound_low(5);
}
#endif
if(xuni =='b') {
dialog::editNumber(fontscale, 25, 400, 10, 100, XLAT("font scale"), "");
const int minfontscale = ISMOBILE ? 50 : 25;
dialog::reaction = [] () { setfsize = true; do_setfsize(); };
dialog::bound_low(minfontscale);
}
if(xuni =='p')
else if(xuni =='p')
vid.backeffects = !vid.backeffects;
handleAllConfig(sym, xuni);
else if(doexiton(sym, uni)) popScreen();
};
}
@ -1012,85 +954,25 @@ void switchGL() {
void resetConfigMenu();
void showBasicConfig() {
void configureOther() {
gamescreen(3);
const char *axmodes[5] = {"OFF", "auto", "light", "heavy", "arrows"};
dialog::init(XLAT("basic configuration"));
if(CAP_TRANS) dialog::addSelItem(XLAT("language"), XLAT("EN"), 'l');
dialog::addSelItem(XLAT("player character"), numplayers() > 1 ? "" : csname(vid.cs), 'g');
if(getcstat == 'g')
mouseovers = XLAT("Affects looks and grammar");
if(CAP_AUDIO) {
dialog::addSelItem(XLAT("background music volume"), its(musicvolume), 'b');
dialog::addSelItem(XLAT("sound effects volume"), its(effvolume), 'e');
}
// input:
dialog::addSelItem(XLAT("help for keyboard users"), XLAT(axmodes[vid.axes]), 'c');
dialog::addBoolItem(XLAT("reverse pointer control"), (vid.revcontrol), 'r');
dialog::addBoolItem(XLAT("draw circle around the target"), (vid.drawmousecircle), 'd');
dialog::addSelItem(XLAT("message flash time"), its(vid.flashtime), 't');
dialog::addSelItem(XLAT("limit messages shown"), its(vid.msglimit), 'z');
const char* msgstyles[3] = {"centered", "left-aligned", "line-broken"};
dialog::addSelItem(XLAT("message style"), XLAT(msgstyles[vid.msgleft]), 'a');
#if ISMOBILE
dialog::addBoolItem(XLAT("targetting ranged Orbs long-click only"), (vid.shifttarget&2), 'i');
#else
dialog::addBoolItem(XLAT("targetting ranged Orbs Shift+click only"), (vid.shifttarget&1), 'i');
#endif
dialog::init(XLAT("other configuration"));
#if ISSTEAM
dialog::addBoolItem(XLAT("send scores to Steam leaderboards"), (vid.steamscore&1), 'x');
dialog::add_action([] {vid.steamscore = vid.steamscore^1; });
#endif
dialog::addBoolItem(XLAT("skip the start menu"), vid.skipstart, 'm');
#if !ISMOBILE
dialog::addBoolItem(XLAT("quick mouse"), vid.quickmouse, 'M');
#endif
dialog::add_action([] { vid.skipstart = !vid.skipstart; });
dialog::addBoolItem(XLAT("forget faraway cells"), memory_saving_mode, 'y');
dialog::add_action([] { memory_saving_mode = !memory_saving_mode; });
#if CAP_ORIENTATION
dialog::addSelItem(XLAT("scrolling by device rotation"), ors::choices[ors::mode], '1');
#endif
if(CAP_SHMUP && !ISMOBILE)
dialog::addSelItem(XLAT("configure keys/joysticks"), "", 'p');
#if CAP_CONFIG
dialog::addItem(XLAT("reset all configuration"), 'R');
#endif
showAllConfig();
dialog::display();
keyhandler = [] (int sym, int uni) {
dialog::handleNavigation(sym, uni);
char xuni = uni | 96;
if(uni >= 32 && uni < 64) xuni = uni;
#if CAP_ORIENTATION
if(xuni == '1') pushScreen(ors::show);
#endif
if(uni == 'M') vid.quickmouse = !vid.quickmouse;
else if(xuni == 'm') vid.skipstart = !vid.skipstart;
if(xuni == 'y') memory_saving_mode = !memory_saving_mode;
if(xuni == 'c') { vid.axes += 60 + (shiftmul > 0 ? 1 : -1); vid.axes %= 5; }
#if CAP_AUDIO
if(CAP_AUDIO && xuni == 'b') {
if(CAP_AUDIO) {
dialog::addSelItem(XLAT("background music volume"), its(musicvolume), 'b');
dialog::add_action([] {
dialog::editNumber(musicvolume, 0, 128, 10, 60, XLAT("background music volume"), "");
dialog::reaction = [] () {
#if CAP_SDLAUDIO
@ -1102,9 +984,10 @@ void showBasicConfig() {
};
dialog::bound_low(0);
dialog::bound_up(MIX_MAX_VOLUME);
}
});
if(CAP_AUDIO && xuni == 'e') {
dialog::addSelItem(XLAT("sound effects volume"), its(effvolume), 'e');
dialog::add_action([] {
dialog::editNumber(effvolume, 0, 128, 10, 60, XLAT("sound effects volume"), "");
dialog::reaction = [] () {
#if ISANDROID
@ -1113,46 +996,79 @@ void showBasicConfig() {
};
dialog::bound_low(0);
dialog::bound_up(MIX_MAX_VOLUME);
}
#endif
if(CAP_TRANS && xuni == 'l')
pushScreen(selectLanguageScreen);
if(xuni == 'g') pushScreen(showCustomizeChar);
#if CAP_SHMUP
if(xuni == 'p')
shmup::configure();
#endif
if(uni == 'r') vid.revcontrol = !vid.revcontrol;
if(xuni == 'd') vid.drawmousecircle = !vid.drawmousecircle;
#if CAP_CONFIG
if(uni == 'R') pushScreen(resetConfigMenu);
#endif
#if ISSTEAM
if(xuni == 'x') vid.steamscore = vid.steamscore^1;
#endif
if(xuni == 't') {
dialog::editNumber(vid.flashtime, 0, 64, 1, 8, XLAT("message flash time"),
XLAT("How long should the messages stay on the screen."));
dialog::bound_low(0);
}
});
}
if(xuni == 'z') {
dialog::editNumber(vid.msglimit, 0, 64, 1, 5, XLAT("limit messages shown"),
XLAT("Maximum number of messages on screen."));
dialog::bound_low(0);
}
if(xuni == 'i') { vid.shifttarget = vid.shifttarget^3; }
if(xuni == 'a') { vid.msgleft = (1+vid.msgleft) % 3; }
menuitem_sightrange('r');
dialog::addBreak(50);
dialog::addBack();
handleAllConfig(sym, xuni);
dialog::display();
}
void configureInterface() {
gamescreen(3);
dialog::init(XLAT("interface"));
if(CAP_TRANS) {
dialog::addSelItem(XLAT("language"), XLAT("EN"), 'l');
dialog::add_action_push(selectLanguageScreen);
}
dialog::addSelItem(XLAT("player character"), numplayers() > 1 ? "" : csname(vid.cs), 'g');
dialog::add_action_push(showCustomizeChar);
if(getcstat == 'g') mouseovers = XLAT("Affects looks and grammar");
dialog::addSelItem(XLAT("message flash time"), its(vid.flashtime), 't');
dialog::add_action([] {
dialog::editNumber(vid.flashtime, 0, 64, 1, 8, XLAT("message flash time"),
XLAT("How long should the messages stay on the screen."));
dialog::bound_low(0);
});
dialog::addSelItem(XLAT("limit messages shown"), its(vid.msglimit), 'z');
dialog::add_action([] {
dialog::editNumber(vid.msglimit, 0, 64, 1, 5, XLAT("limit messages shown"),
XLAT("Maximum number of messages on screen."));
dialog::bound_low(0);
});
const char* msgstyles[3] = {"centered", "left-aligned", "line-broken"};
dialog::addSelItem(XLAT("message style"), XLAT(msgstyles[vid.msgleft]), 'a');
dialog::add_action([] {
vid.msgleft = (1+vid.msgleft) % 3;
});
dialog::addSelItem(XLAT("font scale"), its(fontscale), 'b');
dialog::add_action([] {
dialog::editNumber(fontscale, 25, 400, 10, 100, XLAT("font scale"), "");
const int minfontscale = ISMOBILE ? 50 : 25;
dialog::reaction = [] () { setfsize = true; do_setfsize(); };
dialog::bound_low(minfontscale);
});
const char *glyphsortnames[6] = {
"first on top", "first on bottom",
"last on top", "last on bottom",
"by land", "by number"
};
dialog::addSelItem(XLAT("inventory/kill sorting"), XLAT(glyphsortnames[glyphsortorder]), 'k');
dialog::add_action([] {
glyphsortorder = eGlyphsortorder((glyphsortorder+6+(shiftmul>0?1:-1)) % gsoMAX);
});
const char *glyphmodenames[3] = {"letters", "auto", "images"};
dialog::addSelItem(XLAT("inventory/kill mode"), XLAT(glyphmodenames[vid.graphglyph]), 'd');
dialog::add_action([] {
vid.graphglyph = (1+vid.graphglyph)%3;
});
dialog::addBreak(50);
dialog::addBack();
dialog::display();
}
#if CAP_SDLJOY
@ -1888,6 +1804,95 @@ void selectLanguageScreen() {
}
#endif
void configureMouse() {
gamescreen(1);
dialog::init(XLAT("mouse & touchscreen"));
dialog::addBoolItem(XLAT("reverse pointer control"), (vid.revcontrol), 'r');
dialog::add_action([] {vid.revcontrol = !vid.revcontrol; });
dialog::addBoolItem(XLAT("draw circle around the target"), (vid.drawmousecircle), 'd');
dialog::add_action([] { vid.drawmousecircle = !vid.drawmousecircle; });
#if ISMOBILE
dialog::addBoolItem(XLAT("targetting ranged Orbs long-click only"), (vid.shifttarget&2), 'i');
#else
dialog::addBoolItem(XLAT("targetting ranged Orbs Shift+click only"), (vid.shifttarget&1), 'i');
#endif
dialog::add_action([] {vid.shifttarget = vid.shifttarget^3; });
#if !ISMOBILE
dialog::addBoolItem(XLAT("quick mouse"), vid.quickmouse, 'M');
dialog::add_action([] {vid.quickmouse = !vid.quickmouse; });
#endif
dialog::addSelItem(XLAT("move by clicking on compass"), its(vid.mobilecompasssize), 'C');
dialog::add_action([] {
dialog::editNumber(vid.mobilecompasssize, 0, 100, 10, 20, XLAT("compass size"), XLAT("0 to disable"));
// we need to check the moves
dialog::reaction = checkmove;
dialog::bound_low(0);
});
#if CAP_ORIENTATION
dialog::addSelItem(XLAT("scrolling by device rotation"), ors::choices[ors::mode], '1');
dialog::add_action([] { pushScreen(ors::show); });
#endif
dialog::display();
}
void showSettings() {
gamescreen(1);
dialog::init(XLAT("settings"));
dialog::addItem(XLAT("interface"), 'i');
dialog::add_action_push(configureInterface);
dialog::addItem(XLAT("general graphics"), 'g');
dialog::add_action_push(showGraphConfig);
dialog::addItem(XLAT("colors and aura"), 'c');
dialog::add_action_push(show_color_dialog);
dialog::addItem(XLAT("3D graphics"), '9');
dialog::add_action_push(show3D);
dialog::addItem(XLAT("quick options"), 'q');
dialog::add_action_push(showGraphQuickKeys);
dialog::addItem(XLAT("models and projections"), 'a');
dialog::add_action_push(conformal::model_menu);
#if CAP_SHMUP
if(CAP_SHMUP && !ISMOBILE) {
dialog::addSelItem(XLAT("keyboard & joysticks"), "", 'k');
dialog::add_action(shmup::configure);
}
#endif
dialog::addSelItem(XLAT("mouse & touchscreen"), "", 'm');
dialog::add_action_push(configureMouse);
dialog::addItem(XLAT("other settings"), 'o');
dialog::add_action_push(configureOther);
dialog::addBreak(100);
#if CAP_CONFIG
dialog::addItem(XLAT("save the current config"), 's');
dialog::add_action(saveConfig);
dialog::addItem(XLAT("reset all configuration"), 'R');
dialog::add_action_push(resetConfigMenu);
#endif
if(getcstat == 's') mouseovers = XLAT("Config file: %1", conffile);
dialog::addBack();
dialog::display();
}
#if CAP_COMMANDLINE
int read_color_args() {
@ -2027,8 +2032,8 @@ int read_config_args() {
else if(argis("-d:stereo")) {
PHASEFROM(2); launch_dialog(showStereo);
}
else if(argis("-d:basic")) {
PHASEFROM(2); launch_dialog(showBasicConfig);
else if(argis("-d:iface")) {
PHASEFROM(2); launch_dialog(configureInterface);
}
else if(argis("-d:graph")) {
PHASEFROM(2); launch_dialog(showGraphConfig);

View File

@ -956,29 +956,36 @@ int get_direction_key(int sym, int uni) {
return sym;
}
void gmodekeys(int sym, int uni) {
bool gmodekeys(int sym, int uni) {
#if CAP_RUG
if(rug::rugged) rug::handlekeys(sym, uni);
if(rug::rugged && rug::handlekeys(sym, uni)) return true;
#endif
if(NUMBERKEY == '6') { vid.grid = !vid.grid; return true; }
if(NUMBERKEY == '7') { vid.darkhepta = !vid.darkhepta; return true; }
if(DIM == 2) {
if(NUMBERKEY == '1' && !rug::rugged) { vid.alpha = 999; vid.scale = 998; vid.xposition = vid.yposition = 0; }
if(NUMBERKEY == '2' && !rug::rugged) { vid.alpha = 1; vid.scale = 0.4; vid.xposition = vid.yposition = 0; }
if(NUMBERKEY == '3' && !rug::rugged) { vid.alpha = 1; vid.scale = 1; vid.xposition = vid.yposition = 0; }
if(NUMBERKEY == '4' && !rug::rugged) { vid.alpha = 0; vid.scale = 1; vid.xposition = vid.yposition = 0; }
if(NUMBERKEY == '5') { vid.wallmode += 60 + (shiftmul > 0 ? 1 : -1); vid.wallmode %= 6; }
if(uni == '%') {
else if(NUMBERKEY == '2' && !rug::rugged) { vid.alpha = 1; vid.scale = 0.4; vid.xposition = vid.yposition = 0; }
else if(NUMBERKEY == '3' && !rug::rugged) { vid.alpha = 1; vid.scale = 1; vid.xposition = vid.yposition = 0; }
else if(NUMBERKEY == '4' && !rug::rugged) { vid.alpha = 0; vid.scale = 1; vid.xposition = vid.yposition = 0; }
else if(NUMBERKEY == '5') { vid.wallmode += 60 + (shiftmul > 0 ? 1 : -1); vid.wallmode %= 6; }
else if(NUMBERKEY == '8') { vid.monmode += 60 + (shiftmul > 0 ? 1 : -1); vid.monmode %= 6; }
else if(uni == '%') {
if(vid.wallmode == 0) vid.wallmode = 6;
vid.wallmode--;
}
else return false;
return true;
}
else {
if(NUMBERKEY == '1') { vid.yshift = 0; vid.sspeed = 0; }
if(NUMBERKEY == '2') { vid.yshift = 0; vid.sspeed = -10; }
if(NUMBERKEY == '3') { vid.yshift = 2; vid.sspeed = 0; }
if(NUMBERKEY == '5') { vid.wallmode = vid.wallmode == 5 ? 4 : 5; }
else if(NUMBERKEY == '2') { vid.yshift = 0; vid.sspeed = -10; }
else if(NUMBERKEY == '3') { vid.yshift = 2; vid.sspeed = 0; }
else if(NUMBERKEY == '5') { vid.wallmode = vid.wallmode == 5 ? 4 : 5; }
else return false;
return true;
}
if(NUMBERKEY == '6') vid.grid = !vid.grid;
if(NUMBERKEY == '7') { vid.darkhepta = !vid.darkhepta; }
}
bool haveMobileCompass() {

View File

@ -89,6 +89,8 @@ namespace dialog {
add_key_action(lastItem().key, action);
}
void add_action_push(const reaction_t& action) { add_action([action] { pushScreen(action); }); }
void handler(int sym, int uni) {
dialog::handleNavigation(sym, uni);
if(doexiton(sym, uni)) popScreen();

View File

@ -74,6 +74,35 @@ void buildHelpText() {
"The monster could also kill you by moving into your location, but the game "
"automatically cancels all moves which result in that.\n\n"
);
if(shmup::on) {
help += XLAT(
"Shmup (shoot'em up) mode: You can play a hyperbolic shoot'em up game. The game is based "
"on the usual turn-based grid-based HyperRogue, but there are some changes. You fight by "
"throwing knives, and you have three extra lives. There are no allies, so all Orbs "
"related to allies give you extra lives instead (up to 5). Some other rules have been "
"adapted too.\n\n");
}
if(shmup::on && multi::players > 1) {
help += XLAT(
"Multiplayer: Play cooperatively (locally); treasures, kills, and deaths are calculated "
"for each player too, for more competitive play. Orbs and treasures are shared, orbs drain "
"faster, knives recharge slower, and player characters are not allowed to separate.\n\n");
}
if(multi::players > 1 && !shmup::on) {
help += XLAT(
"Turn-based multiplayer: Turns are executed in parallel. A player can leave the game "
"by pressing a designated key (useful when about to get killed or lost). The following "
"Orbs work to bring such players back: ");
help += XLATN(iinf[itOrbLife].name); help += ", ";
help += XLATN(iinf[itOrbFriend].name); help += ", ";
help += XLATN(iinf[itOrbUndeath].name); help += ", ";
help += XLATN(iinf[itOrbTeleport].name); help += ", ";
help += XLATN(iinf[itOrbSafety].name); help += "\n\n";
}
#if CAP_INV
if(inv::on)

15
hyper.h
View File

@ -869,6 +869,8 @@ namespace multi {
void checklastmove();
void leaveGame(int i);
void configure();
void showConfigureMultiplayer();
}
template<class T> class hookset : public map<int, function<T>> {};
@ -963,6 +965,8 @@ namespace shmup {
extern monster *pc[MAXPLAYER];
int reflect(cell*& c2, cell*& mbase, transmatrix& nat);
void switch_shmup();
}
transmatrix& ggmatrix(cell *c);
@ -1944,6 +1948,9 @@ namespace dialog {
void addBack();
void add_action(const reaction_t& action);
void add_key_action(int key, const reaction_t& action);
void add_action_push(const reaction_t& action);
inline void add_action_push(void a()) { add_action_push((reaction_t) a); }
string view_edited_string();
void start_editing(string& s);
@ -2625,11 +2632,7 @@ void closeJoysticks();
void preparesort();
#if ISMOBILE==1
#define SHMUPTITLE "shoot'em up mode"
#else
#define SHMUPTITLE "shoot'em up / multiplayer / input"
#endif
bool dodrawcell(cell *c);
void drawcell(cell *c, transmatrix V, int spinv, bool mirrored);
@ -2643,7 +2646,7 @@ extern function <void(int sym, int uni)> keyhandler;
#if CAP_SDL
extern function <bool(SDL_Event &ev)> joyhandler;
#endif
void gmodekeys(int sym, int uni);
bool gmodekeys(int sym, int uni);
// check for a plain number key
#define NUMBERKEY (interpret_as_direction(sym, uni) ? 0 : uni)
@ -2662,7 +2665,7 @@ namespace scores { void load(); }
void gotoHelp(const string& h);
void showCustomizeChar();
void showCheatMenu();
void showDisplayMode();
void showGraphQuickKeys();
void showChangeMode();
void showEuclideanMenu();
void show3D();

228
menus.cpp
View File

@ -204,10 +204,9 @@ void showMainMenu() {
dialog::init(XLAT("HyperRogue %1", VER), 0xC00000, 200, 100);
dialog::addItem(XLAT("basic configuration"), 'b');
dialog::addItem(XLAT("graphics configuration"), 'g');
dialog::addItem(XLAT("special display modes"), 'd');
dialog::addItem(XLAT("special game modes"), 'm');
dialog::addItem(XLAT("settings"), 's');
dialog::add_action([] { pushScreen(showSettings); });
dialog::addItem(XLAT("special modes"), 'm');
#if CAP_SAVE
dialog::addItem(XLAT("local highscores"), 't');
@ -262,9 +261,6 @@ void showMainMenu() {
dialog::handleNavigation(sym, uni);
if(sym == SDLK_F1 || uni == 'h') gotoHelp("@");
else if(uni == 'c' && cheater) pushScreen(showCheatMenu);
else if(uni == 'b') pushScreen(showBasicConfig);
else if(uni == 'g') pushScreen(showGraphConfig);
else if(uni == 'd') pushScreen(showDisplayMode);
else if(uni == 'm') pushScreen(showChangeMode);
else if(uni == 'R') dialog::do_if_confirmed([] {
#if CAP_STARTANIM
@ -324,15 +320,11 @@ void editScale() {
dialog::scaleSinh();
}
void showDisplayMode() {
void showGraphQuickKeys() {
cmode = sm::SIDE | sm::MAYDARK;
gamescreen(0);
dialog::init(XLAT("special display modes"));
const char *wdmodes[6] = {"ASCII", "black", "plain", "Escher", "plain/3D", "Escher/3D"};
const char *mdmodes[6] = {"ASCII", "items only", "items and monsters", "high contrast",
"3D", "high contrast/3D"};
dialog::init(XLAT("quick options"));
if(DIM == 2) {
dialog::addBoolItem(XLAT("orthogonal projection"), vid.alpha >= 500, '1');
@ -346,97 +338,29 @@ void showDisplayMode() {
dialog::addBoolItem(XLAT("third person perspective"), vid.yshift > 0 && vid.sspeed > -5, '3');
}
const char *wdmodes[6] = {"ASCII", "black", "plain", "Escher", "plain/3D", "Escher/3D"};
dialog::addSelItem(XLAT("wall display mode"), XLAT(wdmodes[vid.wallmode]), '5');
if(getcstat == '5')
mouseovers = XLAT("also hold Alt during the game to toggle high contrast");
const char *mdmodes[6] = {"ASCII", "items only", "items and monsters", "high contrast",
"3D", "high contrast/3D"};
dialog::addSelItem(XLAT("monster display mode"), XLAT(mdmodes[vid.monmode]), '8');
dialog::addBoolItem(XLAT("draw the grid"), (vid.grid), '6');
dialog::addBoolItem(XLAT("mark heptagons"), (vid.darkhepta), '7');
dialog::addSelItem(XLAT("3D configuration"), "", '9');
if(DIM == 2)
dialog::addSelItem(XLAT("scale factor"), fts(vid.scale), 'z');
dialog::addSelItem(XLAT("monster display mode"), XLAT(mdmodes[vid.monmode]), 'm');
dialog::addBreak(50);
#if CAP_EDIT
if(DIM == 2)
dialog::addBoolItem(XLAT("vector graphics editor"), (false), 'g');
#endif
#if CAP_TEXTURE
if(DIM == 2)
dialog::addBoolItem(XLAT("texture mode"), texture::config.tstate == texture::tsActive, 't');
#endif
// display modes
#if CAP_RUG
if(DIM == 2)
dialog::addBoolItem(XLAT("hypersian rug mode"), (rug::rugged), 'u');
#endif
#if CAP_MODEL
if(DIM == 2)
dialog::addBoolItem(XLAT("paper model creator"), (false), 'n');
#endif
dialog::addBoolItem(XLAT("models and projections"), pmodel, 'a');
dialog::addBoolItem(XLAT("animations/history"), anims::any_on(), 'A');
// dialog::addBoolItem(XLAT("expansion"), viewdists, 'x');
showAllConfig();
dialog::addBreak(50);
dialog::addInfo("Hint: these keys usually work during the game");
dialog::addInfo("also hold Alt during the game to toggle high contrast");
dialog::addBreak(50);
dialog::addBack();
dialog::display();
keyhandler = [] (int sym, int uni) {
dialog::handleNavigation(sym, uni);
char xuni = uni;
// if((xuni >= 'A' && xuni <= 'Z') || (xuni >= 1 && xuni <= 26)) xuni |= 32;
if(xuni == 'p') projectionDialog();
if(xuni == 'z') editScale();
#if CAP_TEXTURE
if(xuni == 't') pushScreen(texture::showMenu);
#endif
if(xuni == 'm') { vid.monmode += 60 + (shiftmul > 0 ? 1 : -1); vid.monmode %= 6; }
if(xuni == '9') pushScreen(show3D);
#if CAP_EDIT
else if(xuni == 'g') {
pushScreen(mapeditor::showDrawEditor);
mapeditor::initdraw(cwt.at);
}
#endif
else if(xuni == 'x') {
viewdists = !viewdists;
}
#if CAP_RUG
else if(xuni == 'u') {
//if(sphere) projectionDialog();
//else
rug::select();
}
#endif
else if(uni == 'a')
pushScreen(conformal::model_menu);
#if CAP_ANIMATIONS
else if(uni == 'A')
pushScreen(anims::show);
#endif
#if CAP_MODEL
else if(xuni == 'n')
netgen::run();
#endif
else gmodekeys(sym, uni);
handleAllConfig(sym, xuni);
if(gmodekeys(sym, uni)) ;
else if(doexiton(sym, uni)) popScreen();
};
}
@ -486,19 +410,82 @@ void help_nochaos() {
"\n\nYou need to reach Crossroads IV to unlock the Chaos mode."
);
}
void showCreative() {
cmode = sm::SIDE | sm::MAYDARK;
gamescreen(3);
dialog::init(XLAT("creative mode"));
dialog::addItem("map editor", 'm');
dialog::add_action([] {
if(tactic::on)
addMessage(XLAT("Not available in the pure tactics mode!"));
else if(daily::on) {
addMessage(XLAT("Not available in the daily challenge!"));
}
else dialog::cheat_if_confirmed([] {
cheater++;
pushScreen(mapeditor::showMapEditor);
lastexplore = turncount;
addMessage(XLAT("You activate your terraforming powers!"));
});
});
#if CAP_EDIT
dialog::addItem(XLAT("vector graphics editor"), 'g');
dialog::add_action([] {
pushScreen(mapeditor::showDrawEditor);
mapeditor::initdraw(cwt.at);
});
#endif
// display modes
#if CAP_MODEL
if(DIM == 2) {
dialog::addItem(XLAT("paper model creator"), 'n');
dialog::add_action([] { netgen::run(); });
}
#endif
dialog::addItem(XLAT("screenshots"), 's');
dialog::add_action([] () { pushScreen(shot::menu); });
dialog::addBoolItem(XLAT("animations/history"), anims::any_on(), 'A');
dialog::add_action_push(anims::show);
#if CAP_TEXTURE
if(DIM == 2) {
dialog::addBoolItem(XLAT("texture mode"), texture::config.tstate == texture::tsActive, 't');
dialog::add_action_push(texture::showMenu);
}
#endif
dialog::addBoolItem(XLAT("cheat mode"), (cheater), 'c');
dialog::add_action(enable_cheat);
// dialog::addBoolItem(XLAT("expansion"), viewdists, 'x');
dialog::addBreak(50);
dialog::addBack();
dialog::display();
}
void showChangeMode() {
gamescreen(3);
dialog::init(XLAT("special game modes"));
// gameplay modes
dialog::init(XLAT("special modes"));
// gameplay modes
#if CAP_TOUR
dialog::addBoolItem(XLAT("Tutorial"), tour::on, 'T');
#endif
dialog::addBoolItem(XLAT("creative mode"), (false), 'c');
dialog::add_action_push(showCreative);
dialog::addBoolItem(XLAT("experiment with geometry"), geometry || CHANGED_VARIATION || viewdists, 'e');
dialog::addBoolItem(XLAT(SHMUPTITLE), (shmup::on || multi::players > 1), 's');
dialog::addBreak(100);
dialog::addBoolItem(XLAT(SHMUPTITLE), shmup::on, 's');
dialog::addBoolItem(XLAT("multiplayer"), multi::players > 1, 'm');
if(!shmup::on) dialog::addSelItem(XLAT("hardcore mode"),
hardcore && !pureHardcore() ? XLAT("PARTIAL") : ONOFF(hardcore), 'h');
if(getcstat == 'h')
@ -519,14 +506,6 @@ void showChangeMode() {
dialog::addBoolItem(XLAT("Strange Challenge"), daily::on, 'z');
#endif
dialog::addBreak(50);
// cheating and map editor
dialog::addBoolItem(XLAT("cheat mode"), (cheater), 'c');
#if CAP_EDIT
dialog::addBoolItem(XLAT("map editor"), (false), 'm');
#endif
dialog::addBreak(50);
dialog::addBack();
@ -543,9 +522,6 @@ void showChangeMode() {
pushScreen(daily::showMenu);
#endif
else if(uni == 'c')
enable_cheat();
else if(xuni == 'e')
runGeometryExperiments();
else if(xuni == 't') {
@ -583,28 +559,9 @@ void showChangeMode() {
else
dialog::do_if_confirmed([] { restart_game(rg::princess); });
}
#if CAP_EDIT
else if(xuni == 'm') {
if(tactic::on)
addMessage(XLAT("Not available in the pure tactics mode!"));
else if(daily::on) {
addMessage(XLAT("Not available in the daily challenge!"));
}
else dialog::cheat_if_confirmed([] {
cheater++;
pushScreen(mapeditor::showMapEditor);
lastexplore = turncount;
addMessage(XLAT("You activate your terraforming powers!"));
});
}
#endif
else if(xuni == 's') {
#if ISMOBILE==1
restart_game(rg::shmup);
#else
shmup::configure();
#endif
}
else if(xuni == 's')
dialog::do_if_confirmed(shmup::switch_shmup);
else if(xuni == 'h' && !shmup::on)
switchHardcore();
else if(xuni == 'r') {
@ -984,9 +941,6 @@ int read_menu_args() {
else if(argis("-d:main")) {
PHASEFROM(2); launch_dialog(showMainMenu);
}
else if(argis("-d:display")) {
PHASEFROM(2); launch_dialog(showDisplayMode);
}
else if(argis("-d:mode")) {
PHASEFROM(2); launch_dialog(showChangeMode);
}

View File

@ -147,7 +147,7 @@ hint hints[] = {
dialog::addItem(XLAT("special display modes"), 'z');
},
[]() {
pushScreen(showDisplayMode);
pushScreen(conformal::model_menu);
}},
{

174
shmup.cpp
View File

@ -357,82 +357,75 @@ struct joy_configurer {
struct shmup_configurer {
bool shmupcfg;
int playercfg;
shmup_configurer() { shmupcfg = shmup::on; playercfg = multi::players; }
void operator()() {
#if CAP_SDL
cmode = sm::SHMUPCONFIG;
dialog::init(SHMUPTITLE);
dialog::addItem(player_count_name(playercfg), 'n');
dialog::addItem(XLAT(shmupcfg ? "shoot'em up mode" : "turn-based mode"), 's');
gamescreen(3);
dialog::init(XLAT("keyboard & joysticks"));
dialog::addItem(XLAT(shmup::on == shmupcfg && players == playercfg ?
"continue playing"
: "start a new game"), '0');
bool haveconfig = shmup::on || players > 1 || multi::alwaysuse;
if(shmupcfg || multi::alwaysuse || playercfg > 1)
dialog::addItem(XLAT("configure player 1") + dsc(0), '1');
if(haveconfig)
dialog::addItem(XLAT("configure player 1"), '1');
else
dialog::addBreak(100);
if(playercfg > 1)
dialog::addItem(XLAT("configure player 2") + dsc(1), '2');
else if(playercfg == 1 && !shmupcfg)
if(players > 1)
dialog::addItem(XLAT("configure player 2"), '2');
else if(players == 1 && !shmup::on)
dialog::addSelItem(XLAT("input"), XLAT(multi::alwaysuse ? "config" : "default"), 'a');
else
dialog::addBreak(100);
if(playercfg > 2)
dialog::addItem(XLAT("configure player 3") + dsc(2), '3');
if(players > 2)
dialog::addItem(XLAT("configure player 3"), '3');
#if CAP_SDLJOY
else if(playercfg == 1 && !shmupcfg && !shmupcfg && !multi::alwaysuse)
else if(!haveconfig)
dialog::addItem(XLAT("old style joystick configuration"), 'b');
#endif
else dialog::addBreak(100);
if(playercfg > 3)
dialog::addItem(XLAT("configure player 4") + dsc(3), '4');
if(players > 3)
dialog::addItem(XLAT("configure player 4"), '4');
else if(!shmup::on && !multi::alwaysuse) {
dialog::addBoolItem(XLAT("smooth scrolling"), smooth_scrolling, 'c');
}
else if(alwaysuse)
dialog::addInfo(XLAT("note: configured input is designed for"));
else dialog::addBreak(100);
if(playercfg > 4)
dialog::addItem(XLAT("configure player 5") + dsc(4), '5');
if(players > 4)
dialog::addItem(XLAT("configure player 5"), '5');
else if(!shmup::on && !multi::alwaysuse) {
const char *axmodes[5] = {"OFF", "auto", "light", "heavy", "arrows"};
dialog::addSelItem(XLAT("help for keyboard users"), XLAT(axmodes[vid.axes]), 'h');
dialog::add_action([] {vid.axes += 60 + (shiftmul > 0 ? 1 : -1); vid.axes %= 5; } );
}
else if(alwaysuse)
dialog::addInfo(XLAT("multiplayer and shmup mode; some features"));
else dialog::addBreak(100);
if(playercfg > 5)
dialog::addItem(XLAT("configure player 6") + dsc(5), '6');
if(players > 5)
dialog::addItem(XLAT("configure player 6"), '6');
else if(alwaysuse)
dialog::addInfo(XLAT("work worse if you use it."));
else dialog::addBreak(100);
if(playercfg > 6)
dialog::addItem(XLAT("configure player 7") + dsc(6), '7');
if(players > 6)
dialog::addItem(XLAT("configure player 7"), '7');
else dialog::addBreak(100);
if(shmupcfg || multi::alwaysuse || playercfg > 1)
if(shmup::on || multi::alwaysuse || players > 1)
dialog::addItem(XLAT("configure panning and general keys"), 'p');
else dialog::addBreak(100);
#if CAP_SDLJOY
if(numsticks > 0) {
if(shmupcfg || multi::alwaysuse || playercfg > 1)
if(shmup::on || multi::alwaysuse || players > 1)
dialog::addItem(XLAT("configure joystick axes"), 'j');
else dialog::addBreak(100);
}
#endif
if(multi::players > 1)
dialog::addItem(XLAT("reset per-player statistics"), 'r');
else dialog::addBreak(100);
dialog::addBreak(50);
#if CAP_CONFIG
dialog::addItem(XLAT("save the configuration"), 'c');
#endif
dialog::addHelp();
dialog::addBack();
@ -443,7 +436,7 @@ struct shmup_configurer {
}
void handleConfig(int sym, int uni) {
auto& cmdlist = shmupcfg ? (DIM == 3 ? playercmds_shmup3 : playercmds_shmup) : playercmds_turn;
auto& cmdlist = shmup::on ? (DIM == 3 ? playercmds_shmup3 : playercmds_shmup) : playercmds_turn;
#if CAP_SDL
if(uni == '1') pushScreen(key_configurer(1, cmdlist));
@ -455,74 +448,15 @@ struct shmup_configurer {
else if(uni == '6') pushScreen(key_configurer(7, cmdlist));
else if(uni == '7') pushScreen(key_configurer(8, cmdlist));
#if CAP_SDLJOY
else if(uni == 'j') pushScreen(joy_configurer(playercfg));
else if(uni == 'j') pushScreen(joy_configurer(players));
#endif
else if(uni == 'a') multi::alwaysuse = !multi::alwaysuse;
#if CAP_SDLJOY
else if(uni == 'b') pushScreen(showJoyConfig);
#endif
else if(uni == 'c') smooth_scrolling = !smooth_scrolling;
else if(uni == 'r')
for(int i=0; i<MAXPLAYER; i++)
kills[i] = deaths[i] = treasures[i] = 0;
else if(uni == 's' || uni == 't')
shmupcfg = !shmupcfg;
#if CAP_CONFIG
else if(uni == 'c')
hr::saveConfig();
#endif
else if(uni == 'n' || uni == 'N') {
playercfg += shiftmul > 0 ? 1 : -1;
playercfg %= MAXPLAYER;
if(playercfg <= 0) playercfg += MAXPLAYER;
}
else if(sym == SDLK_F1 || uni == '?' || uni == 'h') {
gotoHelp("");
help = XLAT(
"Shmup (shoot'em up) mode: You can play a hyperbolic shoot'em up game. The game is based "
"on the usual turn-based grid-based HyperRogue, but there are some changes. You fight by "
"throwing knives, and you have three extra lives. There are no allies, so all Orbs "
"related to allies give you extra lives instead (up to 5). Some other rules have been "
"adapted too.\n\n");
help += XLAT(
"Multiplayer: Play cooperatively (locally); treasures, kills, and deaths are calculated "
"for each player too, for more competitive play. Orbs and treasures are shared, orbs drain "
"faster, knives recharge slower, and player characters are not allowed to separate.\n\n");
help += XLAT(
"Turn-based multiplayer: Turns are executed in parallel. A player can leave the game "
"by pressing a designated key (useful when about to get killed or lost). The following "
"Orbs work to bring such players back: ");
help += XLATN(iinf[itOrbLife].name); help += ", ";
help += XLATN(iinf[itOrbFriend].name); help += ", ";
help += XLATN(iinf[itOrbUndeath].name); help += ", ";
help += XLATN(iinf[itOrbTeleport].name); help += ", ";
help += XLATN(iinf[itOrbSafety].name); help += "\n\n";
help += XLAT("This menu can be also used to configure keys.\n\n");
}
else if(doexiton(sym, uni)) {
popScreen();
auto sc = shmupcfg;
auto pc = playercfg;
if(shmup::on != sc || pc != players) dialog::do_if_confirmed([sc, pc] {
if(shmup::on != sc) {
stop_game();
switch_game_mode(rg::shmup);
resetScores();
}
if(pc != players) {
stop_game();
players = pc;
resetScores();
}
start_game();
});
}
#endif
else if(doexiton(sym, uni)) popScreen();
}
};
@ -530,6 +464,36 @@ void configure() {
pushScreen(shmup_configurer());
}
void showConfigureMultiplayer() {
gamescreen(1);
dialog::init("multiplayer");
for(int i=1; i <= MAXPLAYER; i++) {
string s = player_count_name(i);
if(i <= players) s += dsc(i-1);
dialog::addBoolItem(s, '1', i == multi::players);
dialog::add_action([i] {
dialog::do_if_confirmed([i] {
stop_game();
players = i;
start_game();
});
});
}
if(multi::players > 1) {
dialog::addItem(XLAT("reset per-player statistics"), 'r');
dialog::add_action([] {
for(int i=0; i<MAXPLAYER; i++)
kills[i] = deaths[i] = treasures[i] = 0;
});
}
else dialog::addBreak(100);
dialog::addBack();
dialog::display();
}
#define NUMACT 128
enum pcmds {
@ -3826,6 +3790,14 @@ auto hooks = addHook(clearmemory, 0, shmup::clearMemory) +
else it++;
}
});
void switch_shmup() {
stop_game();
switch_game_mode(rg::shmup);
resetScores();
start_game();
configure();
}
}
}