From: PatR Date: Mon, 20 Apr 2020 23:11:47 +0000 (-0700) Subject: detection bugs when vault guard is at <0,0> X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ca4e72921602c8756e30e27da632c677e73dce2a;p=nethack 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. --- diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 55ae20606..7bddea145 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -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 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 +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 diff --git a/src/detect.c b/src/detect.c index 3c5d87f43..2fbd9aeac 100644 --- a/src/detect.c +++ b/src/detect.c @@ -312,8 +312,8 @@ register struct obj *sobj; /* look for gold carried by monsters (might be in a container) */ for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp)) - continue; /* probably not needed in this case but... */ + if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) + continue; if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) { if (mtmp == u.usteed) { steedgold = TRUE; @@ -402,8 +402,8 @@ register struct obj *sobj; ugold = TRUE; } for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp)) - continue; /* probably overkill here */ + if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) + continue; temp = 0; if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) { gold = cg.zeroobj; /* ensure oextra is cleared too */ @@ -472,7 +472,8 @@ register struct obj *sobj; ct++; } 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) if (o_in(obj, oclass)) { if (mtmp->mx == u.ux && mtmp->my == u.uy) @@ -534,8 +535,9 @@ register struct obj *sobj; } map_object(temp, 1); } - for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) - /* no DEADMONSTER() check needed -- dmons never have inventory */ + for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { + if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) + continue; for (obj = mtmp->minvent; obj; obj = obj->nobj) if ((temp = o_in(obj, oclass)) != 0) { temp->ox = mtmp->mx; @@ -543,6 +545,7 @@ register struct obj *sobj; map_object(temp, 1); break; /* skip rest of this monster's inventory */ } + } if (!ctu) { newsym(u.ux, u.uy); 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. */ 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; 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; for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp)) + if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) continue; for (obj = mtmp->minvent; obj; obj = obj->nobj) { 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."); return 1; } - You("sense %s nearby.", stuff); return 0; } @@ -715,7 +717,7 @@ int class; /* an object class, 0 for all */ /* Objects in the monster's inventory override floor objects. */ for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp)) + if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) continue; for (obj = mtmp->minvent; obj; obj = obj->nobj) 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 * with positive hit-points to know for sure. */ - for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) - if (!DEADMONSTER(mtmp)) { - mcnt++; - break; - } + for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { + if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) + continue; + ++mcnt; + break; /* no need for full count, just 1 or more vs 0 */ + } if (!mcnt) { if (otmp) @@ -809,7 +812,7 @@ int mclass; /* monster class, 0 for all */ cls(); unconstrained = unconstrain_map(); for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp)) + if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) continue; if (!mclass || mtmp->data->mlet == mclass || (mtmp->data == &mons[PM_LONG_WORM] @@ -961,7 +964,7 @@ struct obj *sobj; /* null if crystal ball, *scroll if gold detection scroll */ found = TRUE; } for (mon = fmon; mon; mon = mon->nmon) { - if (DEADMONSTER(mon)) + if (DEADMONSTER(mon) || (mon->isgd && !mon->mx)) continue; if ((tr = detect_obj_traps(mon->minvent, FALSE, 0)) != OTRAP_NONE) { 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(g.level.buriedobjlist, TRUE, cursed_src); for (mon = fmon; mon; mon = mon->nmon) { - if (DEADMONSTER(mon)) + if (DEADMONSTER(mon) || (mon->isgd && !mon->mx)) continue; (void) detect_obj_traps(mon->minvent, TRUE, cursed_src); }