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:
@@ -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
|
||||
|
||||
23
src/botl.c
23
src/botl.c
@@ -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
|
||||
|
||||
|
||||
26
src/end.c
26
src/end.c
@@ -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);
|
||||
|
||||
13
src/exper.c
13
src/exper.c
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user