Merge branch 'NetHack-3.6.2-beta01' into NetHack-3.6.2
This commit is contained in:
+14
-1
@@ -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
@@ -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 *));
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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() */
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user