]> granicus.if.org Git - nethack/commitdiff
score wrapping band-aid
authorcohrs <cohrs>
Fri, 26 Mar 2004 18:28:28 +0000 (18:28 +0000)
committercohrs <cohrs>
Fri, 26 Mar 2004 18:28:28 +0000 (18:28 +0000)
This patch simply keeps the score from wrapping by capping it at LONG_MAX.
If someone wants to change the score to be unsigned, some changes will
need to be made to tweak this code (and use ULONG_MAX instead).
I'm assuming that our platforms all have limits.h.

doc/fixes35.0
src/botl.c
src/end.c
src/exper.c

index 50b83f873117850456a9c6faaf538e8f634ded81..85d4d7ac408dd2ca4ec0ba220702032da5b8a01e 100644 (file)
@@ -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
index 3b97a4b5058173710f7e168920defd9a4c55e0f8..56b9dbcc642ff3eb7d2b41e576989717d7d324f2 100644 (file)
@@ -3,6 +3,7 @@
 /* NetHack may be freely redistributed.  See license for details. */
 
 #include "hack.h"
+#include <limits.h>
 
 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);
-#ifndef GOLDOBJ
-    long ugold = u.ugold + hidden_gold();
+    long deepest = deepest_lev_reached(FALSE);
+    long utotal;
 
-    if ((ugold -= u.ugold0) < 0L) ugold = 0L;
-    return ugold + u.urexp + (long)(50 * (deepest - 1))
+#ifndef GOLDOBJ
+    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
 
index 5257db13e711fa53bc19c7d5d122a9d8d01f586f..9e7bb98e7f3c43df83c4cde7ed69f99f2573fb4a 100644 (file)
--- a/src/end.c
+++ b/src/end.c
 #ifndef NO_SIGNAL
 #include <signal.h>
 #endif
+#include <limits.h>
 #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);
index 6e56c487916bcbe05a1a6a4877c55f09b281b1d0..e3fa4981457423451a5b3a867f0d9c8d515ed766 100644 (file)
@@ -3,6 +3,7 @@
 /* NetHack may be freely redistributed.  See license for details. */
 
 #include "hack.h"
+#include <limits.h>
 
 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