diff --git a/attack.cpp b/attack.cpp index f1760002..c6b4ec3d 100644 --- a/attack.cpp +++ b/attack.cpp @@ -391,7 +391,8 @@ EX void killMutantIvy(cell *c, eMonster who) { removeIvy(c); for(int i=0; itype; i++) if(c->move(i)->mondir == c->c.spin(i) && (isMutantIvy(c->move(i)) || c->move(i)->monst == moFriendlyIvy)) - killMutantIvy(c->move(i), who); + kills[c->move(i)->monst]++, killMutantIvy(c->move(i), who); + if(c->land == laClearing) clearing::imput(c); } EX void killMonster(cell *c, eMonster who, flagtype deathflags IS(0)) { @@ -462,6 +463,7 @@ EX void killMonster(cell *c, eMonster who, flagtype deathflags IS(0)) { if(isMutantIvy(m) || m == moFriendlyIvy) { pcount = 0; + if(isMutantIvy(m)) clearing::direct++; killMutantIvy(c, who); } diff --git a/complex.cpp b/complex.cpp index dd0bd4ab..0b10447f 100644 --- a/complex.cpp +++ b/complex.cpp @@ -956,6 +956,45 @@ EX namespace clearing { steps--; ds++; } } + + typedef tuple celltype; + + map > stats; + + EX bignum imputed; + EX int direct; + + map > score; + + celltype get_celltype(cell *c) { + cell *c1 = c; + if(c->mondir < c->type) + c1 = c->move(c->mondir); + return make_tuple( + celldistAlt(c), type_in(expansion, c, celldistAlt), + celldistAlt(c1), type_in(expansion, c1, celldistAlt) + ); + } + + EX void imput(cell *c) { + if(score.count(c)) return; + auto& is = score[c]; + celltype t = get_celltype(c); + auto& stat = stats[t]; + is.second = c->mondir; + if(c->mpdist <= 6) { + is.first = 1; + forCellEx(c2, c) if(score.count(c2) && c2->move(score[c2].second) == c) + is.first += score[c2].first; + stat.first += is.first; + stat.second++; + } + else { + is.first = stat.second ? stat.first.randomized_div(stat.second) : bignum(1); + imputed += is.first; + } + } + EX } EX namespace whirlpool { diff --git a/graph.cpp b/graph.cpp index 6150925f..7208db16 100644 --- a/graph.cpp +++ b/graph.cpp @@ -4786,7 +4786,7 @@ EX bool nohelp; EX void normalscreen() { help = "@"; - mouseovers = XLAT("Press F1 or right click for help"); + mouseovers = standard_help(); #if CAP_TOUR if(tour::on) mouseovers = tour::tourhelp; diff --git a/help.cpp b/help.cpp index d179f722..6fe48d89 100644 --- a/help.cpp +++ b/help.cpp @@ -178,6 +178,10 @@ void buildHelpText() { #endif } +EX string standard_help() { + return XLAT("Press F1 or right click for help"); + } + EX void buildCredits() { help = ""; help += XLAT("game design, programming, texts and graphics by Zeno Rogue \n\n"); @@ -576,6 +580,16 @@ EX string generateHelpForMonster(eMonster m) { if(isGhost(m)) s += XLAT("\n\nA Ghost never moves to a cell which is adjacent to another Ghost of the same kind.", m); + if(m == moMutant) { + using namespace clearing; + if(direct) + s += XLAT("\n\nLeaves cut directly: " + its(direct)); + if(kills[moMutant]) + s += XLAT("\n\nLeaves cut onscreen: " + its(kills[moMutant])); + if(imputed.nonzero()) + s += XLAT("\n\nLeaves cut offscreen (approximately): " + imputed.get_str(10000)); + } + if(m == moBat || m == moEagle) s += XLAT("\n\nFast flying creatures may attack or go against gravity only in their first move.", m); diff --git a/hud.cpp b/hud.cpp index 38476004..0ae19507 100644 --- a/hud.cpp +++ b/hud.cpp @@ -253,8 +253,25 @@ bool displayglyph(int cx, int cy, int buttonsize, char glyph, color_t color, int (qty < 10 && (flags & (GLYPH_MARKTODO | GLYPH_RUNOUT))) ? buttonsize*3/4 : qty < 100 ? buttonsize / 2 : buttonsize / 3; - if(str != "") - displayfr(cx + buttonsize, cy + buttonsize/2 - bsize/2, 1, bsize, str, color, 16); + + if(id == moMutant + ittypes && clearing::imputed.nonzero()) { + ld d = qty + clearing::imputed.approx_ld(); + if(d < 100000) str = its(int(d)); + else { + int digits = 0; + while(d >= 10) digits++, d /= 10; + str = its(int(d*100)) + "E" + its(digits); + str.insert(1, "."); + } + bsize = buttonsize / 4; + } + + if(str != "") { + if(textwidth(bsize, str) < buttonsize) + displayfr(cx + buttonsize, cy + buttonsize/2 - bsize/2, 1, bsize, str, color, 16); + else + displayfr(cx, cy + buttonsize/2 - bsize/2, 1, bsize, str, color, 0); + } return b; } @@ -365,6 +382,8 @@ EX bool nofps = false; EX color_t crosshair_color = 0xFFFFFFC0; EX ld crosshair_size = 0; +EX bool long_kills; + EX void drawStats() { if(nohud || vid.stereo_mode == sLR) return; if(callhandlers(false, hooks_prestats)) return; @@ -577,7 +596,8 @@ EX void drawStats() { #endif } else if(!peace::on) { - if(displayButtonS(vid.xres - 8, vid.fsize, XLAT("score: %1", its(gold())), forecolor, 16, vid.fsize)) { + string scoreline = XLAT("score: %1", its(gold())); + if(displayButtonS(vid.xres - 8, vid.fsize, scoreline, forecolor, 16, vid.fsize)) { mouseovers = XLAT("Your total wealth"), instat = true, getcstat = SDLK_F1, @@ -590,16 +610,29 @@ EX void drawStats() { "Orbs of Yendor are worth 50 $$$ each.\n\n" ); } - if(displayButtonS(8, vid.fsize, XLAT("kills: %1", its(tkills())), forecolor, 0, vid.fsize)) { - instat = true, - getcstat = SDLK_F1, - mouseovers = XLAT("Your total kills")+": " + its(tkills()), - help = helptitle(XLAT("Your total kills") + ": " + its(tkills()), 0x404040) + - XLAT( - "In most lands, more treasures are generated with each enemy native to this land you kill. " - "Moreover, 100 kills is a requirement to enter the Graveyard and the Hive.\n\n" - "Friendly creatures and parts of monsters (such as the Ivy) do appear in the list, " - "but are not counted in the total kill count."); + string s = XLAT("kills: %1", its(tkills())); + long_kills = false; + int siz = vid.fsize; + if(cwt.at->land == laClearing && clearing::imputed.approx_ld() >= 100000) { + long_kills = true; + s = XLAT("leaves cut: " + (bignum(kills[moMutant]) + clearing::imputed).get_str(200)); + if(mouseovers == standard_help()) mouseovers = " "; + while(siz > 4 && textwidth(siz, s) > vid.xres - textwidth(vid.fsize, scoreline)) siz--; + } + + if(displayButtonS(8, vid.fsize, s, forecolor, 0, siz)) { + instat = true; + getcstat = SDLK_F1; + if(long_kills) { mouseovers = " "; help = generateHelpForMonster(moMutant); } + else { + mouseovers = XLAT("Your total kills")+": " + its(tkills()), + help = helptitle(XLAT("Your total kills") + ": " + its(tkills()), 0x404040) + + XLAT( + "In most lands, more treasures are generated with each enemy native to this land you kill. " + "Moreover, 100 kills is a requirement to enter the Graveyard and the Hive.\n\n" + "Friendly creatures and parts of monsters (such as the Ivy) do appear in the list, " + "but are not counted in the total kill count."); + } } } string vers = VER; diff --git a/system.cpp b/system.cpp index 960384bf..c45867ca 100644 --- a/system.cpp +++ b/system.cpp @@ -394,7 +394,7 @@ bool havesave = true; #if HDR #define MAXBOX 500 -#define POSSCORE 371 // update this when new boxes are added! +#define POSSCORE 373 // update this when new boxes are added! struct score { string ver; int box[MAXBOX]; @@ -414,6 +414,16 @@ void applyBox(int& t) { else boxid++; } +void applyBoxBignum(bignum& tb) { + float tf; + int ti; + if(saving) tf = tb.approx_ld(); + if(saving) memcpy(&ti, &tf, 4); + applyBox(ti); + if(loading) memcpy(&tf, &ti, 4); + if(loading) tb = bignum(tf); + } + EX void applyBoxNum(int& i, string name IS("")) { fakebox[boxid] = (name == ""); boxname[boxid] = name; @@ -814,6 +824,9 @@ EX void applyBoxes() { applyBoxM(moNarciss); applyBoxM(moMirrorSpirit); + + applyBox(clearing::direct); + applyBoxBignum(clearing::imputed); if(POSSCORE != boxid) printf("ERROR: %d boxes\n", boxid); }