detection bugs when vault guard is at <0,0>

Monster detection skipped dead monsters during fmon traversal but
found semi-dead guard parked at <0,0> waiting to remove temporary
vault corridor.  If that happened to be the only monster found then
the feedback was incorrect (a blank map showing no found monsters
instead of a strange feeling).  Object detection found semi-dead
guard's inventory and might report incorrectly too although the
chance of that being the only objects found on the level is a lot
less than it being the only monster.
This commit is contained in:
PatR
2020-04-20 16:11:47 -07:00
parent 5ec96751ba
commit ca4e729216
2 changed files with 26 additions and 19 deletions

View File

@@ -151,6 +151,10 @@ wishing for werecreature figurine always made one that created the monster in
wishing for "royal jelly" yielded "lump of royal jelly" as a special case, but wishing for "royal jelly" yielded "lump of royal jelly" as a special case, but
other 'of' items such as "clove of garlic", "sprig of wolfsbane", or other 'of' items such as "clove of garlic", "sprig of wolfsbane", or
"piece of cloth" didn't allow using their post-of words as shorthand "piece of cloth" didn't allow using their post-of words as shorthand
monster or object detection found semi-dead vault guard at <0,0> while
traversing fmon list; monster detection gave misleading feedback
(blank map instead of 'strange feeling') if there were no other
monsters on level; likewise object detection and guard's minvent
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository Fixes to 3.7.0-x Problems that Were Exposed Via git Repository

View File

@@ -312,8 +312,8 @@ register struct obj *sobj;
/* look for gold carried by monsters (might be in a container) */ /* look for gold carried by monsters (might be in a container) */
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp)) if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx))
continue; /* probably not needed in this case but... */ continue;
if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) { if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) {
if (mtmp == u.usteed) { if (mtmp == u.usteed) {
steedgold = TRUE; steedgold = TRUE;
@@ -402,8 +402,8 @@ register struct obj *sobj;
ugold = TRUE; ugold = TRUE;
} }
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp)) if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx))
continue; /* probably overkill here */ continue;
temp = 0; temp = 0;
if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) { if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) {
gold = cg.zeroobj; /* ensure oextra is cleared too */ gold = cg.zeroobj; /* ensure oextra is cleared too */
@@ -472,7 +472,8 @@ register struct obj *sobj;
ct++; ct++;
} }
for (mtmp = fmon; mtmp && (!ct || !ctu); mtmp = mtmp->nmon) { for (mtmp = fmon; mtmp && (!ct || !ctu); mtmp = mtmp->nmon) {
/* no DEADMONSTER(mtmp) check needed -- dmons never have inventory */ if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx))
continue;
for (obj = mtmp->minvent; obj; obj = obj->nobj) for (obj = mtmp->minvent; obj; obj = obj->nobj)
if (o_in(obj, oclass)) { if (o_in(obj, oclass)) {
if (mtmp->mx == u.ux && mtmp->my == u.uy) if (mtmp->mx == u.ux && mtmp->my == u.uy)
@@ -534,8 +535,9 @@ register struct obj *sobj;
} }
map_object(temp, 1); map_object(temp, 1);
} }
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
/* no DEADMONSTER() check needed -- dmons never have inventory */ if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx))
continue;
for (obj = mtmp->minvent; obj; obj = obj->nobj) for (obj = mtmp->minvent; obj; obj = obj->nobj)
if ((temp = o_in(obj, oclass)) != 0) { if ((temp = o_in(obj, oclass)) != 0) {
temp->ox = mtmp->mx; temp->ox = mtmp->mx;
@@ -543,6 +545,7 @@ register struct obj *sobj;
map_object(temp, 1); map_object(temp, 1);
break; /* skip rest of this monster's inventory */ break; /* skip rest of this monster's inventory */
} }
}
if (!ctu) { if (!ctu) {
newsym(u.ux, u.uy); newsym(u.ux, u.uy);
ter_typ |= TER_MON; /* for autodescribe of self */ ter_typ |= TER_MON; /* for autodescribe of self */
@@ -604,7 +607,7 @@ int class; /* an object class, 0 for all */
* We can exclude checking the buried obj chain for boulders below. * We can exclude checking the buried obj chain for boulders below.
*/ */
sym = class ? def_oc_syms[class].sym : 0; sym = class ? def_oc_syms[class].sym : 0;
if (sym && g.showsyms[SYM_BOULDER + SYM_OFF_X] && sym == g.showsyms[SYM_BOULDER + SYM_OFF_X]) if (sym && sym == g.showsyms[SYM_BOULDER + SYM_OFF_X])
boulder = ROCK_CLASS; boulder = ROCK_CLASS;
if (Hallucination || (Confusion && class == SCROLL_CLASS)) if (Hallucination || (Confusion && class == SCROLL_CLASS))
@@ -644,7 +647,7 @@ int class; /* an object class, 0 for all */
u.usteed->mx = u.ux, u.usteed->my = u.uy; u.usteed->mx = u.ux, u.usteed->my = u.uy;
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp)) if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx))
continue; continue;
for (obj = mtmp->minvent; obj; obj = obj->nobj) { for (obj = mtmp->minvent; obj; obj = obj->nobj) {
if ((!class && !boulder) || o_in(obj, class) if ((!class && !boulder) || o_in(obj, class)
@@ -667,7 +670,6 @@ int class; /* an object class, 0 for all */
strange_feeling(detector, "You feel a lack of something."); strange_feeling(detector, "You feel a lack of something.");
return 1; return 1;
} }
You("sense %s nearby.", stuff); You("sense %s nearby.", stuff);
return 0; return 0;
} }
@@ -715,7 +717,7 @@ int class; /* an object class, 0 for all */
/* Objects in the monster's inventory override floor objects. */ /* Objects in the monster's inventory override floor objects. */
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp)) if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx))
continue; continue;
for (obj = mtmp->minvent; obj; obj = obj->nobj) for (obj = mtmp->minvent; obj; obj = obj->nobj)
if ((!class && !boulder) || (otmp = o_in(obj, class)) != 0 if ((!class && !boulder) || (otmp = o_in(obj, class)) != 0
@@ -790,11 +792,12 @@ int mclass; /* monster class, 0 for all */
* presence of dmons, so we have to find at least one * presence of dmons, so we have to find at least one
* with positive hit-points to know for sure. * with positive hit-points to know for sure.
*/ */
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (!DEADMONSTER(mtmp)) { if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx))
mcnt++; continue;
break; ++mcnt;
} break; /* no need for full count, just 1 or more vs 0 */
}
if (!mcnt) { if (!mcnt) {
if (otmp) if (otmp)
@@ -809,7 +812,7 @@ int mclass; /* monster class, 0 for all */
cls(); cls();
unconstrained = unconstrain_map(); unconstrained = unconstrain_map();
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp)) if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx))
continue; continue;
if (!mclass || mtmp->data->mlet == mclass if (!mclass || mtmp->data->mlet == mclass
|| (mtmp->data == &mons[PM_LONG_WORM] || (mtmp->data == &mons[PM_LONG_WORM]
@@ -961,7 +964,7 @@ struct obj *sobj; /* null if crystal ball, *scroll if gold detection scroll */
found = TRUE; found = TRUE;
} }
for (mon = fmon; mon; mon = mon->nmon) { for (mon = fmon; mon; mon = mon->nmon) {
if (DEADMONSTER(mon)) if (DEADMONSTER(mon) || (mon->isgd && !mon->mx))
continue; continue;
if ((tr = detect_obj_traps(mon->minvent, FALSE, 0)) != OTRAP_NONE) { if ((tr = detect_obj_traps(mon->minvent, FALSE, 0)) != OTRAP_NONE) {
if (tr & OTRAP_THERE) if (tr & OTRAP_THERE)
@@ -1002,7 +1005,7 @@ struct obj *sobj; /* null if crystal ball, *scroll if gold detection scroll */
(void) detect_obj_traps(fobj, TRUE, cursed_src); (void) detect_obj_traps(fobj, TRUE, cursed_src);
(void) detect_obj_traps(g.level.buriedobjlist, TRUE, cursed_src); (void) detect_obj_traps(g.level.buriedobjlist, TRUE, cursed_src);
for (mon = fmon; mon; mon = mon->nmon) { for (mon = fmon; mon; mon = mon->nmon) {
if (DEADMONSTER(mon)) if (DEADMONSTER(mon) || (mon->isgd && !mon->mx))
continue; continue;
(void) detect_obj_traps(mon->minvent, TRUE, cursed_src); (void) detect_obj_traps(mon->minvent, TRUE, cursed_src);
} }