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

This commit is contained in:
nhmall
2018-11-24 16:11:09 -05:00
5 changed files with 70 additions and 77 deletions

View File

@@ -205,6 +205,17 @@ successfully paying for shop damage with shop credit would be followed by
if a migrating monster was killed off because there was no room on the
destination level, it would leave a corpse even if it was a type
which should never leave one (demon, golem, blob, &c)
monsters accompanying hero during level change (usually pets) who failed to
arrive and tried to re-migrate were being removed from the map after
already having been removed [impossible "no monster to remove" if
compiled with EXTRA_SANITY_CHECKS enabled] during migration handling
monsters accompanying hero during level change (usually pets) who failed to
arrive and tried to re-migrate (for hero's next visit to the level)
ended up being killed because the migration attempt happened right
away (same visit by hero, so level still full) and they weren't
accompanying hero on the second attempt
fix for above (all failed arrivals will re-migrate) makes the earlier fix (for
invalid corpse being left by monst killed upon migration failure) moot
end of game while carrying Schroedinger's Box would reveal cat-or-corpse
for inventory disclosure or put that info into dumplog, but not both
attempting to untrap an adjacent trap while on the edge of--not in--a pit

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 rm.h $NHDT-Date: 1432512776 2015/05/25 00:12:56 $ $NHDT-Branch: master $:$NHDT-Revision: 1.41 $ */
/* NetHack 3.6 rm.h $NHDT-Date: 1543052680 2018/11/24 09:44:40 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.59 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Pasi Kallinen, 2017. */
/* NetHack may be freely redistributed. See license for details. */
@@ -631,13 +631,17 @@ extern dlevel_t level; /* structure describing the current level */
(level.monsters[x][y] != (struct monst *) 0 \
&& (level.monsters[x][y])->mburied)
#ifdef EXTRA_SANITY_CHECKS
#define place_worm_seg(m, x, y) do { \
if (level.monsters[x][y] && level.monsters[x][y] != m) impossible("place_worm_seg over mon"); \
level.monsters[x][y] = m; \
#define place_worm_seg(m, x, y) \
do { \
if (level.monsters[x][y] && level.monsters[x][y] != m) \
impossible("place_worm_seg over mon"); \
level.monsters[x][y] = m; \
} while(0)
#define remove_monster(x, y) do { \
if (!level.monsters[x][y]) impossible("no monster to remove"); \
level.monsters[x][y] = (struct monst *) 0; \
#define remove_monster(x, y) \
do { \
if (!level.monsters[x][y]) \
impossible("no monster to remove"); \
level.monsters[x][y] = (struct monst *) 0; \
} while(0)
#else
#define place_worm_seg(m, x, y) level.monsters[x][y] = m

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 do.c $NHDT-Date: 1542765356 2018/11/21 01:55:56 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.174 $ */
/* NetHack 3.6 do.c $NHDT-Date: 1543052696 2018/11/24 09:44:56 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.175 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1446,10 +1446,9 @@ boolean at_stairs, falling, portal;
with the situation, so only say something when debugging */
if (wizard)
pline("(monster in hero's way)");
if (!rloc(mtmp, TRUE) || m_at(u.ux, u.uy))
if (!rloc(mtmp, TRUE) || (mtmp = m_at(u.ux, u.uy)) != 0)
/* no room to move it; send it away, to return later */
migrate_to_level(mtmp, ledger_no(&u.uz), MIGR_RANDOM,
(coord *) 0);
m_into_limbo(mtmp);
}
}

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 dog.c $NHDT-Date: 1502753406 2017/08/14 23:30:06 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.60 $ */
/* NetHack 3.6 dog.c $NHDT-Date: 1543052701 2018/11/24 09:45:01 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.84 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */
@@ -224,7 +224,7 @@ update_mlstmv()
void
losedogs()
{
register struct monst *mtmp, *mtmp0 = 0, *mtmp2;
register struct monst *mtmp, *mtmp0, *mtmp2;
int dismissKops = 0;
/*
@@ -279,17 +279,26 @@ losedogs()
mon_arrive(mtmp, TRUE);
}
/* time for migrating monsters to arrive */
/* time for migrating monsters to arrive;
monsters who belong on this level but fail to arrive get put
back onto the list (at head), so traversing it is tricky */
for (mtmp = migrating_mons; mtmp; mtmp = mtmp2) {
mtmp2 = mtmp->nmon;
if (mtmp->mux == u.uz.dnum && mtmp->muy == u.uz.dlevel) {
if (mtmp == migrating_mons)
/* remove mtmp from migrating_mons list */
if (mtmp == migrating_mons) {
migrating_mons = mtmp->nmon;
else
mtmp0->nmon = mtmp->nmon;
} else {
for (mtmp0 = migrating_mons; mtmp0; mtmp0 = mtmp0->nmon)
if (mtmp0->nmon == mtmp) {
mtmp0->nmon = mtmp->nmon;
break;
}
if (!mtmp0)
panic("losedogs: can't find migrating mon");
}
mon_arrive(mtmp, FALSE);
} else
mtmp0 = mtmp;
}
}
}
@@ -300,9 +309,9 @@ struct monst *mtmp;
boolean with_you;
{
struct trap *t;
struct obj *obj;
xchar xlocale, ylocale, xyloc, xyflags, wander;
int num_segs;
boolean failed_to_place = FALSE;
mtmp->nmon = fmon;
fmon = mtmp;
@@ -328,7 +337,7 @@ boolean with_you;
xyflags = mtmp->mtrack[0].y;
xlocale = mtmp->mtrack[1].x;
ylocale = mtmp->mtrack[1].y;
memset(mtmp->mtrack, 0, sizeof(mtmp->mtrack));
memset(mtmp->mtrack, 0, sizeof mtmp->mtrack);
if (mtmp == u.usteed)
return; /* don't place steed on the map */
@@ -447,47 +456,13 @@ boolean with_you;
mtmp->mx = 0; /*(already is 0)*/
mtmp->my = xyflags;
if (xlocale) {
if (!mnearto(mtmp, xlocale, ylocale, FALSE))
goto fail_mon_placement;
} else {
if (!rloc(mtmp, TRUE)) {
/*
* Failed to place migrating monster,
* probably because the level is full.
* Dump the monster's cargo and leave the monster dead.
*
* TODO? Put back on migrating_mons list instead so
* that if hero leaves this level and then returns,
* monster will have another chance to arrive.
*/
fail_mon_placement:
while ((obj = mtmp->minvent) != 0) {
obj_extract_self(obj);
obj_no_longer_held(obj);
if (obj->owornmask & W_WEP)
setmnotwielded(mtmp, obj);
obj->owornmask = 0L;
if (xlocale && ylocale)
place_object(obj, xlocale, ylocale);
else if (rloco(obj)) {
if (!get_obj_location(obj, &xlocale, &ylocale, 0))
impossible("Can't find relocated object.");
}
}
/*
* TODO? Maybe switch to make_corpse() [won't be needed if
* we re-migrate as suggested above], probably with new
* CORPSTAT_NOOBJS flag to suppress dragon scales and such.
*/
if (!(mvitals[monsndx(mtmp->data)].mvflags & G_NOCORPSE)
&& !LEVEL_SPECIFIC_NOCORPSE(mtmp->data))
(void) mkcorpstat(CORPSE, mtmp, mtmp->data,
xlocale, ylocale, CORPSTAT_NONE);
mtmp->mx = mtmp->my = 0; /* for mongone, mon is not anywhere */
mongone(mtmp);
}
}
if (xlocale)
failed_to_place = !mnearto(mtmp, xlocale, ylocale, FALSE);
else
failed_to_place = !rloc(mtmp, TRUE);
if (failed_to_place)
m_into_limbo(mtmp); /* try again next time hero comes to this level */
}
/* heal monster for time spent elsewhere */
@@ -708,7 +683,7 @@ xchar tolev; /* destination level */
xchar xyloc; /* MIGR_xxx destination xy location: */
coord *cc; /* optional destination coordinates */
{
register struct obj *obj;
struct obj *obj;
d_level new_lev;
xchar xyflags;
int num_segs = 0; /* count of worm segments */
@@ -717,12 +692,12 @@ coord *cc; /* optional destination coordinates */
set_residency(mtmp, TRUE);
if (mtmp->wormno) {
register int cnt;
int cnt = count_wsegs(mtmp);
/* **** NOTE: worm is truncated to # segs = max wormno size **** */
cnt = count_wsegs(mtmp);
num_segs = min(cnt, MAX_NUM_WORMS - 1);
wormgone(mtmp);
place_monster(mtmp, mtmp->mx, mtmp->my);
num_segs = min(cnt, MAX_NUM_WORMS - 1); /* used below */
wormgone(mtmp); /* destroys tail and takes head off map */
place_monster(mtmp, mtmp->mx, mtmp->my); /* put head back for relmon */
}
/* set minvent's obj->no_charge to 0 */
@@ -755,7 +730,7 @@ coord *cc; /* optional destination coordinates */
mtmp->muy = new_lev.dlevel;
mtmp->mx = mtmp->my = 0; /* this implies migration */
if (mtmp == context.polearm.hitmon)
context.polearm.hitmon = NULL;
context.polearm.hitmon = (struct monst *) 0;
}
/* return quality of food; the lower the better */

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mon.c $NHDT-Date: 1539479657 2018/10/14 01:14:17 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.260 $ */
/* NetHack 3.6 mon.c $NHDT-Date: 1543052701 2018/11/24 09:45:01 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.270 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1618,8 +1618,9 @@ struct monst *mon;
struct monst **monst_list; /* &migrating_mons or &mydogs or null */
{
struct monst *mtmp;
boolean unhide = (monst_list != 0);
int mx = mon->mx, my = mon->my;
boolean on_map = (m_at(mx, my) == mon),
unhide = (monst_list != 0);
if (!fmon)
panic("relmon: no fmon available.");
@@ -1633,10 +1634,12 @@ struct monst **monst_list; /* &migrating_mons or &mydogs or null */
seemimic(mon);
}
if (mon->wormno)
remove_worm(mon);
else
remove_monster(mx, my);
if (on_map) {
if (mon->wormno)
remove_worm(mon);
else
remove_monster(mx, my);
}
if (mon == fmon) {
fmon = fmon->nmon;
@@ -1652,7 +1655,8 @@ struct monst **monst_list; /* &migrating_mons or &mydogs or null */
}
if (unhide) {
newsym(mx, my);
if (on_map)
newsym(mx, my);
/* insert into mydogs or migrating_mons */
mon->nmon = *monst_list;
*monst_list = mon;
@@ -2515,7 +2519,7 @@ struct monst *mtmp;
{
unstuck(mtmp);
mdrop_special_objs(mtmp);
migrate_to_level(mtmp, ledger_no(&u.uz), MIGR_APPROX_XY, NULL);
migrate_to_level(mtmp, ledger_no(&u.uz), MIGR_APPROX_XY, (coord *) 0);
}
/* make monster mtmp next to you (if possible);