Merge branch 'NetHack-3.6.2-beta01' into NetHack-3.6.2

This commit is contained in:
nhmall
2018-07-07 12:10:03 -04:00
11 changed files with 67 additions and 35 deletions
+14 -1
View File
@@ -54,7 +54,20 @@ highlighting status conditions would fail to use attributes if a rule with
them was followed by another one without (color only or color&normal) them was followed by another one without (color only or color&normal)
when using 'O' to set hilite_status rules, hide the 'score' status field if when using 'O' to set hilite_status rules, hide the 'score' status field if
game has been built without SCORE_ON_BOTL; latent rules for 'score' game has been built without SCORE_ON_BOTL; latent rules for 'score'
can still be set in config file but can't be added or removed via 'O' can still be set in config file and removed via 'O' but can't be added
make stone-to-flesh behave the same on statues of petrified monsters as it
does on random 'dungeon art' ones (revive at a nearby spot instead of
becoming a corpse when there's already a monster at statue's location)
special level loader didn't support populating several types of special rooms
(ant hole, cockatrice nest, leprechaun hall)
eating rings while polymorphed didn't handle bonus/penalty for increase damage,
increase accuracy, or protection correctly
shopkeeper's position in front of shop door didn't correctly handle bottom
edge of irregularly shaped shop due to typo or copy+paste error
(latent bug; no such shops are present in 3.6.x)
attempting to update permanent inventory window during restore had problems
with unpaid items (needed shop bill before shop and its shopkeeper
were restored) and named fruit
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
+1 -1
View File
@@ -2860,7 +2860,7 @@ E boolean FDECL(get_obj_location, (struct obj *, xchar *, xchar *, int));
E boolean FDECL(get_mon_location, (struct monst *, xchar *, xchar *, int)); E boolean FDECL(get_mon_location, (struct monst *, xchar *, xchar *, int));
E struct monst *FDECL(get_container_location, E struct monst *FDECL(get_container_location,
(struct obj * obj, int *, int *)); (struct obj * obj, int *, int *));
E struct monst *FDECL(montraits, (struct obj *, coord *)); E struct monst *FDECL(montraits, (struct obj *, coord *, BOOLEAN_P));
E struct monst *FDECL(revive, (struct obj *, BOOLEAN_P)); E struct monst *FDECL(revive, (struct obj *, BOOLEAN_P));
E int FDECL(unturn_dead, (struct monst *)); E int FDECL(unturn_dead, (struct monst *));
E void FDECL(cancel_item, (struct obj *)); E void FDECL(cancel_item, (struct obj *));
+10 -4
View File
@@ -1877,10 +1877,11 @@ int old, inc, typ;
{ {
int absold, absinc, sgnold, sgninc; int absold, absinc, sgnold, sgninc;
/* don't include any amount coming from worn rings */ /* don't include any amount coming from worn rings (caller handles
if (uright && uright->otyp == typ) 'protection' differently) */
if (uright && uright->otyp == typ && typ != RIN_PROTECTION)
old -= uright->spe; old -= uright->spe;
if (uleft && uleft->otyp == typ) if (uleft && uleft->otyp == typ && typ != RIN_PROTECTION)
old -= uleft->spe; old -= uleft->spe;
absold = abs(old), absinc = abs(inc); absold = abs(old), absinc = abs(inc);
sgnold = sgn(old), sgninc = sgn(inc); sgnold = sgn(old), sgninc = sgn(inc);
@@ -1900,6 +1901,11 @@ int old, inc, typ;
} else { } else {
inc = 0; /* no further increase allowed via this method */ inc = 0; /* no further increase allowed via this method */
} }
/* put amount from worn rings back */
if (uright && uright->otyp == typ && typ != RIN_PROTECTION)
old += uright->spe;
if (uleft && uleft->otyp == typ && typ != RIN_PROTECTION)
old += uleft->spe;
return old + inc; return old + inc;
} }
@@ -1908,7 +1914,7 @@ accessory_has_effect(otmp)
struct obj *otmp; struct obj *otmp;
{ {
pline("Magic spreads through your body as you digest the %s.", pline("Magic spreads through your body as you digest the %s.",
otmp->oclass == RING_CLASS ? "ring" : "amulet"); (otmp->oclass == RING_CLASS) ? "ring" : "amulet");
} }
STATIC_OVL void STATIC_OVL void
+3 -1
View File
@@ -1194,7 +1194,9 @@ unsigned doname_flags;
Strcat(bp, " (at the ready)"); Strcat(bp, " (at the ready)");
} }
} }
if (!iflags.suppress_price && is_unpaid(obj)) { /* treat 'restoring' like suppress_price because shopkeeper and
bill might not be available yet while restore is in progress */
if (!iflags.suppress_price && !restoring && is_unpaid(obj)) {
long quotedprice = unpaid_cost(obj, TRUE); long quotedprice = unpaid_cost(obj, TRUE);
Sprintf(eos(bp), " (%s, %ld %s)", Sprintf(eos(bp), " (%s, %ld %s)",
+16 -8
View File
@@ -35,8 +35,7 @@ STATIC_DCL struct monst *FDECL(restmonchn, (int, BOOLEAN_P));
STATIC_DCL struct fruit *FDECL(loadfruitchn, (int)); STATIC_DCL struct fruit *FDECL(loadfruitchn, (int));
STATIC_DCL void FDECL(freefruitchn, (struct fruit *)); STATIC_DCL void FDECL(freefruitchn, (struct fruit *));
STATIC_DCL void FDECL(ghostfruit, (struct obj *)); STATIC_DCL void FDECL(ghostfruit, (struct obj *));
STATIC_DCL boolean STATIC_DCL boolean FDECL(restgamestate, (int, unsigned int *, unsigned int *));
FDECL(restgamestate, (int, unsigned int *, unsigned int *));
STATIC_DCL void FDECL(restlevelstate, (unsigned int, unsigned int)); STATIC_DCL void FDECL(restlevelstate, (unsigned int, unsigned int));
STATIC_DCL int FDECL(restlevelfile, (int, XCHAR_P)); STATIC_DCL int FDECL(restlevelfile, (int, XCHAR_P));
STATIC_OVL void FDECL(restore_msghistory, (int)); STATIC_OVL void FDECL(restore_msghistory, (int));
@@ -521,6 +520,7 @@ unsigned int *stuckid, *steedid;
struct obj *otmp, *tmp_bc; struct obj *otmp, *tmp_bc;
char timebuf[15]; char timebuf[15];
unsigned long uid; unsigned long uid;
boolean defer_perm_invent;
mread(fd, (genericptr_t) &uid, sizeof uid); mread(fd, (genericptr_t) &uid, sizeof uid);
if (SYSOPT_CHECK_SAVE_UID if (SYSOPT_CHECK_SAVE_UID
@@ -531,7 +531,7 @@ unsigned int *stuckid, *steedid;
if (!wizard) if (!wizard)
return FALSE; return FALSE;
} }
mread(fd, (genericptr_t) &context, sizeof(struct context_info)); mread(fd, (genericptr_t) &context, sizeof (struct context_info));
if (context.warntype.speciesidx >= LOW_PM) if (context.warntype.speciesidx >= LOW_PM)
context.warntype.species = &mons[context.warntype.speciesidx]; context.warntype.species = &mons[context.warntype.speciesidx];
@@ -539,7 +539,13 @@ unsigned int *stuckid, *steedid;
file option values instead of keeping old save file option values file option values instead of keeping old save file option values
if partial restore fails and we resort to starting a new game */ if partial restore fails and we resort to starting a new game */
newgameflags = flags; newgameflags = flags;
mread(fd, (genericptr_t) &flags, sizeof(struct flag)); mread(fd, (genericptr_t) &flags, sizeof (struct flag));
/* avoid keeping permanent inventory window up to date during restore
(setworn() calls update_inventory); attempting to include the cost
of unpaid items before shopkeeper's bill is available is a no-no;
named fruit names aren't accessible yet either */
defer_perm_invent = flags.perm_invent;
flags.perm_invent = FALSE;
/* wizard and discover are actually flags.debug and flags.explore; /* wizard and discover are actually flags.debug and flags.explore;
player might be overriding the save file values for them; player might be overriding the save file values for them;
in the discover case, we don't want to set that for a normal in the discover case, we don't want to set that for a normal
@@ -645,14 +651,14 @@ unsigned int *stuckid, *steedid;
restlevchn(fd); restlevchn(fd);
mread(fd, (genericptr_t) &moves, sizeof moves); mread(fd, (genericptr_t) &moves, sizeof moves);
mread(fd, (genericptr_t) &monstermoves, sizeof monstermoves); mread(fd, (genericptr_t) &monstermoves, sizeof monstermoves);
mread(fd, (genericptr_t) &quest_status, sizeof(struct q_score)); mread(fd, (genericptr_t) &quest_status, sizeof (struct q_score));
mread(fd, (genericptr_t) spl_book, sizeof(struct spell) * (MAXSPELL + 1)); mread(fd, (genericptr_t) spl_book, (MAXSPELL + 1) * sizeof (struct spell));
restore_artifacts(fd); restore_artifacts(fd);
restore_oracles(fd); restore_oracles(fd);
if (u.ustuck) if (u.ustuck)
mread(fd, (genericptr_t) stuckid, sizeof(*stuckid)); mread(fd, (genericptr_t) stuckid, sizeof *stuckid);
if (u.usteed) if (u.usteed)
mread(fd, (genericptr_t) steedid, sizeof(*steedid)); mread(fd, (genericptr_t) steedid, sizeof *steedid);
mread(fd, (genericptr_t) pl_character, sizeof pl_character); mread(fd, (genericptr_t) pl_character, sizeof pl_character);
mread(fd, (genericptr_t) pl_fruit, sizeof pl_fruit); mread(fd, (genericptr_t) pl_fruit, sizeof pl_fruit);
@@ -665,6 +671,8 @@ unsigned int *stuckid, *steedid;
/* must come after all mons & objs are restored */ /* must come after all mons & objs are restored */
relink_timers(FALSE); relink_timers(FALSE);
relink_light_sources(FALSE); relink_light_sources(FALSE);
/* inventory display is now viable */
flags.perm_invent = defer_perm_invent;
return TRUE; return TRUE;
} }
+7 -6
View File
@@ -602,6 +602,7 @@ struct mkroom *sroom;
/* check that the shopkeeper placement is sane */ /* check that the shopkeeper placement is sane */
if (sroom->irregular) { if (sroom->irregular) {
int rmno = (int) ((sroom - rooms) + ROOMOFFSET); int rmno = (int) ((sroom - rooms) + ROOMOFFSET);
if (isok(sx - 1, sy) && !levl[sx - 1][sy].edge if (isok(sx - 1, sy) && !levl[sx - 1][sy].edge
&& (int) levl[sx - 1][sy].roomno == rmno) && (int) levl[sx - 1][sy].roomno == rmno)
sx--; sx--;
@@ -613,18 +614,18 @@ struct mkroom *sroom;
sy--; sy--;
else if (isok(sx, sy + 1) && !levl[sx][sy + 1].edge else if (isok(sx, sy + 1) && !levl[sx][sy + 1].edge
&& (int) levl[sx][sy + 1].roomno == rmno) && (int) levl[sx][sy + 1].roomno == rmno)
sx++; sy++;
else else
goto shk_failed; goto shk_failed;
} else if (sx == sroom->lx - 1) } else if (sx == sroom->lx - 1) {
sx++; sx++;
else if (sx == sroom->hx + 1) } else if (sx == sroom->hx + 1) {
sx--; sx--;
else if (sy == sroom->ly - 1) } else if (sy == sroom->ly - 1) {
sy++; sy++;
else if (sy == sroom->hy + 1) } else if (sy == sroom->hy + 1) {
sy--; sy--;
else { } else {
shk_failed: shk_failed:
#ifdef DEBUG #ifdef DEBUG
/* Said to happen sometimes, but I have never seen it. */ /* Said to happen sometimes, but I have never seen it. */
+4 -2
View File
@@ -786,10 +786,9 @@ link_doors_rooms()
void void
fill_rooms() fill_rooms()
{ {
int tmpi; int tmpi, m;
for (tmpi = 0; tmpi < nroom; tmpi++) { for (tmpi = 0; tmpi < nroom; tmpi++) {
int m;
if (rooms[tmpi].needfill) if (rooms[tmpi].needfill)
fill_room(&rooms[tmpi], (rooms[tmpi].needfill == 2)); fill_room(&rooms[tmpi], (rooms[tmpi].needfill == 2));
for (m = 0; m < rooms[tmpi].nsubrooms; m++) for (m = 0; m < rooms[tmpi].nsubrooms; m++)
@@ -2452,6 +2451,9 @@ boolean prefilled;
case COURT: case COURT:
case ZOO: case ZOO:
case BEEHIVE: case BEEHIVE:
case ANTHOLE:
case COCKNEST:
case LEPREHALL:
case MORGUE: case MORGUE:
case BARRACKS: case BARRACKS:
fill_zoo(croom); fill_zoo(croom);
+1 -1
View File
@@ -595,7 +595,7 @@ int *fail_reason;
if (use_saved_traits) { if (use_saved_traits) {
/* restore a petrified monster */ /* restore a petrified monster */
cc.x = x, cc.y = y; cc.x = x, cc.y = y;
mon = montraits(statue, &cc); mon = montraits(statue, &cc, (cause == ANIMATE_SPELL));
if (mon && mon->mtame && !mon->isminion) if (mon && mon->mtame && !mon->isminion)
wary_dog(mon, TRUE); wary_dog(mon, TRUE);
} else { } else {
+4 -3
View File
@@ -112,7 +112,6 @@ register struct obj *obj;
: !is_weptool(obj) && !is_wet_towel(obj); : !is_weptool(obj) && !is_wet_towel(obj);
} else } else
unweapon = TRUE; /* for "bare hands" message */ unweapon = TRUE; /* for "bare hands" message */
update_inventory();
} }
STATIC_OVL boolean STATIC_OVL boolean
@@ -230,7 +229,9 @@ setuqwep(obj)
register struct obj *obj; register struct obj *obj;
{ {
setworn(obj, W_QUIVER); setworn(obj, W_QUIVER);
update_inventory(); /* no extra handling needed; this used to include a call to
update_inventory() but that's already performed by setworn() */
return;
} }
void void
@@ -238,7 +239,7 @@ setuswapwep(obj)
register struct obj *obj; register struct obj *obj;
{ {
setworn(obj, W_SWAPWEP); setworn(obj, W_SWAPWEP);
update_inventory(); return;
} }
/*** Commands to change particular slot(s) ***/ /*** Commands to change particular slot(s) ***/
+2 -5
View File
@@ -106,8 +106,7 @@ long mask;
} }
} }
} }
if (!restoring) update_inventory();
update_inventory();
} }
/* called e.g. when obj is destroyed */ /* called e.g. when obj is destroyed */
@@ -138,9 +137,7 @@ register struct obj *obj;
if ((p = w_blocks(obj, wp->w_mask)) != 0) if ((p = w_blocks(obj, wp->w_mask)) != 0)
u.uprops[p].blocked &= ~wp->w_mask; u.uprops[p].blocked &= ~wp->w_mask;
} }
/* setnotworn() isn't called during restore but parallel setworn() */ update_inventory();
if (!restoring)
update_inventory();
} }
/* return item worn in slot indiciated by wornmask; needed by poly_obj() */ /* return item worn in slot indiciated by wornmask; needed by poly_obj() */
+5 -3
View File
@@ -555,9 +555,10 @@ int locflags; /* non-zero means get location even if monster is buried */
/* used by revive() and animate_statue() */ /* used by revive() and animate_statue() */
struct monst * struct monst *
montraits(obj, cc) montraits(obj, cc, adjacentok)
struct obj *obj; struct obj *obj;
coord *cc; coord *cc;
boolean adjacentok; /* False: at obj's spot only, True: nearby is allowed */
{ {
struct monst *mtmp = (struct monst *) 0; struct monst *mtmp = (struct monst *) 0;
struct monst *mtmp2 = (struct monst *) 0; struct monst *mtmp2 = (struct monst *) 0;
@@ -570,7 +571,8 @@ coord *cc;
if (mtmp2->mhpmax <= 0 && !is_rider(mtmp2->data)) if (mtmp2->mhpmax <= 0 && !is_rider(mtmp2->data))
return (struct monst *) 0; return (struct monst *) 0;
mtmp = makemon(mtmp2->data, cc->x, cc->y, mtmp = makemon(mtmp2->data, cc->x, cc->y,
NO_MINVENT | MM_NOWAIT | MM_NOCOUNTBIRTH); (NO_MINVENT | MM_NOWAIT | MM_NOCOUNTBIRTH
| (adjacentok ? MM_ADJACENTOK : 0)));
if (!mtmp) if (!mtmp)
return mtmp; return mtmp;
@@ -786,7 +788,7 @@ boolean by_hero;
} else if (has_omonst(corpse)) { } else if (has_omonst(corpse)) {
/* use saved traits */ /* use saved traits */
xy.x = x, xy.y = y; xy.x = x, xy.y = y;
mtmp = montraits(corpse, &xy); mtmp = montraits(corpse, &xy, FALSE);
if (mtmp && mtmp->mtame && !mtmp->isminion) if (mtmp && mtmp->mtame && !mtmp->isminion)
wary_dog(mtmp, TRUE); wary_dog(mtmp, TRUE);
} else { } else {