diff --git a/help.cpp b/help.cpp index f4a796a4..8a5a3707 100644 --- a/help.cpp +++ b/help.cpp @@ -597,6 +597,26 @@ string turnstring(int i) { else return XLAT("%1 turns", its(i)); } +reaction_t helpgenerator; +string bygen(reaction_t h) { + helpgenerator = h; + return "HELPGEN"; + } + +void gotoHelpFor(eLand l); + +void gotoHelpFor(eItem i) { + help = generateHelpForItem(i); + } + +void gotoHelpFor(eWall w) { + help = generateHelpForWall(w); + }; + +void gotoHelpFor(eMonster m) { + help = generateHelpForMonster(m); + }; + void describeMouseover() { DEBB(DF_GRAPH, (debugfile,"describeMouseover\n")); @@ -605,7 +625,7 @@ void describeMouseover() { if(!c || instat || getcstat != '-') { } else if(c->wall != waInvisibleFloor) { out = XLAT1(linf[c->land].name); - help = generateHelpForLand(c->land); + help = bygen([c] () { gotoHelpFor(c->land); }); if(isIcyLand(c)) out += " (" + fts(heat::celsius(c)) + " °C)"; @@ -656,9 +676,11 @@ void describeMouseover() { if((c->wall == waBigTree || c->wall == waSmallTree) && c->land != laDryForest) help = "Trees in this forest can be chopped down. Big trees take two turns to chop down."; - else if(c->wall != waSea && c->wall != waPalace) - if(!((c->wall == waCavefloor || c->wall == waCavewall) && c->land == laEmerald)) - help = generateHelpForWall(c->wall); + else + if(c->wall != waSea && c->wall != waPalace && c->wall != waDeadfloor) + if(!((c->wall == waCavefloor || c->wall == waCavewall) && (c->land == laEmerald && c->land == laCaves))) + if(!((isAlch(c->wall) && c->land == laAlchemist))) + help = bygen([c] () { gotoHelpFor(c->wall); }); } if(isActivable(c)) out += XLAT(" (touch to activate)"); @@ -680,7 +702,7 @@ void describeMouseover() { if(c->monst == moTortoise && tortoise::seek()) out += " " + tortoise::measure(tortoise::getb(c)); - help = generateHelpForMonster(c->monst); + help = bygen([c] () { gotoHelpFor(c->monst); }); } if(c->item && !itemHiddenFromSight(c)) { @@ -689,7 +711,8 @@ void describeMouseover() { if(c->item == itBarrow) out += " (x" + its(c->landparam) + ")"; if(c->item == itBabyTortoise && tortoise::seek()) out += " " + tortoise::measure(tortoise::babymap[c]); - if(!c->monst) help = generateHelpForItem(c->item); + if(!c->monst) + help = bygen([c] () { gotoHelpFor(c->monst); }); } if(isPlayerOn(c) && !shmup::on) out += XLAT(", you"), help = generateHelpForMonster(moPlayer); @@ -721,8 +744,12 @@ void describeMouseover() { if(mousey < vid.fsize * 3/2) getcstat = SDLK_F1; } -string help_action_text; -reaction_t help_action; +struct help_extension { + char key; + string text; + reaction_t action; + }; +vector help_extensions; void showHelp() { gamescreen(2); @@ -747,19 +774,25 @@ void showHelp() { dialog::addHelp(help); } - if(help == buildHelpText()) dialog::addItem(XLAT("credits"), 'c'); - if(help_action_text != "") dialog::addItem(help_action_text, 't'); + for(auto& he: help_extensions) + dialog::addItem(he.text, he.key); dialog::display(); keyhandler = [] (int sym, int uni) { dialog::handleNavigation(sym, uni); + + for(auto& he: help_extensions) + if(uni == he.key) { + // we need to copy he.action + // as otherwise it could clear the extensions, + // leading to errors + auto act = he.action; + act(); + return; + } if(sym == SDLK_F1 && help != "@") help = "@"; - else if(uni == 'c') - help = buildCredits(); - else if(uni == 't' && help_action) - help_action(); else if(doexiton(sym, uni)) popScreen(); }; @@ -767,6 +800,48 @@ void showHelp() { void gotoHelp(const string& h) { help = h; - help_action = reaction_t(); + help_extensions.clear(); pushScreen(showHelp); + if(help == "@" || help == buildHelpText()) + help_extensions.push_back(help_extension{'c', XLAT("credits"), [] () { help = buildCredits(); }}); + if(help == "HELPGEN") helpgenerator(); + } + +void subhelp(const string& h) { + string oldhelp = help; + auto ext = help_extensions; + reaction_t back = [oldhelp, ext] () { + help = oldhelp; + help_extensions = ext; + }; + help = h; + help_extensions.clear(); + if(help == "HELPGEN") helpgenerator(); + help_extensions.push_back(help_extension{'z', XLAT("back"), back}); + } + +void gotoHelpFor(eLand l) { + help = generateHelpForLand(l); + + int beastcount = 0; + for(int m0=0; m0 3) + help_extensions.push_back(help_extension{'b', XLAT("bestiary of %the1", l), [l, listbeasts] () { + subhelp(helptitle(XLAT("bestiary of %the1", l), 0xC00000)); + listbeasts(); + }}); + else listbeasts(); } diff --git a/landlock.cpp b/landlock.cpp index fa2fdf99..dfc34cc0 100644 --- a/landlock.cpp +++ b/landlock.cpp @@ -1,5 +1,14 @@ // land statistics and flags +bool nodisplay(eMonster m) { + return + m == moIvyDead || + m == moDragonTail || + m == moWolfMoved || + m == moIvyNext || + m == moIvyDead; + } + // returns: 2 = treasure increaser, 1 = just appears, 0 = does not appear int isNative(eLand l, eMonster m) { switch(l) { @@ -41,7 +50,7 @@ int isNative(eLand l, eMonster m) { return (m == moHedge || m == moFireFairy) ? 2 : 0; case laHell: - return (m == moLesser) ? 2 : 0; + return (m == moLesser || m == moGreater) ? 2 : 0; case laCocytus: return (m == moShark || m == moGreaterShark || m == moCrystalSage) ? 2 : @@ -102,7 +111,7 @@ int isNative(eLand l, eMonster m) { case laEAir: case laEEarth: case laEWater: case laEFire: case laElementalWall: - if(m == elementalOf(l)) return 2; + if(m == elementalOf(l) && m) return 2; return (m == moAirElemental || m == moEarthElemental || m == moWaterElemental || m == moFireElemental) ? 1 : 0; case laStorms: @@ -115,7 +124,15 @@ int isNative(eLand l, eMonster m) { return (m == moOutlaw) ? 2 : 0; case laHalloween: - return 1; + return (m == moGhost || m == moZombie || m == moWitch || + m == moLesser || m == moGreater || + m == moVampire || m == moDraugr || + m == moSkeleton || m == moWitchFire || + m == moFlailer || m == moPyroCultist || + m == moFatGuard || m == moHedge || + m == moLancer || m == moFireFairy || + m == moBomberbird || m == moRatlingAvenger || + m == moVineBeast || m == moDragonHead || m == moDragonTail) ? 1 : 0; case laClearing: return (m == moMutant || m == moRedFox) ? 1 : 0; @@ -181,7 +198,7 @@ int isNative(eLand l, eMonster m) { case laDogPlains: return m == moHunterDog ? 1 : 0; - case laCA: return false; + case laCA: return 0; } return false; } diff --git a/menus.cpp b/menus.cpp index 3f82480a..fd2a1ea0 100644 --- a/menus.cpp +++ b/menus.cpp @@ -140,10 +140,9 @@ void showOverview() { int udiv = uni / 1000; if(udiv == 1 && umod < landtypes) { eLand l = eLand(umod); - gotoHelp(generateHelpForLand(l)); + gotoHelp(""); gotoHelpFor(l); if(cheater) { - help_action_text = "teleport"; - help_action = [l] () { + help_extensions.push_back(help_extension{'t', XLAT("teleport"), [l] () { cheater++; bool princ = (l == laPrincessQuest); if(princ) { @@ -157,7 +156,7 @@ void showOverview() { if(princ) fullcenter(); popScreen(); popScreen(); - }; + }}); } } else if(udiv == 2 && umod < ittypes) {