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

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)
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'
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

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 struct monst *FDECL(get_container_location,
(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 int FDECL(unturn_dead, (struct monst *));
E void FDECL(cancel_item, (struct obj *));

View File

@@ -1877,10 +1877,11 @@ int old, inc, typ;
{
int absold, absinc, sgnold, sgninc;
/* don't include any amount coming from worn rings */
if (uright && uright->otyp == typ)
/* don't include any amount coming from worn rings (caller handles
'protection' differently) */
if (uright && uright->otyp == typ && typ != RIN_PROTECTION)
old -= uright->spe;
if (uleft && uleft->otyp == typ)
if (uleft && uleft->otyp == typ && typ != RIN_PROTECTION)
old -= uleft->spe;
absold = abs(old), absinc = abs(inc);
sgnold = sgn(old), sgninc = sgn(inc);
@@ -1900,6 +1901,11 @@ int old, inc, typ;
} else {
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;
}
@@ -1908,7 +1914,7 @@ accessory_has_effect(otmp)
struct obj *otmp;
{
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

View File

@@ -1194,7 +1194,9 @@ unsigned doname_flags;
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);
Sprintf(eos(bp), " (%s, %ld %s)",

View File

@@ -35,8 +35,7 @@ STATIC_DCL struct monst *FDECL(restmonchn, (int, BOOLEAN_P));
STATIC_DCL struct fruit *FDECL(loadfruitchn, (int));
STATIC_DCL void FDECL(freefruitchn, (struct fruit *));
STATIC_DCL void FDECL(ghostfruit, (struct obj *));
STATIC_DCL boolean
FDECL(restgamestate, (int, unsigned int *, unsigned int *));
STATIC_DCL boolean FDECL(restgamestate, (int, unsigned int *, unsigned int *));
STATIC_DCL void FDECL(restlevelstate, (unsigned int, unsigned int));
STATIC_DCL int FDECL(restlevelfile, (int, XCHAR_P));
STATIC_OVL void FDECL(restore_msghistory, (int));
@@ -521,6 +520,7 @@ unsigned int *stuckid, *steedid;
struct obj *otmp, *tmp_bc;
char timebuf[15];
unsigned long uid;
boolean defer_perm_invent;
mread(fd, (genericptr_t) &uid, sizeof uid);
if (SYSOPT_CHECK_SAVE_UID
@@ -531,7 +531,7 @@ unsigned int *stuckid, *steedid;
if (!wizard)
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)
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
if partial restore fails and we resort to starting a new game */
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;
player might be overriding the save file values for them;
in the discover case, we don't want to set that for a normal
@@ -645,14 +651,14 @@ unsigned int *stuckid, *steedid;
restlevchn(fd);
mread(fd, (genericptr_t) &moves, sizeof moves);
mread(fd, (genericptr_t) &monstermoves, sizeof monstermoves);
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) &quest_status, sizeof (struct q_score));
mread(fd, (genericptr_t) spl_book, (MAXSPELL + 1) * sizeof (struct spell));
restore_artifacts(fd);
restore_oracles(fd);
if (u.ustuck)
mread(fd, (genericptr_t) stuckid, sizeof(*stuckid));
mread(fd, (genericptr_t) stuckid, sizeof *stuckid);
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_fruit, sizeof pl_fruit);
@@ -665,6 +671,8 @@ unsigned int *stuckid, *steedid;
/* must come after all mons & objs are restored */
relink_timers(FALSE);
relink_light_sources(FALSE);
/* inventory display is now viable */
flags.perm_invent = defer_perm_invent;
return TRUE;
}

View File

@@ -602,6 +602,7 @@ struct mkroom *sroom;
/* check that the shopkeeper placement is sane */
if (sroom->irregular) {
int rmno = (int) ((sroom - rooms) + ROOMOFFSET);
if (isok(sx - 1, sy) && !levl[sx - 1][sy].edge
&& (int) levl[sx - 1][sy].roomno == rmno)
sx--;
@@ -613,18 +614,18 @@ struct mkroom *sroom;
sy--;
else if (isok(sx, sy + 1) && !levl[sx][sy + 1].edge
&& (int) levl[sx][sy + 1].roomno == rmno)
sx++;
sy++;
else
goto shk_failed;
} else if (sx == sroom->lx - 1)
} else if (sx == sroom->lx - 1) {
sx++;
else if (sx == sroom->hx + 1)
} else if (sx == sroom->hx + 1) {
sx--;
else if (sy == sroom->ly - 1)
} else if (sy == sroom->ly - 1) {
sy++;
else if (sy == sroom->hy + 1)
} else if (sy == sroom->hy + 1) {
sy--;
else {
} else {
shk_failed:
#ifdef DEBUG
/* Said to happen sometimes, but I have never seen it. */

View File

@@ -786,10 +786,9 @@ link_doors_rooms()
void
fill_rooms()
{
int tmpi;
int tmpi, m;
for (tmpi = 0; tmpi < nroom; tmpi++) {
int m;
if (rooms[tmpi].needfill)
fill_room(&rooms[tmpi], (rooms[tmpi].needfill == 2));
for (m = 0; m < rooms[tmpi].nsubrooms; m++)
@@ -2452,6 +2451,9 @@ boolean prefilled;
case COURT:
case ZOO:
case BEEHIVE:
case ANTHOLE:
case COCKNEST:
case LEPREHALL:
case MORGUE:
case BARRACKS:
fill_zoo(croom);

View File

@@ -595,7 +595,7 @@ int *fail_reason;
if (use_saved_traits) {
/* restore a petrified monster */
cc.x = x, cc.y = y;
mon = montraits(statue, &cc);
mon = montraits(statue, &cc, (cause == ANIMATE_SPELL));
if (mon && mon->mtame && !mon->isminion)
wary_dog(mon, TRUE);
} else {

View File

@@ -112,7 +112,6 @@ register struct obj *obj;
: !is_weptool(obj) && !is_wet_towel(obj);
} else
unweapon = TRUE; /* for "bare hands" message */
update_inventory();
}
STATIC_OVL boolean
@@ -230,7 +229,9 @@ setuqwep(obj)
register struct obj *obj;
{
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
@@ -238,7 +239,7 @@ setuswapwep(obj)
register struct obj *obj;
{
setworn(obj, W_SWAPWEP);
update_inventory();
return;
}
/*** Commands to change particular slot(s) ***/

View File

@@ -106,8 +106,7 @@ long mask;
}
}
}
if (!restoring)
update_inventory();
update_inventory();
}
/* called e.g. when obj is destroyed */
@@ -138,9 +137,7 @@ register struct obj *obj;
if ((p = w_blocks(obj, wp->w_mask)) != 0)
u.uprops[p].blocked &= ~wp->w_mask;
}
/* setnotworn() isn't called during restore but parallel setworn() */
if (!restoring)
update_inventory();
update_inventory();
}
/* return item worn in slot indiciated by wornmask; needed by poly_obj() */

View File

@@ -555,9 +555,10 @@ int locflags; /* non-zero means get location even if monster is buried */
/* used by revive() and animate_statue() */
struct monst *
montraits(obj, cc)
montraits(obj, cc, adjacentok)
struct obj *obj;
coord *cc;
boolean adjacentok; /* False: at obj's spot only, True: nearby is allowed */
{
struct monst *mtmp = (struct monst *) 0;
struct monst *mtmp2 = (struct monst *) 0;
@@ -570,7 +571,8 @@ coord *cc;
if (mtmp2->mhpmax <= 0 && !is_rider(mtmp2->data))
return (struct monst *) 0;
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)
return mtmp;
@@ -786,7 +788,7 @@ boolean by_hero;
} else if (has_omonst(corpse)) {
/* use saved traits */
xy.x = x, xy.y = y;
mtmp = montraits(corpse, &xy);
mtmp = montraits(corpse, &xy, FALSE);
if (mtmp && mtmp->mtame && !mtmp->isminion)
wary_dog(mtmp, TRUE);
} else {