From 94efef5d653e33ae6667f739c99fbaa17a263cb8 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Wed, 12 Jul 2017 18:03:53 +0200 Subject: [PATCH] further work for 10.0 --- basegraph.cpp | 2 +- changelog.txt | 31 ++++ classes.cpp | 8 +- complex.cpp | 2 + config.cpp | 17 ++- control.cpp | 86 ++--------- flags.cpp | 2 +- game.cpp | 112 +++++++++------ graph.cpp | 33 +++-- help.cpp | 113 +-------------- hud.cpp | 4 + hyper.h | 27 ++-- init.cpp | 9 +- kohonen.cpp | 2 +- mapeditor.cpp | 2 +- menus.cpp | 258 ++++----------------------------- rogueviz.cpp | 4 +- scores.cpp | 388 +++++++++++++++++++++++++++----------------------- system.cpp | 1 + yendor.cpp | 1 + 20 files changed, 441 insertions(+), 661 deletions(-) diff --git a/basegraph.cpp b/basegraph.cpp index 42c8d341..94e7f541 100644 --- a/basegraph.cpp +++ b/basegraph.cpp @@ -1003,7 +1003,7 @@ void setvideomode() { flags = SDL_OPENGL | SDL_HWSURFACE | SDL_GL_DOUBLEBUFFER; SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1); - if(vid.antialias && AA_MULTI) { + if(vid.antialias & AA_MULTI) { SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 16); glEnable(GL_MULTISAMPLE); diff --git a/changelog.txt b/changelog.txt index f4c56be3..fff29126 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1703,3 +1703,34 @@ - added a missing russian translation - [RogueViz] fixed legend in the svg/high quality output - more control for text in svg output + +2017.07.04 14:40 work in progress +- peaceful mode (work in progress) +- anti-aliased lines, and linewidth setting, option to make lines further from the model center narrower +- rearranged the menus +- '9' key to list all the frames in the current slideshow; better support for multiple slideshows compiled in +- configurable border and foreground color (mostly for presentations, not available in the menus) +- aura effect adjusts to the background color +- nicer text frames +- aura in the spherical geometry +- fixed the Hypersian Rug on some machines (using another OpenGL function), glew used on Linux +- unicode superscript d is now used in the expansion screen instead of "^d" +- some preparation for the Inventory Mode +- texts changed, some minor translation fixes +- fixed the default wsad keys +- [technical] improved the NOGL compilation flag to avoid OpenGL +- [technical] refactoring (gotoHelp, sdltogl) +- [technical] changed #ifdef LOCAL to #ifdef EXTRA_...; extra features are now included by starting the compilation from another file +- [technical] HYPERPATH added, for reaching the files when HyperRogue is called from a different location +- [technical] private source files moved to the "private" dir + +- antialiased multisampling +- major refactoring: return to previous menu +- image in the character selection screen +- ignore zero-score games +- do not save zero-score games +- consistency in menu +- multiple selectable columns in scores +- menu -> scores => list the current game if in game over +- yendor hardness fix +- hints shown on the quest status/quit screen diff --git a/classes.cpp b/classes.cpp index b865e9bc..bc34b292 100644 --- a/classes.cpp +++ b/classes.cpp @@ -736,7 +736,7 @@ enum eMonster { // shmup specials moPlayer, moBullet, moFlailBullet, moFireball, moTongue, moAirball, // temporary - moDeadBug, moLightningBolt, moDeadBird, moEnergySword, moWarning, + moDeadBug, moLightningBolt, moDeadBird, moEnergySword, moWarning, moRogueviz }; @@ -767,7 +767,7 @@ genderswitch_t genderswitch[NUM_GS] = { // --- items --- -const int ittypes = 111; +const int ittypes = 112; struct itemtype { char glyph; @@ -1153,6 +1153,7 @@ itemtype iinf[ittypes] = { "with this Orb." }, { '$', 0xC060C0, "Spinel", bulldashdesc }, { 'o', 0xC0C0FF, "Orb of the Mirror", NODESCYET }, + { 'O', 0xF0F0F0, "your orbs", NODESC}, }; enum eItem { itNone, itDiamond, itGold, itSpice, itRuby, itElixir, itShard, itBone, itHell, itStatue, @@ -1185,7 +1186,8 @@ enum eItem { itNone, itDiamond, itGold, itSpice, itRuby, itElixir, itShard, itBo itOrbSword, itKraken, itOrbSword2, itBarrow, itTrollEgg, itWarning, itOrbStone, itOrbNature, itTreat, itSlime, itAmethyst, itOrbRecall, itDodeca, itOrbDash, itGreenGrass, itOrbHorns, - itOrbBull, itBull, itOrbMirror + itOrbBull, itBull, itOrbMirror, + itInventory }; // --- wall types --- diff --git a/complex.cpp b/complex.cpp index c777d3ce..709572d7 100644 --- a/complex.cpp +++ b/complex.cpp @@ -589,6 +589,8 @@ namespace princess { achievement_gain("PRINCESS1"); princess::saved = true; princess::everSaved = true; + if(inv::on && !princess::reviveAt) + princess::reviveAt = gold(NO_LOVE); items[itSavedPrincess]++; } if(newdist == OUT_OF_PRISON && princess::challenge) { diff --git a/config.cpp b/config.cpp index c541dd2d..e7fec8ce 100644 --- a/config.cpp +++ b/config.cpp @@ -407,6 +407,8 @@ void showAllConfig() { dialog::addItem(XLAT("exit configuration"), 'v'); #ifndef NOCONFIG dialog::addItem(XLAT("save the current config"), 's'); + if(getcstat == 's') + mouseovers = XLAT("Config file: %1", conffile); #endif } @@ -448,6 +450,8 @@ void showGraphConfig() { #ifndef MOBWEB dialog::addSelItem(XLAT("framerate limit"), its(vid.framelimit), 'l'); + if(getcstat == 'l') + mouseovers = XLAT("Reduce the framerate limit to conserve CPU energy"); #endif #ifndef IOS @@ -455,6 +459,7 @@ void showGraphConfig() { #endif dialog::addSelItem(XLAT("scrolling speed"), fts(vid.sspeed), 'a'); + dialog::addSelItem(XLAT("movement animation speed"), fts(vid.mspeed), 'm'); dialog::addBoolItem(XLAT("extra graphical effects"), (vid.particles), 'u'); @@ -508,7 +513,9 @@ void showGraphConfig() { if(xuni == 'a') dialog::editNumber(vid.sspeed, -5, 5, 1, 0, XLAT("scrolling speed"), - XLAT("+5 = center instantly, -5 = do not center the map")); + 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, XLAT("movement animation speed"), @@ -613,6 +620,8 @@ void showBasicConfig() { dialog::addSelItem(XLAT("language"), XLAT("EN"), 'l'); #endif dialog::addSelItem(XLAT("player character"), numplayers() > 1 ? "" : csname(vid.cs), 'g'); + if(getcstat == 'g') + mouseovers = XLAT("Affects looks and grammar"); #ifndef NOAUDIO dialog::addSelItem(XLAT("background music volume"), its(musicvolume), 'b'); @@ -719,6 +728,12 @@ void showJoyConfig() { #ifndef MOBWEB dialog::addSelItem(XLAT("joystick mode"), XLAT(autojoy ? "automatic" : "manual"), 'p'); + if(getcstat == 'p') { + if(autojoy) + mouseovers = XLAT("joystick mode: automatic (release the joystick to move)"); + if(!autojoy) + mouseovers = XLAT("joystick mode: manual (press a button to move)"); + } dialog::addSelItem(XLAT("first joystick: movement threshold"), its(vid.joyvalue), 'a'); dialog::addSelItem(XLAT("first joystick: execute movement threshold"), its(vid.joyvalue2), 'b'); diff --git a/control.cpp b/control.cpp index eee79b9a..5b4b2819 100644 --- a/control.cpp +++ b/control.cpp @@ -10,7 +10,7 @@ bool gtouched; int getcstat, lgetcstat; ld getcshift; bool inslider; -int andmode = 0; +function keyhandler; // is the player using mouse? (used for auto-cross) bool mousing = true; @@ -32,12 +32,6 @@ int lastt; Uint8 *SDL_GetKeyState(void *v) { static Uint8 tab[1024]; return tab; } #endif -bool quitsaves() { return (items[itOrbSafety] && havesave); } - -bool needConfirmation() { - return canmove && (gold() >= 30 || tkills() >= 50) && !cheater && !quitsaves(); - } - bool mouseout() { if((getcstat != '-' && getcstat) || (lgetcstat && lgetcstat != '-')) return true; return outofmap(mouseh); @@ -210,52 +204,6 @@ bool doexiton(int sym, int uni) { return false; } -void handleKeyQuit(int sym, int uni) { - dialog::handleNavigation(sym, uni); - // ignore the camera movement keys - -#ifndef NORUG - if(rug::rugged && (sym == SDLK_UP || sym == SDLK_DOWN || sym == SDLK_PAGEUP || sym == SDLK_PAGEDOWN || - sym == SDLK_RIGHT || sym == SDLK_LEFT)) - sym = 0; -#endif - - if(sym == SDLK_RETURN || sym == SDLK_KP_ENTER || sym == SDLK_F10) quitmainloop = true; - else if(uni == 'r' || sym == SDLK_F5) { - restartGame(), popScreen(); - msgs.clear(); - } - else if(sym == SDLK_UP || sym == SDLK_KP8 || sym == PSEUDOKEY_WHEELUP) msgscroll++; - else if(sym == SDLK_DOWN || sym == SDLK_KP2 || sym == PSEUDOKEY_WHEELDOWN) msgscroll--; - else if(sym == SDLK_PAGEUP || sym == SDLK_KP9) msgscroll+=5; - else if(sym == SDLK_PAGEDOWN || sym == SDLK_KP3) msgscroll-=5; - else if(uni == 'v') popScreenAll(), pushScreen(showMainMenu); - else if(sym == SDLK_F3 || (sym == ' ' || sym == SDLK_HOME)) - fullcenter(); - else if(uni == 'o' && DEFAULTNOR(sym)) setAppropriateOverview(); -#ifdef INV - else if(uni == 'i' && DEFAULTNOR(sym) && inv::on) - pushScreen(inv::show); -#endif -#ifndef NOSAVE - else if(uni == 't') { - if(!canmove) restartGame(); - loadScores(); - msgs.clear(); - } - #endif - - else if(doexiton(sym, uni) && !didsomething) { - popScreen(); - msgscroll = 0; - msgs.clear(); - if(!canmove) { - addMessage(XLAT("GAME OVER")); - addMessage(timeline()); - } - } - } - bool didsomething; #ifdef MOBILE @@ -396,24 +344,6 @@ void handleKeyNormal(int sym, int uni) { else quitmainloop = true; } - if(!canmove) { - if(sym == SDLK_RETURN || sym == SDLK_KP_ENTER) quitmainloop = true; - else if(uni == 'r') restartGame(); -#ifndef NOSAVE - else if(uni == 't') { - restartGame(); - loadScores(); - } -#endif -#ifndef NORUG - else if(rug::rugged) ; -#endif - else if(sym == SDLK_UP || sym == SDLK_KP8) msgscroll++; - else if(sym == SDLK_DOWN || sym == SDLK_KP2) msgscroll--; - else if(sym == SDLK_PAGEUP || sym == SDLK_KP9) msgscroll+=5; - else if(sym == SDLK_PAGEDOWN || sym == SDLK_KP3) msgscroll-=5; - } - if(uni == 'o' && DEFAULTNOR(sym)) setAppropriateOverview(); #ifdef INV if(uni == 'i' && DEFAULTNOR(sym) && inv::on) @@ -776,3 +706,17 @@ void displayabutton(int px, int py, string s, int col) { } #endif +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--; + } + } + diff --git a/flags.cpp b/flags.cpp index 5a6a2f72..0885e630 100644 --- a/flags.cpp +++ b/flags.cpp @@ -267,7 +267,7 @@ int itemclass(eItem i) { if(i == itSavedPrincess || i == itStrongWind || i == itWarning) return IC_NAI; if(i == itKey || i == itOrbYendor || i == itGreenStone || i == itHolyGrail || i == itCompass || - isElementalShard(i) || i == itRevolver) + isElementalShard(i) || i == itRevolver || i == itInventory) return IC_OTHER; return IC_ORB; } diff --git a/game.cpp b/game.cpp index 8f96e5ff..b7a6bf67 100644 --- a/game.cpp +++ b/game.cpp @@ -189,15 +189,6 @@ bool itemHiddenFromSight(cell *c) { && !(shmup::on && shmup::boatAt(c)); } -int puregold() { - int i = items[itOrbYendor] * 50 + items[itHolyGrail] * 10; - if(items[itOrbLove]) i += 30; - for(int t=0; tprincess = NULL; if(i->bestdist == OUT_OF_PALACE) { items[itSavedPrincess]--; - if(items[itSavedPrincess] == 0) { + if(items[itSavedPrincess] == 0 && !inv::on) { items[itOrbLove] = 0; - princess::reviveAt = gold() + 20; + princess::reviveAt = gold(NO_LOVE) + 20; } } if(princess::challenge) showMissionScreen(); @@ -2154,13 +2161,13 @@ bool attackMonster(cell *c, flagtype flags, eMonster killer) { addMessage(XLAT("That was easy, but groups could be dangerous.")); } - if(tk < 10 && ntk >= 10 && !tactic::on && !euclid && !sphere) + if(tk < 10 && ntk >= 10 && !tactic::on && !euclid && !sphere && !inv::on) addMessage(XLAT("Good to know that your fighting skills serve you well in this strange world.")); - if(tk < 50 && ntk >= 50 && !euclid && !sphere) + if(tk < R100/2 && ntk >= R100/2 && !euclid && !sphere) addMessage(XLAT("You wonder where all these monsters go, after their death...")); - if(tk < 100 && ntk >= 100 && !euclid && !sphere) + if(tk < R100 && ntk >= R100 && !euclid && !sphere) addMessage(XLAT("You feel that the souls of slain enemies pull you to the Graveyard...")); if(!tu && trollUnlocked()) { @@ -5429,6 +5436,10 @@ void checkmove() { for(int i=0; iland)); addMessage(XLAT("With each %1 you collect...", which, c2->land)); } - else if(items[which] == 9 && maxgold() == 9 && !specialmode) - addMessage(XLAT("Are there any magical orbs in %the1?...", c2->land)); - else if(items[which] == 10 && maxgold() == 10 && !specialmode) { + else if(items[which] == 9 && maxgold() == 9 && !specialmode) { + if(inv::on) { + addMessage(XLAT("The treasure gives your magical powers!", c2->land)); + if(!ISMOBILE) + addMessage(XLAT("Press 'i' to access your magical powers.", c2->land)); + } + else + addMessage(XLAT("Are there any magical orbs in %the1?...", c2->land)); + } + else if(items[which] == R10 && maxgold() == R10 && !specialmode && !inv::on) { addMessage(XLAT("You feel that %the1 slowly become%s1 dangerous...", c2->land)); addMessage(XLAT("Better find some other place.")); } - else if(which == itSpice && items[itSpice] == 7 && !specialmode) + else if(which == itSpice && items[itSpice] == U10*7/10 && !specialmode) addMessage(XLAT("You have a vision of the future, fighting demons in Hell...")); - else if(which == itSpice && items[itSpice] == 9 && !specialmode) + else if(which == itSpice && items[itSpice] == U10-1 && !specialmode) addMessage(XLAT("You will be fighting red rock snakes, too...")); - else if(which == itKraken && items[itKraken] == 9 && !specialmode) + else if(which == itKraken && items[itKraken] == U10-1 && !specialmode) addMessage(XLAT("You feel that a magical weapon is waiting for you...")); // else if(which == itFeather && items[itFeather] == 10) // addMessage(XLAT("There should be a Palace somewhere nearby...")); - else if(which == itElixir && items[itElixir] == 4 && !specialmode) + else if(which == itElixir && items[itElixir] == U5-1 && !specialmode) addMessage(XLAT("With this Elixir, your life should be long and prosperous...")); - else if(which == itRuby && items[itRuby] == 4 && !specialmode) { + else if(which == itRuby && items[itRuby] == U5-1 && !specialmode) { addMessage(XLAT("You feel something strange about gravity here...")); } - else if(which == itPalace && items[itPalace] == 4 && !specialmode) { + else if(which == itPalace && items[itPalace] == U5-1 && !specialmode) { addMessage(XLAT("The rug depicts a man in a deep dungeon, unable to leave.")); } - else if(which == itIvory && items[itIvory] == 4 && !specialmode) { + else if(which == itIvory && items[itIvory] == U5-1 && !specialmode) { addMessage(XLAT("You feel attuned to gravity, ready to face mountains and dungeons.")); } - else if(which == itBone && items[itBone] == 6 && !specialmode) + else if(which == itBone && items[itBone] == U5+1 && !specialmode) addMessage(XLAT("The Necromancer's Totem contains hellish incantations...")); - else if(which == itStatue && items[itStatue] == 6 && !specialmode) + else if(which == itStatue && items[itStatue] == U5+1 && !specialmode) addMessage(XLAT("The inscriptions on the Statue of Cthulhu point you toward your destiny...")); - else if(which == itStatue && items[itStatue] == 4 && !specialmode) + else if(which == itStatue && items[itStatue] == U5-1 && !specialmode) addMessage(XLAT("There must be some temples of Cthulhu in R'Lyeh...")); - else if(which == itDiamond && items[itDiamond] == 8 && !specialmode) + else if(which == itDiamond && items[itDiamond] == U10-2 && !specialmode) addMessage(XLAT("Still, even greater treasures lie ahead...")); - else if(which == itFernFlower && items[itFernFlower] == 4 && !specialmode) + else if(which == itFernFlower && items[itFernFlower] == U5-1 && !specialmode) addMessage(XLAT("You overheard Hedgehog Warriors talking about emeralds...")); - else if(which == itEmerald && items[itEmerald] == 4 && !specialmode && !chaosmode) + else if(which == itEmerald && items[itEmerald] == U5-1 && !specialmode && !chaosmode) addMessage(XLAT("You overhear miners talking about a castle...")); - else if(which == itEmerald && items[itEmerald] == 5 && !specialmode && !chaosmode) + else if(which == itEmerald && items[itEmerald] == U5 && !specialmode && !chaosmode) addMessage(XLAT("A castle in the Crossroads...")); else if(which == itShard) ; else { @@ -5983,21 +6001,23 @@ bool collectItem(cell *c2, bool telekinesis) { } #ifdef MOBILE - if(pg < lastsafety + 45 && g2 >= lastsafety + 45) + if(pg < lastsafety + R30*3/2 && g2 >= lastsafety + R30*3/2) addMessage(XLAT("The Orb of Safety from the Land of Eternal Motion might save you.")); #endif - if(pg < 15 && g2 >= 15) +#define IF(x) if(pg < (x) && g2 >= x) + + IF(R60/4) addMessage(XLAT("Collect treasure to access more different lands...")); - if(pg < 30 && g2 >= 30) + IF(R30) addMessage(XLAT("You feel that you have enough treasure to access new lands!")); - if(pg < 45 && g2 >= 45) + IF(R30*3/2) addMessage(XLAT("Collect more treasures, there are still more lands waiting...")); - if(pg < 60 && g2 >= 60) + IF(R60) addMessage(XLAT("You feel that the stars are right, and you can access R'Lyeh!")); - if(pg < 75 && g2 >= 75) + IF(R30*5/2) addMessage(XLAT("Kill monsters and collect treasures, and you may get access to Hell...")); - if(pg < 90 && g2 >= 90) + IF(R10 * 9) addMessage(XLAT("To access Hell, collect %1 treasures each of 9 kinds...", its(R10))); if(hellUnlocked() && !lhu) { addMessage(XLAT("Abandon all hope, the gates of Hell are opened!")); @@ -6021,7 +6041,7 @@ bool collectItem(cell *c2, bool telekinesis) { numOrb++; if(numOrb) achievement_count("ORB", numOrb, 0); - if(princess::reviveAt && gold() >= princess::reviveAt) { + if(princess::reviveAt && gold(NO_LOVE) >= princess::reviveAt && !inv::on) { princess::reviveAt = 0, items[itSavedPrincess] = 1; addMessage("You have enough treasure now to revive the Princess!"); @@ -6095,8 +6115,12 @@ void roundTableMessage(cell *c2) { } long long circlesize[100], disksize[100]; +ld circlesizeD[10000]; +int lastsize; void computeSizes() { + lastsize = purehepta ? 44 : 76; + circlesize[0] = 1; if(!purehepta) { @@ -6168,12 +6192,12 @@ void knightFlavorMessage(cell *c2) { addMessage(XLAT("\"Train in the Desert first!\"")); } else if(msgid == 8) { - if(rad <= 76) + if(rad <= lastsize) addMessage(XLAT("\"Our Table seats %1 Knights!\"", llts(circlesize[rad]))); else addMessage(XLAT("\"By now, you should have your own formula, you know?\"")); } - else if(msgid == 9 && rad <= 76) { + else if(msgid == 9 && rad <= lastsize) { addMessage(XLAT("\"There are %1 floor tiles inside our Table!\"", llts(disksize[rad]))); } else if(msgid == 10 && !items[itPirate] && !items[itWhirlpool]) { diff --git a/graph.cpp b/graph.cpp index f1753f39..8359f6ed 100644 --- a/graph.cpp +++ b/graph.cpp @@ -602,7 +602,7 @@ bool drawItemType(eItem it, cell *c, const transmatrix& V, int icol, int ticks, queuepolyat(V * spin(ticks / 1500. + M_PI/(ct6+6)), *xsh, darkena(0x202020, 0, hidden ? 0x40 : 0xF0), PPR_ITEMb); } - else if(xch == 'o') { + else if(xch == 'o' || it == itInventory) { if(it == itOrbFire) icol = firecolor(100); queuepoly(V, shDisk, darkena(icol, 0, hidden ? 0x20 : 0xC0)); if(it == itOrbFire) icol = firecolor(200); @@ -4330,13 +4330,7 @@ void drawthemap() { mapeditor::ewsearch.dist = 1e30; modist = 1e20; mouseover = NULL; modist2 = 1e20; mouseover2 = NULL; - mouseovers = XLAT("Press F1 or right click for help"); -#ifdef ROGUEVIZ - if(rogueviz::on) mouseovers = " "; -#endif -#ifdef TOUR - if(tour::on) mouseovers = tour::tourhelp; -#endif + centdist = 1e20; if(!torus) centerover = NULL; @@ -4643,6 +4637,16 @@ void gamescreen(int _darken) { void normalscreen() { help = "@"; + +#ifdef ROGUEVIZ + if(!rogueviz::on) +#endif + mouseovers = XLAT("Press F1 or right click for help"); + +#ifdef TOUR + if(tour::on) mouseovers = tour::tourhelp; +#endif + if(!outofmap(mouseh)) getcstat = '-'; cmode2 = smNormal; gamescreen(hiliteclick && mmmon ? 1 : 0); drawStats(); @@ -4655,6 +4659,8 @@ void normalscreen() { #endif displayButton(vid.xres-8, vid.yres-vid.fsize, XLAT("(v) menu"), 'v', 16); keyhandler = handleKeyNormal; + + describeMouseover(); } vector< function > screens = { normalscreen }; @@ -4689,14 +4695,21 @@ void drawscreen() { lgetcstat = getcstat; getcstat = 0; inslider = false; + mouseovers = " "; + cmode2 = smMenu; keyhandler = [] (int sym, int uni) { return false; }; screens.back()(); + int col = linf[cwt.c->land].color; + if(cwt.c->land == laRedRock) col = 0xC00000; + +#ifndef MOBILE + displayfr(vid.xres/2, vid.fsize, 2, vid.fsize, mouseovers, col, 8); +#endif + drawmessages(); - describeMouseover(); - if((havewhat&HF_BUG) && darken == 0 && cmode2 == smNormal) for(int k=0; k<3; k++) displayfr(vid.xres/2 + vid.fsize * 5 * (k-1), vid.fsize*2, 2, vid.fsize, its(hive::bugcount[k]), minf[moBug0+k].color, 8); diff --git a/help.cpp b/help.cpp index 82484861..c096b1f5 100644 --- a/help.cpp +++ b/help.cpp @@ -60,7 +60,9 @@ string buildHelpText() { h += XLAT( "You can right click any element to get more information about it.\n\n" ); +#ifdef MAC h += XLAT("(You can also use right Shift)\n\n"); +#endif #endif h += XLAT("See more on the website: ") + "http//roguetemple.com/z/hyper/\n\n"; @@ -158,7 +160,7 @@ string generateHelpForItem(eItem it) { help += XLAT(iinf[it].help); - if(it == itSavedPrincess || it == itOrbLove) + if(it == itSavedPrincess || it == itOrbLove) if(!inv::on) help += princessReviveHelp(); if(it == itTrollEgg) @@ -530,16 +532,12 @@ void describeMouseover() { DEBB(DF_GRAPH, (debugfile,"describeMouseover\n")); cell *c = mousing ? mouseover : playermoved ? NULL : centerover; - string out = mouseovers; - if(!c || instat || getcstat) { } + string& out = mouseovers; + if(!c || instat || getcstat != '-') { } else if(c->wall != waInvisibleFloor) { out = XLAT1(linf[c->land].name); help = generateHelpForLand(c->land); - // Celsius - - // if(c->land == laIce) out = "Icy Lands (" + fts(60 * (c->heat - .4)) + " C)"; - if(c->land == laIce || c->land == laCocytus) out += " (" + fts(heat::celsius(c)) + " °C)"; if(c->land == laDryForest && c->landparam) @@ -562,29 +560,10 @@ void describeMouseover() { if(c->land == laTortoise && tortoise::seek()) out += " " + tortoise::measure(getBits(c)); - /* if(c->land == laGraveyard || c->land == laHauntedBorder || c->land == laHaunted) - out += " (" + its(c->landparam)+")"; */ - if(buggyGeneration) { char buf[20]; sprintf(buf, " H=%d M=%d", c->landparam, c->mpdist); out += buf; } -// if(c->land == laBarrier) -// out += "(" + string(linf[c->barleft].name) + " / " + string(linf[c->barright].name) + ")"; - - // out += "(" + its(c->bardir) + ":" + string(linf[c->barleft].name) + " / " + string(linf[c->barright].name) + ")"; - - // out += " MD"+its(c->mpdist); - - // out += " WP:" + its(c->wparam); - // out += " rose:" + its(rosemap[c]/4) + "." + its(rosemap[c]%4); - // out += " MP:" + its(c->mpdist); - // out += " cda:" + its(celldistAlt(c)); - - /* out += " DP=" + its(celldistance(c, cwt.c)); - out += " DO=" + its(celldist(c)); - out += " PD=" + its(c->pathdist); */ - if(false) { out += " LP:" + itsh(c->landparam)+"/"+its(turncount); @@ -594,33 +573,17 @@ void describeMouseover() { out += " D:" + its(c->mpdist); char zz[64]; sprintf(zz, " P%p", c); out += zz; - // out += " rv" + its(rosedist(c)); - // if(rosemap.count(c)) - // out += " rv " + its(rosemap[c]/8) + "." + its(rosemap[c]%8); - // out += " ai" + its(c->aitmp); + if(euclid) { for(int i=0; i<4; i++) out += " " + its(getEuclidCdata(c->master)->val[i]); out += " " + itsh(getBits(c)); } else { for(int i=0; i<4; i++) out += " " + its(getHeptagonCdata(c->master)->val[i]); - // out += " " + itsh(getHeptagonCdata(c->master)->bits); out += " " + fts(tortoise::getScent(getBits(c))); } - // itsh(getHeptagonCdata(c->master)->bits); - // out += " barleft: " + s0 + dnameof(c->barleft); - // out += " barright: " + s0 + dnameof(c->barright); } - // char zz[64]; sprintf(zz, " P%p", c); out += zz; - - /* whirlwind::calcdirs(c); - for(int i=0; iland); @@ -635,26 +598,6 @@ void describeMouseover() { } } - // char zz[64]; sprintf(zz, " P%d", princess::dist(c)); out += zz; - // out += " MD"+its(c->mpdist); - // out += " H "+its(c->heat); - // if(c->type != 6) out += " Z"+its(c->master->zebraval); - // out += " H"+its(c->heat); - -/* // Hive debug - if(c->land == laHive) { - out += " [" + its(c->tmp) + " H" + its(int(c->heat)); - if(c->tmp >= 0 && c->tmp < size(buginfo) && buginfo[c->tmp].where == c) { - buginfo_t b(buginfo[c->tmp]); - for(int k=0; k<3; k++) out += ":" + its(b.dist[k]); - for(int k=0; k<3; k++) - for(int i=0; itmp) - out += " B"+its(k)+":"+its(i); - } - out += "]"; - } */ - if(c->wall && !((c->wall == waFloorA || c->wall == waFloorB || c->wall == waFloorC || c->wall == waFloorD) && c->item)) { out += ", "; out += XLAT1(winf[c->wall].name); @@ -721,55 +664,11 @@ void describeMouseover() { if(isWarped(c)) help += s0 + "\n\n" + warpdesc; } -/* - else if(cmode == emGraphConfig) { - if(getcstat == 'a' && vid.sspeed > -4.99) - out = XLAT("+5 = center instantly, -5 = do not center the map"); - else if(getcstat == 'a') - out = XLAT("press Space or Home to center on the PC"); - else if(getcstat == 'w') - out = XLAT("also hold Alt during the game to toggle high contrast"); - else if(getcstat == 'f') - out = XLAT("Reduce the framerate limit to conserve CPU energy"); - } - else if(cmode == emBasicConfig) { - if(getcstat == 'c') - out = XLAT("The axes help with keyboard movement"); - else if(getcstat == 'g') - out = XLAT("Affects looks and grammar"); -#ifndef MOBILE - else if(getcstat == 's') - out = XLAT("Config file: %1", conffile); -#endif - else out = ""; - } - else if(cmode == emDisplayMode) { - if(getcstat == 'p') { - if(autojoy) - out = XLAT("joystick mode: automatic (release the joystick to move)"); - if(!autojoy) - out = XLAT("joystick mode: manual (press a button to move)"); - } - } - else if(cmode == emChangeMode) { - if(getcstat == 'h') - out = XLAT("One wrong move and it is game over!"); - } -*/ - mouseovers = out; - #ifdef ROGUEVIZ rogueviz::describe(c); #endif - int col = linf[cwt.c->land].color; - if(cwt.c->land == laRedRock) col = 0xC00000; - -#ifndef MOBILE - displayfr(vid.xres/2, vid.fsize, 2, vid.fsize, out, col, 8); -#endif - if(mousey < vid.fsize * 3/2) getcstat = SDLK_F1; } diff --git a/hud.cpp b/hud.cpp index 833906f3..a8c61607 100644 --- a/hud.cpp +++ b/hud.cpp @@ -231,6 +231,10 @@ void displayglyph2(int cx, int cy, int buttonsize, int i) { mouseovers += XLAT(" (click to drop)"); getcstat = 'g'; } + if(it == itInventory) { + mouseovers += XLAT(" (click to use)"); + getcstat = 'i'; + } if(imp & GLYPH_LOCAL) mouseovers += XLAT(" (local treasure)"); help = generateHelpForItem(it); } diff --git a/hyper.h b/hyper.h index 742032e1..9d056ec5 100644 --- a/hyper.h +++ b/hyper.h @@ -559,7 +559,12 @@ bool isFriendly(eMonster m); bool isFriendly(cell *c); bool isChild(cell *w, cell *killed); // is w killed if killed is killed? -int gold(); +static const int NO_TREASURE = 1; +static const int NO_YENDOR = 2; +static const int NO_GRAIL = 4; +static const int NO_LOVE = 8; + +int gold(int no = 0); int tkills(); bool hellUnlocked(); @@ -1037,10 +1042,6 @@ void checkmove(); transmatrix eumove(int x, int y); transmatrix eumovedir(int d); -#ifndef NOSAVE -void loadScores(); -#endif - int reptilemax(); extern bool mousing; @@ -1289,7 +1290,9 @@ eLand getNewSealand(eLand old); bool createOnSea(eLand old); namespace inv { - bool on; + extern bool on; + extern int remaining[ittypes]; + void compute(); } bool drawItemType(eItem it, cell *c, const transmatrix& V, int icol, int ticks, bool hidden); @@ -1315,7 +1318,7 @@ template int addHook(hookset*& m, int prio, const U& hook) return 0; } -extern purehookset hooks_frame, hooks_stats, clearmemory; +extern purehookset hooks_frame, hooks_stats, clearmemory, hooks_config; template void callhooks(hookset *h, U... args) { if(h) for(auto& p: *h) p.second(args...); @@ -1429,10 +1432,10 @@ void switchGL(); void switchFullscreen(); extern screenmode cmode2; +namespace scores { void load(); } + void gotoHelp(const string& h); void showCustomizeChar(); -void showScores(); -void showPickScores(); void showCheatMenu(); void showDisplayMode(); void showChangeMode(); @@ -1445,3 +1448,9 @@ void gamescreen(int darken); void showMission(); void handleKeyQuit(int sym, int uni); void handlePanning(int sym, int uni); + +#ifdef MOBILE +namespace leader { void showMenu(); void handleKey(int sym, int uni); } +#endif + +bool needConfirmation(); diff --git a/init.cpp b/init.cpp index 5402e750..f15073ff 100644 --- a/init.cpp +++ b/init.cpp @@ -1,6 +1,6 @@ -#define VER "9.4n2" -#define VERNUM 9416 -#define VERNUM_HEX 0x9416 +#define VER "9.4n3" +#define VERNUM 9417 +#define VERNUM_HEX 0x9417 #define GEN_M 0 #define GEN_F 1 @@ -264,7 +264,7 @@ const char *loadlevel = NULL; #include "landgen.cpp" #include "orbs.cpp" #ifdef INV -#include "inventory.cpp" +#include "closed/inventory.cpp" #endif #include "system.cpp" #include "geometry.cpp" @@ -281,6 +281,7 @@ const char *loadlevel = NULL; #include "config.cpp" #include "scores.cpp" #include "menus.cpp" +#include "quit.cpp" #ifdef FIXEDSIZE #include "nofont.cpp" #endif diff --git a/kohonen.cpp b/kohonen.cpp index c7bbce43..18cd38b5 100644 --- a/kohonen.cpp +++ b/kohonen.cpp @@ -361,7 +361,7 @@ void run(const char *fname, int _perdist, double _maxfac) { } void describe(cell *c) { - if(cmode == emHelp) return; + if(cmode2 == smHelp) return; neuron *n = getNeuronSlow(c); if(!n) return; help += "cell number: " + its(n - &net[0]) + "\n"; diff --git a/mapeditor.cpp b/mapeditor.cpp index fe013a76..42a05191 100644 --- a/mapeditor.cpp +++ b/mapeditor.cpp @@ -1721,7 +1721,7 @@ namespace mapeditor { if(mapeditor::painttype == 4) mapeditor::painttype = 0, mapeditor::paintwhat = 0, mapeditor::paintwhat_str = "clear monster"; - mapeditor::copywhat = NULL; + mapeditor::copywhat = NULL; mapeditor::undo.clear(); if(!cheater) mapeditor::displaycodes = 0; if(!cheater) mapeditor::whichShape = 0; diff --git a/menus.cpp b/menus.cpp index 5ae71637..d84de360 100644 --- a/menus.cpp +++ b/menus.cpp @@ -3,6 +3,8 @@ #include "dialogs.cpp" +// -- overview -- + #define BLACKISH 0x404040 #define REDDISH 0x400000 @@ -159,6 +161,8 @@ void showOverview() { }; } +// -- main menu -- + bool checkHalloweenDate() { time_t t = time(NULL); struct tm tm = *localtime(&t); @@ -241,7 +245,7 @@ void showMainMenu() { else if(sym == 'd') pushScreen(showDisplayMode); else if(sym == 'm') pushScreen(showChangeMode); #ifndef NOSAVE - else if(sym == 't') loadScores(); + else if(sym == 't') scores::load(); #endif else if(uni == 'y'-96) { if(!sphere) { @@ -271,7 +275,7 @@ void showMainMenu() { #ifdef INV else if(sym == 'i') { clearMessages(); - pushScreen(inv::show()); + pushScreen(inv::show); } #endif else if(sym == SDLK_ESCAPE) @@ -294,6 +298,8 @@ void showMainMenu() { }; } +// -- display modes -- + void showDisplayMode() { gamescreen(3); @@ -308,6 +314,8 @@ void showDisplayMode() { 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'); + if(getcstat == '5') + mouseovers = XLAT("also hold Alt during the game to toggle high contrast"); dialog::addBoolItem(XLAT("draw the grid"), (vid.grid), '6'); dialog::addBoolItem(XLAT("mark heptagons"), (vid.darkhepta), '7'); dialog::addSelItem(XLAT("3D configuration"), "", '9'); @@ -383,19 +391,7 @@ void showDisplayMode() { }; } -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--; - } - } +// -- game modes -- void switchHardcore() { if(hardcore && !canmove) { @@ -426,16 +422,18 @@ void showChangeMode() { 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'); + if(getcstat == 'h') + mouseovers = XLAT("One wrong move and it is game over!"); 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("peaceful mode"), (chaosmode), 'p'); dialog::addBoolItem(XLAT("inventory mode"), (inv::on), 'i'); + dialog::addBoolItem(XLAT("pure tactics mode"), (tactic::on), 't'); + dialog::addBoolItem(XLAT("Yendor Challenge"), (yendor::on), 'y'); + dialog::addBoolItem(XLAT("%1 Challenge", moPrincess), (princess::challenge), 'P'); + dialog::addBoolItem(XLAT("random pattern mode"), (randomPatternsMode), 'r'); dialog::addBreak(50); // cheating and map editor @@ -489,7 +487,7 @@ void showChangeMode() { } else if(xuni == '7') restartGame('7'); - else if(xuni == 'P') + else if(xuni == 'p') pushScreen(peace::showMenu); else if(xuni == 'i') { restartGame('i'); @@ -512,7 +510,7 @@ void showChangeMode() { if(!princess::everSaved) addMessage(XLAT("Save %the1 first to unlock this challenge!", moPrincess)); else - restartGame('p'); + restartGame('P'); } #ifndef NOEDIT else if(xuni == 'm') { @@ -545,6 +543,8 @@ void showChangeMode() { }; } +// -- cheat menu -- + void showCheatMenu() { gamescreen(1); dialog::init("cheat menu"); @@ -592,6 +592,8 @@ void showCheatMenu() { }; } +// -- geometry menu -- + int eupage = 0; int euperpage = 21; @@ -698,27 +700,7 @@ void showEuclideanMenu() { }; } -#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 - - } +// -- demo -- #ifdef DEMO bool demoanim; @@ -804,188 +786,8 @@ void handleDemoKey(int sym, int uni) { } } #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); - } + +// -- overview -- void setAppropriateOverview() { clearMessages(); @@ -1001,9 +803,3 @@ void setAppropriateOverview() { pushScreen(showOverview); } -void showMissionScreen() { - popScreenAll(); - pushScreen(showMission); - achievement_final(false); - msgscroll = 0; - } diff --git a/rogueviz.cpp b/rogueviz.cpp index 04667c6b..ccb75c89 100644 --- a/rogueviz.cpp +++ b/rogueviz.cpp @@ -1987,8 +1987,8 @@ slide rvslides[] = { auto hooks = addHook(hooks_frame, 0, drawExtra) + addHook(hooks_args, 100, readArgs) + - addHook(clearmemory, 0, clear) + - addHook(hooks_config, 0, [] () { ss::list(rogueviz::rvtour::rvslides); }); + addHook(clearmemory, 0, close) + + addHook(hooks_config, 0, [] () { tour::ss::list(rogueviz::rvtour::rvslides); }); }; diff --git a/scores.cpp b/scores.cpp index f28ad8cb..88fba3c3 100644 --- a/scores.cpp +++ b/scores.cpp @@ -1,5 +1,9 @@ #ifndef NOSAVE + +namespace scores { + vector scores; +score *currentgame; int scoresort = 2; int scoredisplay = 1; @@ -15,14 +19,37 @@ bool fakescore() { return fakebox[scoredisplay]; } -string displayfor(score* S) { +int colwidth() { + if(scoredisplay == 0) return 5; + if(scoredisplay == 1) return 16; + if(scoredisplay == 5) return 8; + return 4; + } + +string displayfor(score* S, bool shorten = false) { // printf("S=%p, scoredisplay = %d\n", S, scoredisplay); if(S == NULL) { - return XLATN(boxname[scoredisplay]); + string str = XLATN(boxname[scoredisplay]); + if(!shorten) return str; + if(scoredisplay == 0 || scoredisplay == 65) return XLAT("time"); + if(scoredisplay == 2) return "$$$"; + if(scoredisplay == 3) return XLAT("kills"); + if(scoredisplay == 4) return XLAT("turns"); + if(scoredisplay == 5) return XLAT("cells"); + if(scoredisplay == 67) return XLAT("cheats"); + if(scoredisplay == 66) return XLAT("saves"); + if(scoredisplay == 197) return XLAT("players"); + int i = 0; + for(int j=0; j<5; j++) if(i < size(str)) getnext(str.c_str(), i); + return str.substr(0, i); } - if(scoredisplay == 0) { - char buf[10]; - snprintf(buf, 10, "%d:%02d", S->box[0]/60, S->box[0]%60); + if(scoredisplay == 0 || scoredisplay == 65) { + char buf[20]; + int t = S->box[0]; + if(t >= 3600) + snprintf(buf, 20, "%d:%02d:%02d", t/3600, (t/60)%60, t%60); + else + snprintf(buf, 20, "%d:%02d", t/60, t%60); return buf; } if(scoredisplay == 1) { @@ -33,58 +60,6 @@ string displayfor(score* S) { return its(S->box[scoredisplay]); } -void loadScores() { - scores.clear(); - FILE *f = fopen(scorefile, "rt"); - if(!f) { - printf("Could not open the score file '%s'!\n", scorefile); - addMessage(s0 + "Could not open the score file: " + scorefile); - return; - } - while(!feof(f)) { - char buf[120]; - if(fgets(buf, 120, f) == NULL) break; - if(buf[0] == 'H' && buf[1] == 'y') { - score sc; bool ok = true; - {if(fscanf(f, "%s", buf) <= 0) break;} sc.ver = buf; - - for(int i=0; i= "4.4") { - sc.box[0] = sc.box[65]; - // the first executable on Steam included a corruption - if(sc.box[65] > 1420000000 && sc.box[65] < 1430000000) { - sc.box[0] = sc.box[65] - sc.box[1]; - sc.box[65] = sc.box[0]; - } - // do not include saves - if(sc.box[65 + 4 + itOrbSafety - itOrbLightning]) ok = false; - } - else - sc.box[0] = sc.box[1] - sc.box[0]; // could not save then - if(ok && boxid > 20) scores.push_back(sc); - } - } - fclose(f); - addMessage(its(size(scores))+" games have been recorded in "+scorefile); - pushScreen(showScores); - boxid = 0; applyBoxes(); - scoresort = 2; reverse(scores.begin(), scores.end()); - scoremode = 0; - if(shmup::on) scoremode = 1; - else if(hardcore) scoremode = 2; - scorefrom = 0; - stable_sort(scores.begin(), scores.end(), scorecompare); - #ifdef MOBILE - extern int andmode; - andmode = 2; - #endif - } - vector > pickscore_options; void sortScores() { @@ -101,28 +76,84 @@ void shiftScoreDisplay(int delta) { if(fakescore()) shiftScoreDisplay(delta); } -void showScores() { - int y = vid.fsize * 7/2; - int bx = vid.fsize; - getcstat = 1; +int curcol; + +vector columns; + +bool monsterpage = false; + +void showPickScores() { + + int d = scoredisplay = columns[curcol]; - string modes = - scoremode == 0 ? XLAT(", m - mode: normal") : - scoremode == 1 ? XLAT(", m - mode: shoot'em up") : - scoremode == 2 ? XLAT(", m - mode: hardcore only") : - "?"; + pickscore_options.clear(); - if(euclid) modes += XLAT(" (E:%1)", euclidland); + scorerev = false; + for(int i=0; i= '1' && uni <= '9') uni = uni + 1000 - '1'; + else if(uni >= 1000 && uni < 1000 + size(pickscore_options)) { + scoredisplay = pickscore_options[uni - 1000].second; + for(int i=0; i vid.xres) break; + if(displaystr(bx*at, vid.fsize, 0, vid.fsize, displayfor(NULL, true), i == curcol ? 0xFFD500 : forecolor, 0)) + getcstat = 1000+i; + at += colwidth(); + } + if(scorefrom < 0) scorefrom = 0; int id = 0; int omit = scorefrom; @@ -144,41 +175,58 @@ void showScores() { if(wrongtype) { id++; continue; } if(omit) { omit--; rank++; id++; continue; } - - char buf[16]; - rank++; sprintf(buf, "%d", rank); - displaystr(bx*4, y, 0, vid.fsize, buf, 0xC0C0C0, 16); + bool cur = S.box[MAXBOX-1]; + if(cur) { + saveBox(); + for(int i=0; i vid.xres) break; + at += colwidth(); + if(displaystr(bx*(at-1), y, 0, vid.fsize, displayfor(&S), col, 16)) + getcstat = 1000+i; + } - displaystr(bx*22, y, 0, vid.fsize, S.ver, 0xC0C0C0, 16); - - displaystr(bx*23, y, 0, vid.fsize, displayfor(&S), 0xC0C0C0, 0); - y += vid.fsize*5/4; id++; } -#ifdef MOBILE - buttonclicked = false; - displayabutton(-1, +1, XLAT("SORT"), BTON); - displayabutton( 0, +1, XLAT("PICK"), BTON); - displayabutton(+1, +1, XLAT("PLAY"), BTON); -#endif + int i0 = vid.yres - vid.fsize; + int xr = vid.xres / 80; + + string modes = + scoremode == 0 ? XLAT(", m - mode: normal") : + scoremode == 1 ? XLAT(", m - mode: shoot'em up") : + scoremode == 2 ? XLAT(", m - mode: hardcore only") : + "?"; + + if(euclid) modes += XLAT(" (E:%1)", euclidland); + + displayButton(xr*10, i0, IFM("s - ") + XLAT("sort"), 's', 8); + displayButton(xr*25, i0, IFM("t - ") + XLAT("choose"), 't', 8); + displayButton(xr*40, i0, IFM("0 - ") + XLAT("play"), '0', 8); + displayButton(xr*65, i0, IFM("m - ") + modes.substr(6), 'm', 8); keyhandler = [] (int sym, int uni) { - #ifndef MOBILE - if(sym == SDLK_LEFT || sym == SDLK_KP4 || sym == 'h' || sym == 'a') - shiftScoreDisplay(-1); - else if(sym == SDLK_RIGHT || sym == SDLK_KP6 || sym == 'l' || sym == 'd') - shiftScoreDisplay(1); + if(sym == SDLK_LEFT || sym == SDLK_KP4 || sym == 'h' || sym == 'a') { + if(curcol > 0) curcol--; + } + else if(sym == SDLK_RIGHT || sym == SDLK_KP6 || sym == 'l' || sym == 'd') { + if(curcol < POSSCORE-1) curcol++; + } + else if(sym >= 1000 && sym < 1000+POSSCORE) + curcol = sym - 1000; else if(sym == 't') { mapeditor::infix = ""; pushScreen(showPickScores); } else if(sym == SDLK_UP || sym == 'k' || sym == 'w') scorefrom -= 5; @@ -191,98 +239,88 @@ void showScores() { else if(sym == 's') sortScores(); else if(sym == 'm') { scoremode++; scoremode %= 3; } else if(doexiton(sym, uni)) popScreen(); - #else - static int scoredragx, scoredragy; - extern bool clicked, lclicked; - extern int andmode; + + static int scoredragy; + static bool lclicked; - if(andmode) { - if(!clicked && !lclicked) { - andmode = 0; - scoredragx = mousex; + if(mousepressed) { + if(!lclicked) { + // scoredragx = mousex; scoredragy = mousey; } - } - else { - - if(clicked && !lclicked) - scoredragx = mousex, scoredragy = mousey; - - else if(lclicked && !clicked) { - if(mousey > vid.ycenter - 2 * vid.fsize) { - if(mousex < vid.xcenter*2/3) sortScores(); - else if(mousex < vid.xcenter*4/3) - cmode = emPickScores; - else andmode = 0, popScreen(); - } - } - - else if(clicked && lclicked) { - // if(mousex > scoredragx + 80) scoredragx += 80, shiftScoreDisplay(1); - // if(mousex < scoredragx - 80) scoredragx -= 80, shiftScoreDisplay(-1); + else { while(mousey > scoredragy + vid.fsize) scoredragy += vid.fsize, scorefrom--; while(mousey < scoredragy - vid.fsize) scoredragy -= vid.fsize, scorefrom++; } + + lclicked = mousepressed; } - #endif }; } -bool monsterpage = false; - -void showPickScores() { - - getcstat = '0'; - int d = scoredisplay; - - pickscore_options.clear(); - - scorerev = false; - - for(int i=0; i= '1' && uni <= '9') uni = uni + 1000 - '1'; - else if(uni >= 1000 && uni < 1000 + size(pickscore_options)) { - scoredisplay = pickscore_options[uni - 1000].second; - popScreen(); + if(sc.ver >= "4.4") { + sc.box[0] = sc.box[65]; + // the first executable on Steam included a corruption + if(sc.box[65] > 1420000000 && sc.box[65] < 1430000000) { + sc.box[0] = sc.box[65] - sc.box[1]; + sc.box[65] = sc.box[0]; + } + // do not include saves + if(sc.box[65 + 4 + itOrbSafety - itOrbLightning]) ok = false; + } + else + sc.box[0] = sc.box[1] - sc.box[0]; // could not save then + + if(sc.box[2] == 0) continue; // do not list zero scores + + if(ok && boxid > 20) scores.push_back(sc); } - else if(mapeditor::editInfix(uni)) ; - else if(doexiton(sym, uni)) popScreen(); - }; + } + + saveBox(); + score sc; + for(int i=0; i