fix stone-to-flesh on petrified long worm
montraits() didn't have any handling for long worm tails, makemon() didn't have any provision for creating a long worm without a tail, replmon() uses place_wegs() to put tail segments on the map when replacing a dummy new monster with the mtraits one but place_wsegs() wasn't updating the head segment since it isn't put on the map. That turned out to be key because there is always an extra segment co-located with the monster and when its coordinates were wrong, worm_known() gave bad results for visibility checking. The statue-goes-away message was the one for not being able to see the monster that it just animated into, even though 'w' appeared at the spot. It took quite a while to track down what was going on there. Sanity checking for worms has been updated and could conceivably start triggering complaints about things that it used ignore.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.228 $ $NHDT-Date: 1591017415 2020/06/01 13:16:55 $
|
||||
$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.229 $ $NHDT-Date: 1591178395 2020/06/03 09:59:55 $
|
||||
|
||||
General Fixes and Modified Features
|
||||
-----------------------------------
|
||||
@@ -192,6 +192,8 @@ change mkclass() to usually honor (always honor for L class) the hell-only and
|
||||
(nor master lich there unless demilich gets a potion of gain level)
|
||||
thieving monster could be killed while hero was removing armor, triggering
|
||||
warning "stealarm(): dead monster stealing" when taking-off finished
|
||||
petrifying a long worm and then reanimating it handled tail incorrectly;
|
||||
with sanity_check On, X coordinate of head segment was reported as 0
|
||||
|
||||
|
||||
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 hack.h $NHDT-Date: 1580600495 2020/02/01 23:41:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.128 $ */
|
||||
/* NetHack 3.6 hack.h $NHDT-Date: 1591178395 2020/06/03 09:59:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.138 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Pasi Kallinen, 2017. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -305,10 +305,11 @@ typedef struct sortloot_item Loot;
|
||||
#define MM_EDOG 0x001000L /* add edog structure */
|
||||
#define MM_ASLEEP 0x002000L /* monsters should be generated asleep */
|
||||
#define MM_NOGRP 0x004000L /* suppress creation of monster groups */
|
||||
#define MM_NOTAIL 0x008000L /* if a long worm, don't give it a tail */
|
||||
/* if more MM_ flag masks are added, skip or renumber the GP_ one(s) */
|
||||
#define GP_ALLOW_XY 0x008000L /* [actually used by enexto() to decide whether
|
||||
#define GP_ALLOW_XY 0x010000L /* [actually used by enexto() to decide whether
|
||||
* to make an extra call to goodpos()] */
|
||||
#define GP_ALLOW_U 0x010000L /* don't reject hero's location */
|
||||
#define GP_ALLOW_U 0x020000L /* don't reject hero's location */
|
||||
|
||||
/* flags for make_corpse() and mkcorpstat() */
|
||||
#define CORPSTAT_NONE 0x00
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 makemon.c $NHDT-Date: 1590879611 2020/05/30 23:00:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.172 $ */
|
||||
/* NetHack 3.6 makemon.c $NHDT-Date: 1591178397 2020/06/03 09:59:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.173 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1124,10 +1124,11 @@ long mmflags;
|
||||
struct monst fakemon;
|
||||
coord cc;
|
||||
int mndx, mcham, ct, mitem;
|
||||
boolean anymon = (!ptr);
|
||||
boolean byyou = (x == u.ux && y == u.uy);
|
||||
boolean allow_minvent = ((mmflags & NO_MINVENT) == 0);
|
||||
boolean countbirth = ((mmflags & MM_NOCOUNTBIRTH) == 0);
|
||||
boolean anymon = !ptr,
|
||||
byyou = (x == u.ux && y == u.uy),
|
||||
allow_minvent = ((mmflags & NO_MINVENT) == 0),
|
||||
countbirth = ((mmflags & MM_NOCOUNTBIRTH) == 0),
|
||||
allowtail = ((mmflags & MM_NOTAIL) == 0);
|
||||
unsigned gpflags = (mmflags & MM_IGNOREWATER) ? MM_IGNOREWATER : 0;
|
||||
|
||||
fakemon = cg.zeromonst;
|
||||
@@ -1348,7 +1349,7 @@ long mmflags;
|
||||
mtmp->mpeaceful = mtmp->mtame = FALSE;
|
||||
}
|
||||
if (mndx == PM_LONG_WORM && (mtmp->wormno = get_wormno()) != 0) {
|
||||
initworm(mtmp, rn2(5));
|
||||
initworm(mtmp, allowtail ? rn2(5) : 0);
|
||||
if (count_wsegs(mtmp))
|
||||
place_worm_tail_randomly(mtmp, x, y);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 mkobj.c $NHDT-Date: 1590870787 2020/05/30 20:33:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.179 $ */
|
||||
/* NetHack 3.6 mkobj.c $NHDT-Date: 1591178399 2020/06/03 09:59:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.180 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Derek S. Ray, 2015. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1597,6 +1597,9 @@ struct monst *mtmp;
|
||||
mtmp2->minvent = (struct obj *) 0;
|
||||
if (mtmp->mextra)
|
||||
copy_mextra(mtmp2, mtmp);
|
||||
/* if mtmp is a long worm with segments, its saved traits will
|
||||
be one without any segments */
|
||||
mtmp2->wormno = 0;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
90
src/worm.c
90
src/worm.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 worm.c $NHDT-Date: 1580633722 2020/02/02 08:55:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.43 $ */
|
||||
/* NetHack 3.6 worm.c $NHDT-Date: 1591178400 2020/06/03 10:00:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.45 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2009. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -126,9 +126,9 @@ int wseg_count;
|
||||
} else {
|
||||
wtails[wnum] = wheads[wnum] = seg = newseg();
|
||||
seg->nseg = (struct wseg *) 0;
|
||||
seg->wx = worm->mx;
|
||||
seg->wy = worm->my;
|
||||
}
|
||||
seg->wx = worm->mx;
|
||||
seg->wy = worm->my;
|
||||
wgrowtime[wnum] = 0L;
|
||||
}
|
||||
|
||||
@@ -144,14 +144,13 @@ toss_wsegs(curr, display_update)
|
||||
struct wseg *curr;
|
||||
boolean display_update;
|
||||
{
|
||||
struct wseg *seg;
|
||||
struct wseg *nxtseg;
|
||||
|
||||
while (curr) {
|
||||
seg = curr->nseg;
|
||||
nxtseg = curr->nseg;
|
||||
|
||||
/* remove from level.monsters[][] */
|
||||
|
||||
/* need to check curr->wx for genocided while migrating_mon */
|
||||
/* remove from level.monsters[][];
|
||||
need to check curr->wx for genocided while migrating_mon */
|
||||
if (curr->wx) {
|
||||
remove_monster(curr->wx, curr->wy);
|
||||
|
||||
@@ -162,7 +161,7 @@ boolean display_update;
|
||||
|
||||
/* free memory used by the segment */
|
||||
dealloc_seg(curr);
|
||||
curr = seg;
|
||||
curr = nxtseg;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,7 +312,6 @@ struct monst *worm;
|
||||
int wnum = worm->wormno;
|
||||
|
||||
worm->wormno = 0;
|
||||
|
||||
/* This will also remove the real monster (ie 'w') from the its
|
||||
* position in level.monsters[][].
|
||||
*/
|
||||
@@ -505,11 +503,9 @@ boolean use_detection_glyph;
|
||||
int what_tail = what_mon(PM_LONG_WORM_TAIL, newsym_rn2);
|
||||
|
||||
while (curr != wheads[worm->wormno]) {
|
||||
num = use_detection_glyph
|
||||
? detected_monnum_to_glyph(what_tail)
|
||||
: (worm->mtame
|
||||
? petnum_to_glyph(what_tail)
|
||||
: monnum_to_glyph(what_tail));
|
||||
num = use_detection_glyph ? detected_monnum_to_glyph(what_tail)
|
||||
: worm->mtame ? petnum_to_glyph(what_tail)
|
||||
: monnum_to_glyph(what_tail);
|
||||
show_glyph(curr->wx, curr->wy, num);
|
||||
curr = curr->nseg;
|
||||
}
|
||||
@@ -612,6 +608,7 @@ NHFILE *nhfp;
|
||||
* place_wsegs()
|
||||
*
|
||||
* Place the segments of the given worm. Called from restore.c
|
||||
* and from replmon() in mon.c.
|
||||
* If oldworm is not NULL, assumes the oldworm segments are on map
|
||||
* in the same location as worm segments
|
||||
*/
|
||||
@@ -622,40 +619,63 @@ struct monst *worm, *oldworm;
|
||||
struct wseg *curr = wtails[worm->wormno];
|
||||
|
||||
while (curr != wheads[worm->wormno]) {
|
||||
xchar x = curr->wx;
|
||||
xchar y = curr->wy;
|
||||
xchar x = curr->wx, y = curr->wy;
|
||||
struct monst *mtmp = m_at(x, y);
|
||||
|
||||
if (oldworm && mtmp == oldworm)
|
||||
remove_monster(x, y);
|
||||
else if (mtmp)
|
||||
impossible("placing worm seg <%d,%d> over another mon", x, y);
|
||||
else if (oldworm)
|
||||
impossible("replacing worm seg <%d,%d> on empty spot", x, y);
|
||||
|
||||
if (oldworm) {
|
||||
if (m_at(x,y) == oldworm)
|
||||
remove_monster(x, y);
|
||||
else
|
||||
impossible("placing worm seg <%i,%i> over another mon", x, y);
|
||||
}
|
||||
place_worm_seg(worm, x, y);
|
||||
curr = curr->nseg;
|
||||
}
|
||||
/* head segment is co-located with worm itself so not placed on the map */
|
||||
curr->wx = worm->mx, curr->wy = worm->my;
|
||||
}
|
||||
|
||||
/* called from mon_sanity_check(mon.c) */
|
||||
void
|
||||
sanity_check_worm(worm)
|
||||
struct monst *worm;
|
||||
{
|
||||
struct wseg *curr;
|
||||
int wnum, x, y;
|
||||
|
||||
if (!worm)
|
||||
panic("no worm!");
|
||||
if (!worm->wormno)
|
||||
panic("not a worm?!");
|
||||
if (!worm) {
|
||||
impossible("worm_sanity: null monster!");
|
||||
return;
|
||||
}
|
||||
/* note: wormno can't be less than 0 (unsigned bit field) and can't
|
||||
be greater that MAX_NUM_WORMS - 1 (which uses all available bits)
|
||||
so checking for 0 is all we can manage for wormno validation;
|
||||
since caller has already done that, this is rather pointless... */
|
||||
if (!worm->wormno) {
|
||||
impossible("worm_sanity: not a worm!");
|
||||
return;
|
||||
}
|
||||
|
||||
curr = wtails[worm->wormno];
|
||||
wnum = worm->wormno;
|
||||
if (!wtails[wnum] || !wheads[wnum]) {
|
||||
impossible("wormno %d is set without proper tail", wnum);
|
||||
return;
|
||||
}
|
||||
/* if worm is migrating, we can't check its segments against the map */
|
||||
if (!worm->mx)
|
||||
return;
|
||||
|
||||
curr = wtails[wnum];
|
||||
while (curr != wheads[wnum]) {
|
||||
x = curr->wx, y = curr->wy;
|
||||
if (!isok(x, y))
|
||||
impossible("worm seg not isok <%d,%d>", x, y);
|
||||
else if (g.level.monsters[x][y] != worm)
|
||||
impossible("mon (%s) at seg location is not worm (%s)",
|
||||
fmt_ptr((genericptr_t) g.level.monsters[x][y]),
|
||||
fmt_ptr((genericptr_t) worm));
|
||||
|
||||
while (curr != wheads[worm->wormno]) {
|
||||
if (curr->wx) {
|
||||
if (!isok(curr->wx, curr->wy))
|
||||
panic("worm seg not isok");
|
||||
if (g.level.monsters[curr->wx][curr->wy] != worm)
|
||||
panic("worm not at seg location");
|
||||
}
|
||||
curr = curr->nseg;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 zap.c $NHDT-Date: 1589491666 2020/05/14 21:27:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.340 $ */
|
||||
/* NetHack 3.6 zap.c $NHDT-Date: 1591178401 2020/06/03 10:00:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.341 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2013. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -586,6 +586,11 @@ boolean adjacentok; /* False: at obj's spot only, True: nearby is allowed */
|
||||
return (struct monst *) 0;
|
||||
mtmp = makemon(mtmp2->data, cc->x, cc->y,
|
||||
(NO_MINVENT | MM_NOWAIT | MM_NOCOUNTBIRTH
|
||||
/* in case mtmp2 is a long worm; saved traits for
|
||||
long worm don't include tail segments so don't
|
||||
give mtmp any; it will be given a new 'wormno'
|
||||
though unless those are exhausted */
|
||||
| MM_NOTAIL
|
||||
| (adjacentok ? MM_ADJACENTOK : 0)));
|
||||
if (!mtmp) {
|
||||
/* mtmp2 is a copy of obj's object->oextra->omonst extension
|
||||
|
||||
Reference in New Issue
Block a user