diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 50b83f873..85d4d7ac4 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -60,6 +60,7 @@ thrown potions can sometimes hit a steed's saddle sync default documentation of "null" option with the code tripping over a cockatrice corpse didn't petrify, even when not wearing boots do not call swamps on the Juiblex level "moat" when freezing +keep score from wrapping around and becoming negative by capping it Platform- and/or Interface-Specific Fixes diff --git a/src/botl.c b/src/botl.c index 3b97a4b50..56b9dbcc6 100644 --- a/src/botl.c +++ b/src/botl.c @@ -3,6 +3,7 @@ /* NetHack may be freely redistributed. See license for details. */ #include "hack.h" +#include extern const char *hu_stat[]; /* defined in eat.c */ @@ -154,20 +155,20 @@ max_rank_sz() long botl_score() { - int deepest = deepest_lev_reached(FALSE); + long deepest = deepest_lev_reached(FALSE); + long utotal; + #ifndef GOLDOBJ - long ugold = u.ugold + hidden_gold(); - - if ((ugold -= u.ugold0) < 0L) ugold = 0L; - return ugold + u.urexp + (long)(50 * (deepest - 1)) + utotal = u.ugold + hidden_gold(); + if ((utotal -= u.ugold0) < 0L) utotal = 0L; #else - long umoney = money_cnt(invent) + hidden_gold(); - - if ((umoney -= u.umoney0) < 0L) umoney = 0L; - return umoney + u.urexp + (long)(50 * (deepest - 1)) + utotal = money_cnt(invent) + hidden_gold(); + if ((utotal -= u.umoney0) < 0L) utotal = 0L; #endif - + (long)(deepest > 30 ? 10000 : - deepest > 20 ? 1000*(deepest - 20) : 0); + utotal += u.urexp + (50 * (deepest - 1)) + + (deepest > 30 ? 10000 : deepest > 20 ? 1000*(deepest - 20) : 0); + if (utotal < u.urexp) utotal = LONG_MAX; /* wrap around */ + return utotal; } #endif diff --git a/src/end.c b/src/end.c index 5257db13e..9e7bb98e7 100644 --- a/src/end.c +++ b/src/end.c @@ -10,8 +10,12 @@ #ifndef NO_SIGNAL #include #endif +#include #include "dlb.h" +/* add b to long a, convert wraparound to max value */ +#define nowrap_add(a, b) (a = ((a + b) < 0 ? LONG_MAX : (a + b))) + /* these probably ought to be generated by makedefs, like LAST_GEM */ #define FIRST_GEM DILITHIUM_CRYSTAL #define FIRST_AMULET AMULET_OF_ESP @@ -538,7 +542,7 @@ winid endwin; value = arti_cost(otmp); /* zorkmid value */ points = value * 5 / 2; /* score value */ if (counting) { - u.urexp += points; + nowrap_add(u.urexp, points); } else { makeknown(otmp->otyp); otmp->known = otmp->dknown = otmp->bknown = otmp->rknown = 1; @@ -567,6 +571,7 @@ int how; boolean bones_ok, have_windows = iflags.window_inited; struct obj *corpse = (struct obj *)0; long umoney; + long tmp; if (how == TRICKED) { if (killer.name[0]) { @@ -721,7 +726,6 @@ die: /* calculate score, before creating bones [container gold] */ { - long tmp; int deepest = deepest_lev_reached(FALSE); #ifndef GOLDOBJ @@ -738,11 +742,11 @@ die: tmp = 0L; if (how < PANICKED) tmp -= tmp / 10L; - u.urexp += tmp; - u.urexp += 50L * (long)(deepest - 1); + tmp += 50L * (long)(deepest - 1); if (deepest > 20) - u.urexp += 1000L * (long)((deepest > 30) ? 10 : deepest - 20); - if (how == ASCENDED) u.urexp *= 2L; + tmp += 1000L * (long)((deepest > 30) ? 10 : deepest - 20); + nowrap_add(u.urexp, tmp); + if (how == ASCENDED) nowrap_add(u.urexp, u.urexp); } if (bones_ok) { @@ -819,9 +823,11 @@ die: /* add points for collected valuables */ for (val = valuables; val->list; val++) for (i = 0; i < val->size; i++) - if (val->list[i].count != 0L) - u.urexp += val->list[i].count + if (val->list[i].count != 0L) { + tmp = val->list[i].count * (long)objects[val->list[i].typ].oc_cost; + nowrap_add(u.urexp, tmp); + } /* count the points for artifacts */ artifact_score(invent, TRUE, endwin); @@ -835,7 +841,7 @@ die: if (Schroedingers_cat) { int mhp, m_lev = adj_lev(&mons[PM_HOUSECAT]); mhp = d(m_lev, 8); - u.urexp += mhp; + nowrap_add(u.urexp, mhp); if (!done_stopprint) Strcat(eos(pbuf), " and Schroedinger's cat"); } @@ -844,7 +850,7 @@ die: if (!done_stopprint) Sprintf(eos(pbuf), " and %s", mon_nam(mtmp)); if (mtmp->mtame) - u.urexp += mtmp->mhp; + nowrap_add(u.urexp, mtmp->mhp); mtmp = mtmp->nmon; } if (!done_stopprint) putstr(endwin, 0, pbuf); diff --git a/src/exper.c b/src/exper.c index 6e56c4879..e3fa49814 100644 --- a/src/exper.c +++ b/src/exper.c @@ -3,6 +3,7 @@ /* NetHack may be freely redistributed. See license for details. */ #include "hack.h" +#include STATIC_DCL long FDECL(newuexp, (int)); STATIC_DCL int FDECL(enermod, (int)); @@ -99,8 +100,16 @@ void more_experienced(exp, rexp) register int exp, rexp; { - u.uexp += exp; - u.urexp += 4*exp + rexp; + long newexp = u.uexp + exp; + long rexpincr = 4*exp + rexp; + long newrexp = u.urexp + rexpincr; + + /* cap experience and score on wraparound */ + if (newexp < 0 && exp > 0) newexp = LONG_MAX; + if (newrexp < 0 && rexpincr > 0) newrexp = LONG_MAX; + u.uexp = newexp; + u.urexp = newrexp; + if(exp #ifdef SCORE_ON_BOTL || flags.showscore