eliminate one more source of vault guard newsym msgs
see_monsters() was producing spurious vault guard at 0,0
messages
Reproduce issue by:
1. Entering vault via teleport.
2. Wait for guard to enter.
3. Drop gold (if necessary) and follow guard.
4. Right after the guard disappears, but before
the corridor does, the following can lead to
the messages:
a) control-R to refresh the display.
or
b) save the game and restore.
In both cases, see_monsters() will get called and lead
to the spurious messages for the vault guard that is
parked.
Also, add a macro PARKEDMONSTER(mon) instead of checking the
the isgd bit and the value of mon->mx being zero in multiple
places
Also, adds MON_PARKED bit to mstate.
Currently the PARKEDMONSTER(mon) macro mentioned above,
does not use the new bit.
This commit is contained in:
+15
-10
@@ -55,16 +55,17 @@ enum m_ap_types {
|
||||
M_AP_MONSTER = 3 /* a monster; mostly used for cloned Wizard */
|
||||
};
|
||||
|
||||
#define MON_FLOOR 0x00
|
||||
#define MON_OFFMAP 0x01
|
||||
#define MON_DETACH 0x02
|
||||
#define MON_MIGRATING 0x04
|
||||
#define MON_LIMBO 0x08
|
||||
#define MON_BUBBLEMOVE 0x10
|
||||
#define MON_ENDGAME_FREE 0x20
|
||||
#define MON_ENDGAME_MIGR 0x40
|
||||
#define MON_OBLITERATE 0x80
|
||||
#define MON_STILL_ARRIVING 0x100
|
||||
#define MON_FLOOR 0x0000
|
||||
#define MON_OFFMAP 0x0001
|
||||
#define MON_DETACH 0x0002
|
||||
#define MON_MIGRATING 0x0004
|
||||
#define MON_LIMBO 0x0008
|
||||
#define MON_BUBBLEMOVE 0x0010
|
||||
#define MON_ENDGAME_FREE 0x0020
|
||||
#define MON_ENDGAME_MIGR 0x0040
|
||||
#define MON_OBLITERATE 0x0080
|
||||
#define MON_STILL_ARRIVING 0x0100
|
||||
#define MON_PARKED 0x0200
|
||||
|
||||
#define M_AP_TYPMASK 0x7
|
||||
#define M_AP_F_DKNOWN 0x8
|
||||
@@ -212,6 +213,10 @@ struct monst {
|
||||
|
||||
/* dead monsters stay on the fmon list until dmonsfree() at end of turn */
|
||||
#define DEADMONSTER(mon) ((mon)->mhp < 1)
|
||||
/* vault guards intentionally remain on the fmon list at 0,0 until
|
||||
the temporary corridor is dealt with */
|
||||
#define PARKEDMONSTER(mon) ((mon)->isgd && (mon)->mx == 0)
|
||||
/* eventually, we'll be able to use (((mon)->mstate & MON_PARKED) != 0) */
|
||||
|
||||
#define is_starting_pet(mon) ((mon)->m_id == svc.context.startingpet_mid)
|
||||
#define is_vampshifter(mon) \
|
||||
|
||||
+11
-11
@@ -345,7 +345,7 @@ gold_detect(struct obj *sobj)
|
||||
|
||||
/* look for gold carried by monsters (might be in a container) */
|
||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||
if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx))
|
||||
if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp))
|
||||
continue;
|
||||
if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) {
|
||||
if (mtmp == u.usteed) {
|
||||
@@ -433,7 +433,7 @@ gold_detect(struct obj *sobj)
|
||||
ugold = TRUE;
|
||||
}
|
||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||
if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx))
|
||||
if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp))
|
||||
continue;
|
||||
temp = 0;
|
||||
if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) {
|
||||
@@ -497,7 +497,7 @@ food_detect(struct obj *sobj)
|
||||
ct++;
|
||||
}
|
||||
for (mtmp = fmon; mtmp && (!ct || !ctu); mtmp = mtmp->nmon) {
|
||||
if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx))
|
||||
if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp))
|
||||
continue;
|
||||
for (obj = mtmp->minvent; obj; obj = obj->nobj)
|
||||
if (o_in(obj, oclass)) {
|
||||
@@ -561,7 +561,7 @@ food_detect(struct obj *sobj)
|
||||
map_object(temp, 1);
|
||||
}
|
||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||
if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx))
|
||||
if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp))
|
||||
continue;
|
||||
for (obj = mtmp->minvent; obj; obj = obj->nobj)
|
||||
if ((temp = o_in(obj, oclass)) != 0) {
|
||||
@@ -666,7 +666,7 @@ object_detect(struct obj *detector, /* object doing the detecting */
|
||||
u.usteed->mx = u.ux, u.usteed->my = u.uy;
|
||||
|
||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||
if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx))
|
||||
if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp))
|
||||
continue;
|
||||
for (obj = mtmp->minvent; obj; obj = obj->nobj) {
|
||||
if ((!class && !boulder) || o_in(obj, class)
|
||||
@@ -736,7 +736,7 @@ object_detect(struct obj *detector, /* object doing the detecting */
|
||||
|
||||
/* Objects in the monster's inventory override floor objects. */
|
||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||
if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx))
|
||||
if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp))
|
||||
continue;
|
||||
for (obj = mtmp->minvent; obj; obj = obj->nobj)
|
||||
if ((!class && !boulder) || (otmp = o_in(obj, class)) != 0
|
||||
@@ -807,7 +807,7 @@ monster_detect(struct obj *otmp, /* detecting object (if any) */
|
||||
* with positive hit-points to know for sure.
|
||||
*/
|
||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||
if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx))
|
||||
if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp))
|
||||
continue;
|
||||
++mcnt;
|
||||
break; /* no need for full count, just 1 or more vs 0 */
|
||||
@@ -826,7 +826,7 @@ monster_detect(struct obj *otmp, /* detecting object (if any) */
|
||||
cls();
|
||||
unconstrained = unconstrain_map();
|
||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||
if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx))
|
||||
if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp))
|
||||
continue;
|
||||
if (!mclass || mtmp->data->mlet == mclass
|
||||
|| (mtmp->data == &mons[PM_LONG_WORM]
|
||||
@@ -969,7 +969,7 @@ display_trap_map(int cursed_src)
|
||||
(void) detect_obj_traps(svl.level.buriedobjlist, TRUE, cursed_src, NULL);
|
||||
(void) detect_obj_traps(fobj, TRUE, cursed_src, NULL);
|
||||
for (mon = fmon; mon; mon = mon->nmon) {
|
||||
if (DEADMONSTER(mon) || (mon->isgd && !mon->mx))
|
||||
if (DEADMONSTER(mon) || PARKEDMONSTER(mon))
|
||||
continue;
|
||||
(void) detect_obj_traps(mon->minvent, TRUE, cursed_src, NULL);
|
||||
}
|
||||
@@ -1046,7 +1046,7 @@ trap_detect(
|
||||
found = TRUE;
|
||||
}
|
||||
for (mon = fmon; mon; mon = mon->nmon) {
|
||||
if (DEADMONSTER(mon) || (mon->isgd && !mon->mx))
|
||||
if (DEADMONSTER(mon) || PARKEDMONSTER(mon))
|
||||
continue;
|
||||
if ((tr = detect_obj_traps(mon->minvent, FALSE, 0, NULL))
|
||||
!= OTRAP_NONE) {
|
||||
@@ -1643,7 +1643,7 @@ findone(coordxy zx, coordxy zy, genericptr_t whatfound)
|
||||
struct monst *mtmp = m_at(zx, zy);
|
||||
struct found_things *found_p = (struct found_things *) whatfound;
|
||||
|
||||
if (mtmp && (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)))
|
||||
if (mtmp && (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp)))
|
||||
mtmp = (struct monst *) NULL;
|
||||
found_p->ft_cc.x = zx; /* needed by detect_obj_traps() */
|
||||
found_p->ft_cc.y = zy;
|
||||
|
||||
+1
-1
@@ -1544,7 +1544,7 @@ see_monsters(void)
|
||||
|
||||
/* loop through level.monsters (aka fmon) */
|
||||
for (mon = fmon; mon; mon = mon->nmon) {
|
||||
if (DEADMONSTER(mon))
|
||||
if (DEADMONSTER(mon) || PARKEDMONSTER(mon))
|
||||
continue;
|
||||
if ((mon->mstate & MON_STILL_ARRIVING) != 0)
|
||||
continue;
|
||||
|
||||
+2
-2
@@ -303,7 +303,7 @@ show_transient_light(struct obj *obj, coordxy x, coordxy y)
|
||||
|
||||
radius_squared = ls->range * ls->range;
|
||||
for (mon = fmon; mon; mon = mon->nmon) {
|
||||
if (DEADMONSTER(mon) || (mon->isgd && !mon->mx))
|
||||
if (DEADMONSTER(mon) || PARKEDMONSTER(mon))
|
||||
continue;
|
||||
/* light range is the radius of a circle and we're limiting
|
||||
canseemon() to a square enclosing that circle, but setting
|
||||
@@ -343,7 +343,7 @@ transient_light_cleanup(void)
|
||||
so need to be replaced by "remembered, unseen monster" glyph */
|
||||
mtempcount = 0;
|
||||
for (mon = fmon; mon; mon = mon->nmon) {
|
||||
if (DEADMONSTER(mon))
|
||||
if (DEADMONSTER(mon) || PARKEDMONSTER(mon))
|
||||
continue;
|
||||
if (mon->mtemplit) {
|
||||
mon->mtemplit = 0;
|
||||
|
||||
+1
-3
@@ -43,9 +43,7 @@ monster_census(boolean spotted) /* seen|sensed vs all */
|
||||
int count = 0;
|
||||
|
||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||
if (DEADMONSTER(mtmp))
|
||||
continue;
|
||||
if (mtmp->isgd && mtmp->mx == 0)
|
||||
if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp))
|
||||
continue;
|
||||
if (spotted && !canspotmon(mtmp))
|
||||
continue;
|
||||
|
||||
@@ -1230,7 +1230,7 @@ movemon_singlemon(struct monst *mtmp)
|
||||
off the map too; gd_move() decides whether the temporary
|
||||
corridor can be removed and guard discarded (via clearing
|
||||
mon->isgd flag so that dmonsfree() will get rid of mon) */
|
||||
if (mtmp->isgd && !mtmp->mx && !(mtmp->mstate & MON_MIGRATING)) {
|
||||
if (PARKEDMONSTER(mtmp) && !(mtmp->mstate & MON_MIGRATING)) {
|
||||
/* parked at <0,0>; eventually isgd should get set to false */
|
||||
if (svm.moves > mtmp->mlstmv) {
|
||||
(void) gd_move(mtmp);
|
||||
|
||||
+1
-1
@@ -922,7 +922,7 @@ dochug(struct monst *mtmp)
|
||||
/*FALLTHRU*/
|
||||
case MMOVE_NOTHING: /* no movement, but it can still attack you */
|
||||
case MMOVE_DONE: /* absolutely no movement */
|
||||
/* vault guard might have vanished */
|
||||
/* vault guard might have vanished; PARKEDMONSTER(mtmp) */
|
||||
if (mtmp->isgd && (DEADMONSTER(mtmp) || mtmp->mx == 0))
|
||||
return 1; /* behave as if it died */
|
||||
/* During hallucination, monster appearance should
|
||||
|
||||
@@ -448,6 +448,13 @@ restmonchn(NHFILE *nhfp)
|
||||
restshk(mtmp, ghostly);
|
||||
if (mtmp->ispriest)
|
||||
restpriest(mtmp, ghostly);
|
||||
if (mtmp->isgd) {
|
||||
/* fixup for new bit MON_PARKED added post 5.0.0 */
|
||||
if (!mtmp->mx
|
||||
&& (mtmp->mstate & MON_PARKED) == 0L
|
||||
&& (mtmp->mstate & MON_MIGRATING) == 0L)
|
||||
mtmp->mstate |= MON_PARKED;
|
||||
}
|
||||
|
||||
if (!ghostly) {
|
||||
if (mtmp->m_id == svc.context.polearm.m_id)
|
||||
|
||||
+16
-4
@@ -903,8 +903,10 @@ place_monster(struct monst *mon, coordxy x, coordxy y)
|
||||
|
||||
buf[0] = '\0';
|
||||
/* normal map bounds are <1..COLNO-1,0..ROWNO-1> but sometimes
|
||||
vault guards (either living or dead) are parked at <0,0> */
|
||||
if (!isok(x, y) && (x != 0 || y != 0 || !mon->isgd)) {
|
||||
vault guards (either living or dead) are parked at <0,0>;
|
||||
their mstate should have the MON_PARKED bit set (post-5.0.0) */
|
||||
if (!isok(x, y)
|
||||
&& !(((mon->mstate & MON_PARKED) != 0) || PARKEDMONSTER(mon))) {
|
||||
describe_level(buf, 0);
|
||||
impossible("trying to place %s at <%d,%d> mstate:%lx on %s",
|
||||
minimal_monnam(mon, TRUE), x, y, mon->mstate, buf);
|
||||
@@ -912,7 +914,7 @@ place_monster(struct monst *mon, coordxy x, coordxy y)
|
||||
}
|
||||
if ((mon == u.usteed && !gi.in_steed_dismounting)
|
||||
/* special case is for convoluted vault guard handling */
|
||||
|| (DEADMONSTER(mon) && !(mon->isgd && x == 0 && y == 0))) {
|
||||
|| (DEADMONSTER(mon) && !PARKEDMONSTER(mon))) {
|
||||
describe_level(buf, 0);
|
||||
impossible("placing %s onto map, mstate:%lx, on %s?",
|
||||
(mon == u.usteed) ? "steed" : "defunct monster",
|
||||
@@ -928,7 +930,17 @@ place_monster(struct monst *mon, coordxy x, coordxy y)
|
||||
}
|
||||
mon->mx = x, mon->my = y;
|
||||
svl.level.monsters[x][y] = mon;
|
||||
mon->mstate = MON_FLOOR;
|
||||
/* even though MON_FLOOR is not actually a bit currently
|
||||
(MON_FLOOR == 0) we want to preserve some of the other
|
||||
bits that may be set. We'll probably make MON_FLOOR an
|
||||
actual bit one day */
|
||||
|
||||
mon->mstate &= ~(MON_OFFMAP | MON_DETACH | MON_LIMBO | MON_MIGRATING);
|
||||
|
||||
/* We don't mess with these bits above:
|
||||
MON_BUBBLEMOVE | MON_ENDGAME_FREE | MON_ENDGAME_MIGR
|
||||
| MON_OBLITERATE | MON_STILL_ARRIVING | MON_PARKED
|
||||
*/
|
||||
}
|
||||
|
||||
/*steed.c*/
|
||||
|
||||
+4
-1
@@ -146,6 +146,7 @@ restfakecorr(struct monst *grd)
|
||||
/* it seems you left the corridor - let the guard disappear */
|
||||
if (clear_fcorr(grd, FALSE)) {
|
||||
grd->isgd = 0; /* dmonsfree() should delete this mon */
|
||||
grd->mstate &= ~MON_PARKED;
|
||||
mongone(grd);
|
||||
}
|
||||
}
|
||||
@@ -162,8 +163,10 @@ parkguard(struct monst *grd)
|
||||
remove_monster(grd->mx, grd->my);
|
||||
newsym(grd->mx, grd->my);
|
||||
}
|
||||
if (m_at(0, 0) != grd)
|
||||
if (m_at(0, 0) != grd) {
|
||||
grd->mstate |= MON_PARKED;
|
||||
place_monster(grd, 0, 0);
|
||||
}
|
||||
/* [grd->mx,my just got set to 0,0 by place_monster(), so this
|
||||
just sets EGD(grd)->ogx,ogy to 0,0 too; is that what we want?] */
|
||||
EGD(grd)->ogx = grd->mx;
|
||||
|
||||
@@ -98,6 +98,7 @@ makemap_unmakemon(struct monst *mtmp, boolean migratory)
|
||||
mongone() -> m_detach() -> mon_leaving_level() copes with that */
|
||||
mtmp->mstate |= MON_OFFMAP;
|
||||
mtmp->mstate &= ~(MON_MIGRATING | MON_LIMBO | MON_ENDGAME_MIGR);
|
||||
/* FIXME: will post-5.0.0 MON_PARKED need to be dealt with here? */
|
||||
mtmp->nmon = fmon;
|
||||
fmon = mtmp;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user