// HyperRogue menus // Copyright (C) 2011-2016 Zeno Rogue, see 'hyper.cpp' for details #include "dialogs.cpp" #define BLACKISH 0x404040 #define REDDISH 0x400000 ld whatever = 0; int PREC(ld x) { ld sh = shiftmul; if(sh > -.2 && sh < .2) x = 10.01; return int(shiftmul * x); } void showOverview() { DEBB(DF_GRAPH, (debugfile,"show overview\n")); mouseovers = XLAT("world overview"); mouseovers += " "; mouseovers += XLAT(" kills: %1/%2", its(tkills()), its(killtypes())); mouseovers += XLAT(" $$$: %1", its(gold())); if(hellUnlocked()) { int i1, i2; countHyperstoneQuest(i1, i2); mouseovers += XLAT(" Hyperstone: %1/%2", its(i1), its(i2)); } else mouseovers += XLAT(" Hell: %1/9", its(orbsUnlocked())); bool pages; int nl = LAND_OVER, nlm; eLand *landtab = land_over; if(randomPatternsMode) { nl = nlm = RANDLANDS; landtab = randlands; } else { pages = true; landtab += dialog::handlePage(nl, nlm, (nl+1)/2); } int vf = min((vid.yres-64-vid.fsize*2) / nlm, vid.xres/40); eLand curland = cwt.c->land; if(curland == laPalace && princess::dist(cwt.c) < OUT_OF_PRISON) curland = laPrincessQuest; if(isElemental(curland)) curland = laElementalWall; getcstat = '0'; for(int i=0; i= 25) col = 0xFFD500; else if(lv >= 10) col = 0x00D500; else if(items[it]) col = 0xC0C0C0; else col = BLACKISH; if(chaosmode && noChaos(l)) col = REDDISH; int c8 = (vf+2)/3; if(displayfrZ(xr*24-c8*6, i0, 1, vf-4, its(items[it]), col, 16)) getcstat = 2000+it; if(!cheater) if(displayfrZ(xr*24, i0, 1, vf-4, its(hiitems[modecode()][it]), col, 16)) getcstat = 2000+it; if(items[it]) col = iinf[it].color; else col = BLACKISH; if(chaosmode && noChaos(l)) col = REDDISH; if(displayfrZ(xr*24+c8*4, i0, 1, vf-4, s0 + iinf[it].glyph, col, 16)) getcstat = 2000+it; if(displayfrZ(xr*24+c8*5, i0, 1, vf-4, XLAT1(iinf[it].name), col, 0)) getcstat = 2000+it; eItem io = orbType(l); if(io == itShard) { if(items[it] >= 10) col = winf[waMirror].color; else col = BLACKISH; if(chaosmode && noChaos(l)) col = REDDISH; if(displayfrZ(xr*46, i0, 1, vf-4, XLAT1(winf[waMirror].name), col, 0)) getcstat = 3000+waMirror; if(getcstat == 3000+waMirror) mouseovers = XLAT( olrDescriptions[getOLR(io, cwt.c->land)], cwt.c->land, it, treasureType(cwt.c->land)); } else if(io) { if(lv >= 25) col = 0xFFD500; else if(lv >= 10) col = 0xC0C0C0; else col = BLACKISH; if(chaosmode && noChaos(l)) col = REDDISH; if(displayfrZ(xr*46-c8*4, i0, 1, vf-4, its(items[io]), col, 16)) getcstat = 2000+io; if(lv >= 10) col = iinf[io].color; else col = BLACKISH; if(chaosmode && noChaos(l)) col = REDDISH; if(displayfrZ(xr*46-c8, i0, 1, vf-4, s0 + iinf[io].glyph, col, 16)) getcstat = 2000+io; if(displayfrZ(xr*46, i0, 1, vf-4, XLAT1(iinf[io].name), col, 0)) getcstat = 2000+io; if(getcstat == 2000+io) mouseovers = XLAT( olrDescriptions[getOLR(io, curland)], curland, it, treasureType(curland)); } } dialog::displayPageButtons(3, pages); keyhandler = [] (int sym, int uni) { int umod = uni % 1000; int udiv = uni / 1000; if(udiv == 1 && umod < landtypes) { if(cheater && !hiliteclick) { eLand l = eLand(umod); cheater++; bool princ = (l == laPrincessQuest); if(princ) { if(kills[moVizier] == 0) kills[moVizier] = 1; princess::forceMouse = true; princess::gotoPrincess = true; l = laPalace; } cheatMoveTo(l); popScreen(); canmove = true; if(princ) fullcenter(); } else gotoHelp(generateHelpForLand(eLand(umod))); } else if(udiv == 2 && umod < ittypes) { if(cheater && !hiliteclick) { cheater++; int ic = itemclass(eItem(umod)); if(ic == IC_TREASURE) items[umod] += PREC(10); if(ic == IC_ORB) items[umod] += PREC(60); if(umod == itGreenStone) items[umod] += PREC(100); else if(ic == IC_OTHER) items[umod] += (shiftmul>0?1:-1); if(items[umod] < 0) items[umod] = 0; if(hardcore) canmove = true; else checkmove(); } else gotoHelp(generateHelpForItem(eItem(umod))); } else if(udiv == 3 && umod < walltypes) gotoHelp(generateHelpForWall(eWall(umod))); else if(uni == SDLK_F1) gotoHelp( "This displays all lands available in the game. " "Bonus lands (available only in separate challenges) " "are not included. Lands written in dark have to be " "unlocked, and lands in dark red are unavailable " "because of using special options. Click on any " "land or item to get information about it. Hover over " "an Orb to know its relation to the current land. " "Cheaters can click to move between lands, and use the " "mousewheel to gain or lose treasures and orbs quickly (Ctrl = precise, Shift = reverse)." ); else if(dialog::handlePageButtons(uni)) ; else if(doexiton(sym, uni)) popScreen(); }; } bool checkHalloweenDate() { time_t t = time(NULL); struct tm tm = *localtime(&t); int month = tm.tm_mon + 1; int day = tm.tm_mday; if(month == 10 && day >= 24) return true; if(month == 11 && day <= 7) return true; return false; } void showMainMenu() { gamescreen(2); getcstat = ' '; 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'); #ifndef NOSAVE dialog::addItem(XLAT("local highscores"), 't'); #endif dialog::addItem(XLAT("help"), 'h'); dialog::lastItem().keycaption += " / F1"; if(cheater) dialog::addItem(XLAT("cheats"), 'c'); else dialog::addBreak(100); dialog::addItem(XLAT("restart game"), 'r'); dialog::lastItem().keycaption += " / F5"; string q; #ifdef MOBILE dialog::addItem(XLAT("visit the website"), 'q'); #else q = quitsaves() ? "save" : "quit"; q = q + " the game"; dialog::addItem(XLAT(q), 'q'); dialog::lastItem().keycaption += " / F10"; #endif if(canmove) q = "review your quest"; else q = "game over screen"; dialog::addItem(XLAT(q), SDLK_ESCAPE); dialog::addItem(XLAT("world overview"), 'o'); if(inv::on) dialog::addItem(XLAT("inventory"), 'i'); if(checkHalloweenDate()) dialog::addItem(XLAT("Halloween mini-game"), 'y'-96); #ifdef ROGUEVIZ dialog::addItem(XLAT("rogueviz menu"), 'u'); #endif #ifdef MOBILE #ifdef HAVE_ACHIEVEMENTS dialog::addItem(XLAT("leaderboards/achievements"), '3'); #endif #endif #ifdef ANDROIDSHARE dialog::addItem("SHARE", 's'-96); #endif if(!canmove) q = "review the scene"; else if(turncount > 0) q = "continue game"; else q = "play the game!"; dialog::addItem(XLAT(q), ' '); dialog::display(); keyhandler = [] (int sym, int uni) { dialog::handleNavigation(sym, uni); if(sym == SDLK_F1 || sym == 'h') gotoHelp(help); else if(sym == 'c' && cheater) pushScreen(showCheatMenu); else if(sym == 'b') pushScreen(showBasicConfig); else if(sym == 'g') pushScreen(showGraphConfig); else if(sym == 'd') pushScreen(showDisplayMode); else if(sym == 'm') pushScreen(showChangeMode); #ifndef NOSAVE else if(sym == 't') loadScores(); #endif else if(uni == 'y'-96) { if(!sphere) { euclidland = laHalloween; restartGame('E'); vid.alpha = 999; vid.scale = 998; popScreen(); } else { restartGame('E'); vid.alpha = 1; vid.scale = 1; popScreen(); } } else if(sym == 'r' || sym == SDLK_F5) { restartGame(); popScreen(); } else if(sym == 'q' || sym == SDLK_F10) quitmainloop = true; else if(sym == 'o') { clearMessages(); pushScreen(showOverview); } #ifdef INV else if(sym == 'i') { clearMessages(); pushScreen(inv::show()); } #endif else if(sym == SDLK_ESCAPE) showMissionScreen(); #ifdef MOBILE #ifdef HAVE_ACHIEVEMENTS else if(sym == '3') { achievement_final(false); pushScreen(leader::showMenu); } #endif #endif #ifdef ROGUEVIZ else if(uni == 'u') pushScreen(rogueviz::showMenu); #endif else if(doexiton(sym, uni)) { popScreenAll(); msgs.clear(); } }; } void showDisplayMode() { gamescreen(3); 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::addBoolItem(XLAT("orthogonal projection"), vid.alpha >= 500, '1'); dialog::addBoolItem(XLAT("small Poincaré model"), vid.alpha == 1 && vid.scale < 1, '2'); dialog::addBoolItem(XLAT("big Poincaré model"), vid.alpha == 1 && vid.scale >= 1, '3'); dialog::addBoolItem(XLAT("Klein-Beltrami model"), vid.alpha == 0, '4'); dialog::addSelItem(XLAT("wall display mode"), XLAT(wdmodes[vid.wallmode]), '5'); dialog::addBoolItem(XLAT("draw the grid"), (vid.grid), '6'); dialog::addBoolItem(XLAT("mark heptagons"), (vid.darkhepta), '7'); dialog::addSelItem(XLAT("3D configuration"), "", '9'); dialog::addSelItem(XLAT("scale factor"), fts(vid.scale), 'z'); dialog::addSelItem(XLAT("monster display mode"), XLAT(mdmodes[vid.monmode]), 'm'); dialog::addBreak(50); #ifndef NOEDIT dialog::addBoolItem(XLAT("vector graphics editor"), (false), 'g'); #endif // display modes #ifndef NORUG dialog::addBoolItem(XLAT("hypersian rug mode"), (rug::rugged), 'u'); #endif #ifndef NOMODEL dialog::addBoolItem(XLAT("paper model creator"), (false), 'n'); #endif dialog::addBoolItem(XLAT("conformal/history mode"), (conformal::on), 'a'); dialog::addBoolItem(XLAT("expansion"), viewdists, 'x'); showAllConfig(); 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') { dialog::editNumber(vid.scale, .001, 1000, .1, 1, XLAT("scale factor"), XLAT("Scale the displayed model.")); dialog::scaleLog(); dialog::sidedialog = true; } if(xuni == 'm') { vid.monmode += 60 + (shiftmul > 0 ? 1 : -1); vid.monmode %= 6; } if(xuni == '9') pushScreen(show3D); #ifndef NOEDIT else if(xuni == 'g') { pushScreen(mapeditor::showDrawEditor); mapeditor::initdraw(cwt.c); } #endif else if(xuni == 'x') { viewdists = !viewdists; popScreen(); } #ifndef NORUG else if(xuni == 'u') { if(sphere) projectionDialog(); else rug::select(); } #endif else if(uni == 'a') pushScreen(conformal::show); #ifndef NOMODEL else if(xuni == 'n') pushScreen(netgen::show); #endif else gmodekeys(sym, uni); handleAllConfig(sym, xuni); }; } void gmodekeys(int sym, int uni) { if(uni == '1') { vid.alpha = 999; vid.scale = 998; } if(uni == '2') { vid.alpha = 1; vid.scale = 0.4; } if(uni == '3') { vid.alpha = 1; vid.scale = 1; } if(uni == '4') { vid.alpha = 0; vid.scale = 1; } if(uni == '5') { vid.wallmode += 60 + (shiftmul > 0 ? 1 : -1); vid.wallmode %= 6; } if(uni == '6') vid.grid = !vid.grid; if(uni == '7') { vid.darkhepta = !vid.darkhepta; } if(uni == '%' && sym == '5') { if(vid.wallmode == 0) vid.wallmode = 6; vid.wallmode--; } } void switchHardcore() { if(hardcore && !canmove) { restartGame(); hardcore = false; popScreen(); } else if(hardcore && canmove) { hardcore = false; } else { hardcore = true; canmove = true; hardcoreAt = turncount; } if(hardcore) addMessage("One wrong move, and it is game over!"); else addMessage("Not so hardcore?"); if(pureHardcore()) popScreen(); } void showChangeMode() { gamescreen(3); dialog::init(XLAT("special game modes")); // gameplay modes #ifdef TOUR dialog::addBoolItem(XLAT("Tutorial"), tour::on, 'T'); #endif dialog::addBoolItem(XLAT("Euclidean/elliptic mode"), (euclid || sphere), 'e'); dialog::addBoolItem(XLAT(SHMUPTITLE), (shmup::on || multi::players > 1), 's'); if(!shmup::on) dialog::addSelItem(XLAT("hardcore mode"), hardcore && !pureHardcore() ? XLAT("PARTIAL") : ONOFF(hardcore), 'h'); multi::cpid = 0; dialog::addBoolItem(XLAT("%1 Challenge", moPrincess), (princess::challenge), 'p'); dialog::addBoolItem(XLAT("random pattern mode"), (randomPatternsMode), 'r'); dialog::addBoolItem(XLAT("Yendor Challenge"), (yendor::on), 'y'); dialog::addBoolItem(XLAT("pure tactics mode"), (tactic::on), 't'); dialog::addBoolItem(XLAT("heptagonal mode"), (purehepta), '7'); dialog::addBoolItem(XLAT("Chaos mode"), (chaosmode), 'C'); dialog::addBoolItem(XLAT("peaceful mode"), (chaosmode), 'P'); dialog::addBoolItem(XLAT("inventory mode"), (inv::on), 'i'); dialog::addBreak(50); // cheating and map editor dialog::addBoolItem(XLAT("cheat mode"), (cheater), 'c'); #ifndef NOEDIT dialog::addBoolItem(XLAT("map editor"), (false), 'm'); #endif dialog::addBreak(50); dialog::addItem(XLAT("return to the game"), 'v'); dialog::display(); keyhandler = [] (int sym, int uni) { dialog::handleNavigation(sym, uni); char xuni = uni; if(xuni == 'v' || sym == SDLK_ESCAPE) popScreen(); else if(uni == 'c') { if(tactic::on && gold()) { addMessage(XLAT("Not available in the pure tactics mode!")); } else if(!cheater) { cheater++; addMessage(XLAT("You activate your demonic powers!")); #ifndef MOBILE addMessage(XLAT("Shift+F, Shift+O, Shift+T, Shift+L, Shift+U, etc.")); #endif popScreen(); } else { popScreen(); firstland = princess::challenge ? laPalace : laIce; restartGame(); } } else if(xuni == 'e') pushScreen(showEuclideanMenu); else if(xuni == 't') { clearMessages(); pushScreen(tactic::showMenu); } else if(xuni == 'y') { clearMessages(); if(yendor::everwon || autocheat) pushScreen(yendor::showMenu); else gotoHelp(yendor::chelp); } else if(xuni == '7') restartGame('7'); else if(xuni == 'P') pushScreen(peace::showMenu); else if(xuni == 'i') { restartGame('i'); } #ifdef TOUR else if(uni == 'T') { tour::start(); } #endif else if(uni == 'C') { if(chaosUnlocked) restartGame('C'); if(chaosmode) gotoHelp( "In the Chaos mode, lands change very often, and " "there are no walls between them. " "Some lands are incompatible with this." "\n\nYou need to reach Crossroads IV to unlock the Chaos mode." ); } else if(xuni == 'p') { if(!princess::everSaved) addMessage(XLAT("Save %the1 first to unlock this challenge!", moPrincess)); else restartGame('p'); } #ifndef NOEDIT else if(xuni == 'm') { if(tactic::on) addMessage(XLAT("Not available in the pure tactics mode!")); else { cheater++; pushScreen(mapeditor::showMapEditor); lastexplore = turncount; addMessage(XLAT("You activate your terraforming powers!")); } } #endif else if(xuni == 's') { #ifdef MOBILE restartGame('s'); #else multi::shmupcfg = shmup::on; pushScreen(shmup::showShmupConfig); #endif } else if(xuni == 'h' && !shmup::on) switchHardcore(); else if(xuni == 'r') { firstland = laIce; restartGame('r'); } else if(doexiton(sym, uni)) popScreen(); }; } void showCheatMenu() { gamescreen(1); dialog::init("cheat menu"); dialog::addItem(XLAT("return to the game"), ' '); dialog::addBreak(50); dialog::addItem(XLAT("gain orb powers"), 'F'); dialog::addItem(XLAT("summon treasure"), 'T'); dialog::addItem(XLAT("summon dead orbs"), 'D'); dialog::addItem(XLAT("lose all treasure"), 'J'); dialog::addItem(XLAT("gain kills"), 'K'); dialog::addItem(XLAT("Hyperstone Quest"), 'C'); dialog::addItem(XLAT("summon orbs"), 'O'); dialog::addItem(XLAT("gain Orb of Yendor"), 'Y'); dialog::addItem(XLAT("summon lots of treasure"), 'T'-64); dialog::addItem(XLAT("Safety (quick save)"), 'S'); dialog::addItem(XLAT("Select the land ---"), 'L'); dialog::addItem(XLAT("--- and teleport there"), 'U'); dialog::addItem(XLAT("rotate the character"), 'Z'); dialog::addItem(XLAT("summon a Golem"), 'G'); dialog::addItem(XLAT("summon Sandworm"), 'W'); dialog::addItem(XLAT("summon Ivy"), 'I'); dialog::addItem(XLAT("summon a Monster"), 'E'); dialog::addItem(XLAT("summon Thumpers"), 'H'); dialog::addItem(XLAT("summon Bonfire"), 'B'); dialog::addItem(XLAT("summon Mimics"), 'M'); dialog::addItem(XLAT("deplete orb powers"), 'P'); dialog::addItem(XLAT("summon Orb of Yendor"), 'Y'-64); dialog::addItem(XLAT("switch ghost timer"), 'G'-64); dialog::addItem(XLAT("switch web display"), 'W'-64); dialog::display(); keyhandler = [] (int sym, int uni) { dialog::handleNavigation(sym, uni); if(uni != 0) { applyCheat(uni); if(uni == 'F' || uni == 'C' || uni == 'O' || uni == 'S' || uni == 'U' || uni == 'G' || uni == 'W' || uni == 'I' || uni == 'E' || uni == 'H' || uni == 'B' || uni == 'M' || uni == 'P' || uni == 'Y'-64 || uni == 'G'-64 || uni == ' ' || uni == 8 || uni == 13 || uni == SDLK_ESCAPE || uni == 'q' || uni == 'v' || sym == SDLK_ESCAPE || sym == SDLK_F10) popScreen(); } }; } int eupage = 0; int euperpage = 21; #define LAND_SPHEUC ((targetgeometry > 1) ? LAND_SPH : LAND_EUC) #define land_spheuc ((targetgeometry > 1) ? land_sph : land_euc) const char* geometrynames[gGUARD] = { "hyperbolic", "Euclidean", "spherical", "elliptic", "Zebra quotient", "field quotient", "torus" }; void showEuclideanMenu() { gamescreen(4); int s = vid.fsize; vid.fsize = vid.fsize * 4/5; dialog::init(XLAT("Euclidean/elliptic mode")); if(cheater) for(int i=0; i= 25) landvisited[i] = true; landvisited[laCrossroads] = true; landvisited[laIce] = true; landvisited[laMirror] = true; landvisited[laPrincessQuest] = cheater || princess::everSaved; landvisited[laWildWest] = true; landvisited[laHalloween] = true; landvisited[laCA] = true; // for(int i=2; i= LAND_SPHEUC) { dialog::addBreak(100); break; } eLand l = land_spheuc[euperpage * eupage + i]; if(landvisited[l]) { char ch; if(i < 26) ch = 'a' + i; else ch = 'A' + (i-26); dialog::addItem(XLAT1(linf[l].name), ch); } else dialog::addBreak(100); } dialog::addBreak(50); dialog::addItem(XLAT("Return to the hyperbolic world"), '0'); dialog::addItem(XLAT("next page"), '-'); dialog::addBreak(100); dialog::addHelp( XLAT("Choose from the lands visited this game.") + " " + XLAT("Scores and achievements are not") + " " + XLAT("saved in the Euclidean mode!") ); dialog::display(); vid.fsize = s; keyhandler = [] (int sym, int uni) { dialog::handleNavigation(sym, uni); int lid; if(uni >= 'a' && uni <= 'z') lid = uni - 'a'; else if(uni >= 'A' && uni <= 'Z') lid = 26 + uni - 'A'; else lid = -1; if(lid >= 0) lid += euperpage * eupage; if(uni == '0') { targetgeometry = geometry; restartGame('g'); popScreen(); } else if(uni == '5') { targetgeometry = eGeometry(1+targetgeometry); if(targetgeometry == gGUARD) targetgeometry = gEuclid; } else if(uni == '-' || uni == PSEUDOKEY_WHEELUP || uni == PSEUDOKEY_WHEELDOWN) { eupage++; if(eupage * euperpage >= LAND_SPHEUC) eupage = 0; } else if(lid >= 0 && lid < LAND_SPHEUC) { euclidland = land_spheuc[lid]; if(landvisited[euclidland] && euclidland != laOceanWall) { if(targetgeometry != geometry) restartGame('g'); else restartGame(tactic::on ? 't' : 0); // disable PTM if chosen a land from the Euclidean menu if(tactic::on) restartGame('t'); popScreen(); } else euclidland = laIce; } else if(uni == '2' || sym == SDLK_F1) gotoHelp( "If you want to know how much the gameplay is affected by the " "hyperbolic geometry in HyperRogue, this mode is for you!\n\n" "You can play an Euclidean version of each of the lands in " "HyperRogue. Lands which include horocycles (Temple, Caribbean, " "Whirlpool), infinite trees (Zebra, Emerald), or networks of " "ultraparallel lines (Crossroads, Vineyard, Palace) cannot be " "faithfully represented in Euclidean, so yo get more " "or less simplified versions of them. Choose Crossroads to play a game " "where many different lands appear." ); else if(doexiton(sym, uni)) popScreen(); }; } #ifdef MOBILE namespace leader { void showMenu(); void handleKey(int sym, int uni); } #endif void handleQuit(int sym, int uni) { if(uni == 'r' || sym == SDLK_F5) { restartGame(), popScreen(); msgs.clear(); } else if(uni == 'v') pushScreen(showMainMenu); else if(uni == SDLK_ESCAPE) popScreen(); else if(uni == 'o') setAppropriateOverview(); #ifndef NOSAVE else if(uni == 't') { if(!canmove) restartGame(); loadScores(); msgs.clear(); } #endif } #ifdef DEMO bool demoanim; void toggleanim(bool v) { demoanim = v; if(v) { sightrange = 4; vid.wallmode = 5; vid.particles = true; vid.sspeed = -1; vid.mspeed = -1; geom3::highdetail = geom3::middetail = 5; } else { sightrange = 7; vid.sspeed = 5; vid.mspeed = 5; vid.particles = false; vid.wallmode = 3; geom3::highdetail = geom3::middetail = -1; } } void showDemo() { gamescreen(2); getcstat = ' '; dialog::init(XLAT("HyperRogue %1: online demo", VER), 0xC00000, 200, 100); dialog::addBreak(50); dialog::addItem(XLAT("play"), 'f'); // dialog::addItem(XLAT("tutorial"), 'T'); dialog::addItem(XLAT("help"), 'h'); dialog::lastItem().keycaption += " / F1"; dialog::addItem(XLAT("toggle high detail"), 'a'); dialog::addBreak(100); dialog::addTitle("highlights", 0xC00000, 120); dialog::addItem(XLAT("Temple of Cthulhu"), 't'); dialog::addItem(XLAT("Land of Storms"), 'l'); dialog::addItem(XLAT("Burial Grounds"), 'b'); dialog::display(); } void handleDemoKey(int sym, int uni) { dialog::handleNavigation(sym, uni); if(sym == SDLK_F1 || sym == 'h') gotoHelp(help); else if(sym == 'a') { toggleanim(!demoanim); popScreen(); } else if(sym == 'f') { firstland = laIce; if(tactic::on) restartGame('t'); else restartGame(); popScreen(); } else if(sym == 'T') { firstland = laIce; if(!tour::on) tour::start(); popScreen(); } else if(sym == 't') { firstland = laTemple; if(!tactic::on) restartGame('t'); else restartGame(); popScreen(); } else if(sym == 'l') { firstland = laStorms; if(!tactic::on) restartGame('t'); else restartGame(); popScreen(); } else if(sym == 'b') { firstland = laBurial; if(!tactic::on) restartGame('t'); else restartGame(); items[itOrbSword] = 60; popScreen(); } } #endif function keyhandler; #ifndef MOBILE void quitOrAgain() { int y = vid.yres * (618) / 1000; displayButton(vid.xres/2, y + vid.fsize*1/2, (items[itOrbSafety] && havesave) ? XLAT("Press Enter or F10 to save") : XLAT("Press Enter or F10 to quit"), SDLK_RETURN, 8, 2); displayButton(vid.xres/2, y + vid.fsize*2, XLAT("or 'r' or F5 to restart"), 'r', 8, 2); displayButton(vid.xres/2, y + vid.fsize*7/2, XLAT("or 't' to see the top scores"), 't', 8, 2); displayButton(vid.xres/2, y + vid.fsize*10/2, XLAT("or 'v' to see the main menu"), 'v', 8, 2); displayButton(vid.xres/2, y + vid.fsize*13/2, XLAT("or 'o' to see the world overview"), 'o', 8, 2); } #endif int msgscroll = 0; string timeline() { int timespent = (int) (savetime + (timerstopped ? 0 : (time(NULL) - timerstart))); char buf[20]; sprintf(buf, "%d:%02d", timespent/60, timespent % 60); return shmup::on ? XLAT("%1 knives (%2)", its(turncount), buf) : XLAT("%1 turns (%2)", its(turncount), buf); } void showMission() { cmode2 = smMission; gamescreen(1); drawStats(); keyhandler = handleKeyQuit; dialog::init( #ifdef TOUR tour::on ? (canmove ? XLAT("Tutorial") : XLAT("GAME OVER")) : #endif cheater ? XLAT("It is a shame to cheat!") : showoff ? XLAT("Showoff mode") : canmove && princess::challenge ? XLAT("%1 Challenge", moPrincess) : canmove ? XLAT("Quest status") : XLAT("GAME OVER"), 0xC00000, 200, 100 ); dialog::addInfo(XLAT("Your score: %1", its(gold()))); dialog::addInfo(XLAT("Enemies killed: %1", its(tkills()))); #ifdef TOUR if(tour::on) ; else #endif if(items[itOrbYendor]) { dialog::addInfo(XLAT("Orbs of Yendor found: %1", its(items[itOrbYendor])), iinf[itOrbYendor].color); dialog::addInfo(XLAT("CONGRATULATIONS!"), iinf[itOrbYendor].color); } else { if(princess::challenge) dialog::addInfo(XLAT("Follow the Mouse and escape with %the1!", moPrincess)); else if(gold() < R30) dialog::addInfo(XLAT("Collect %1 $$$ to access more worlds", its(R30))); else if(gold() < R60) dialog::addInfo(XLAT("Collect %1 $$$ to access even more lands", its(R60))); else if(!hellUnlocked()) dialog::addInfo(XLAT("Collect at least %1 treasures in each of 9 types to access Hell", its(R10))); else if(items[itHell] < R10) dialog::addInfo(XLAT("Collect at least %1 Demon Daisies to find the Orbs of Yendor", its(R10))); else if(size(yendor::yi) == 0) dialog::addInfo(XLAT("Look for the Orbs of Yendor in Hell or in the Crossroads!")); else dialog::addInfo(XLAT("Unlock the Orb of Yendor!")); } if(!timerstopped && !canmove) { savetime += time(NULL) - timerstart; timerstopped = true; } if(canmove && !timerstart) timerstart = time(NULL); if(princess::challenge) ; #ifdef TOUR else if(tour::on) ; #endif else if(tkills() < R100) dialog::addInfo(XLAT("Defeat %1 enemies to access the Graveyard", its(R100))); else if(kills[moVizier] == 0 && (items[itFernFlower] < U5 || items[itGold] < U5)) dialog::addInfo(XLAT("Kill a Vizier in the Palace to access Emerald Mine")); else if(items[itEmerald] < U5) dialog::addInfo(XLAT("Collect 5 Emeralds to access Camelot")); else if(hellUnlocked() && !chaosmode) { bool b = true; for(int i=0; i=0) { msginfo m; m.spamtype = 0; m.flashout = true; m.stamp = ticks-128*vid.flashtime-128*(gls-i); m.msg = gamelog[i].msg; m.quantity = gamelog[i].quantity; mnum++, msgs.push_back(m); } dialog::addBreak(100); bool intour = false; #ifdef TOUR intour = tour::on; #endif if(intour) { #ifdef TOUR if(canmove) { dialog::addItem(XLAT("spherical geometry"), '1'); dialog::addItem(XLAT("Euclidean geometry"), '2'); dialog::addItem(XLAT("more curved hyperbolic geometry"), '3'); } if(!items[itOrbTeleport]) dialog::addItem(XLAT("teleport away"), '4'); else if(!items[itOrbAether]) dialog::addItem(XLAT("move through walls"), '4'); else dialog::addItem(XLAT("flash"), '4'); if(canmove) { if(tour::slidecommand != "") dialog::addItem(tour::slidecommand, '5'); dialog::addItem(XLAT("static mode"), '6'); dialog::addItem(XLAT("enable/disable texts"), '7'); dialog::addItem(XLAT("next slide"), SDLK_RETURN); dialog::addItem(XLAT("previous slide"), SDLK_BACKSPACE); dialog::addItem(XLAT("list of slides"), '9'); } else dialog::addBreak(200); dialog::addItem(XLAT("main menu"), 'v'); #endif } else { dialog::addItem(XLAT(canmove ? "continue" : "see how it ended"), SDLK_ESCAPE); dialog::addItem(XLAT("main menu"), 'v'); dialog::addItem(XLAT("restart"), SDLK_F5); #ifndef MOBILE dialog::addItem(XLAT(quitsaves() ? "save" : "quit"), SDLK_F10); #endif #ifdef ANDROIDSHARE dialog::addItem(XLAT("SHARE"), 's'-96); #endif } dialog::display(); if(mnum) displayfr(vid.xres/2, vid.yres-vid.fsize*(mnum+1), 2, vid.fsize/2, XLAT("last messages:"), 0xC0C0C0, 8); } void setAppropriateOverview() { clearMessages(); if(tactic::on) pushScreen(tactic::showMenu); else if(yendor::on) pushScreen(yendor::showMenu); else if(peace::on) pushScreen(peace::showMenu); else if(geometry != gNormal) pushScreen(showEuclideanMenu); else pushScreen(showOverview); } void showMissionScreen() { popScreenAll(); pushScreen(showMission); achievement_final(false); msgscroll = 0; }