score wrapping band-aid

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.
This commit is contained in:
cohrs
2004-03-26 18:28:28 +00:00
parent e424ca4ba3
commit 607f63e5fd
4 changed files with 40 additions and 23 deletions

View 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);
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

View File

@@ -10,8 +10,12 @@
#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);

View 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