From: PatR Date: Mon, 6 Feb 2023 23:50:39 +0000 (-0800) Subject: fix github issue #972 - moving while trapped X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5d5445d85bb9bb0e874c9b1748ab64dc49a0fafc;p=nethack fix github issue #972 - moving while trapped Reported by elunna: a monster trapped in a pit or web that was adjacent to a polymorph trap could enter that trap to change shape. It would remain flagged as trapped but there's no way to escape from a polymorph trap so it would be stuck. Fix supplied by entrez: when a monster is picking MUSE strategy, don't allow it choose "enter polymorph trap" if it is currently trapped. I entered the changes from the diff manually and added a bunch of minor formatting bits. Fixes #972 --- diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index eece26df0..0d44f3886 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1,4 +1,4 @@ -HDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1051 $ $NHDT-Date: 1665130022 2022/10/07 08:07:02 $ +DT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1051 $ $NHDT-Date: 1665130022 2022/10/07 08:07:02 $ General Fixes and Modified Features ----------------------------------- @@ -1107,6 +1107,9 @@ fix a case where punished iron ball yanked hero on top of a monster slightly randomize amount of items and monsters in the mines dying in a wall spot (temporary gap or via Passes_walls) shared by two shops could result in "place_object: \"\" [0] off map <0,0>" warnings +a monster capable of using a polymorph trap to deliberately change form could + do so when trapped in an adjacent web or pit; if that happened, the + monster remained flagged as 'trapped' and wouldn't be able to move Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/muse.c b/src/muse.c index 22a412adc..5507fcc68 100644 --- a/src/muse.c +++ b/src/muse.c @@ -356,7 +356,7 @@ m_sees_sleepy_soldier(struct monst *mtmp) /* Select a defensive item/action for a monster. Returns TRUE iff one is found. */ boolean -find_defensive(struct monst* mtmp, boolean tryescape) +find_defensive(struct monst *mtmp, boolean tryescape) { struct obj *obj; struct trap *t; @@ -470,7 +470,7 @@ find_defensive(struct monst* mtmp, boolean tryescape) } } - if (stuck || immobile) { + if (stuck || immobile || mtmp->mtrapped) { ; /* fleeing by stairs or traps is not possible */ } else if (levl[x][y].typ == STAIRS) { stway = stairway_at(x,y); @@ -670,7 +670,7 @@ find_defensive(struct monst* mtmp, boolean tryescape) * 2: did something and can't attack again (i.e. teleported). */ int -use_defensive(struct monst* mtmp) +use_defensive(struct monst *mtmp) { int i, fleetim, how = 0; struct obj *otmp = gm.m.defensive; @@ -1095,7 +1095,7 @@ use_defensive(struct monst* mtmp) } int -rnd_defensive_item(struct monst* mtmp) +rnd_defensive_item(struct monst *mtmp) { struct permonst *pm = mtmp->data; int difficulty = mons[(monsndx(pm))].difficulty; @@ -1171,7 +1171,7 @@ linedup_chk_corpse(coordxy x, coordxy y) } static void -m_use_undead_turning(struct monst* mtmp, struct obj* obj) +m_use_undead_turning(struct monst *mtmp, struct obj *obj) { coordxy ax = u.ux + sgn(mtmp->mux - mtmp->mx) * 3, ay = u.uy + sgn(mtmp->muy - mtmp->my) * 3; @@ -1270,7 +1270,7 @@ mon_has_friends(struct monst *mtmp) * found. */ boolean -find_offensive(struct monst* mtmp) +find_offensive(struct monst *mtmp) { register struct obj *obj; boolean reflection_skip = m_seenres(mtmp, M_SEEN_REFL) != 0 @@ -1436,9 +1436,8 @@ find_offensive(struct monst* mtmp) #undef nomore } -static -int -mbhitm(register struct monst* mtmp, register struct obj* otmp) +static int +mbhitm(struct monst *mtmp, struct obj *otmp) { int tmp; boolean reveal_invis = FALSE, hits_you = (mtmp == &gy.youmonst); @@ -1637,7 +1636,7 @@ mbhit( * after find_offensive(). Return values are same as use_defensive(). */ int -use_offensive(struct monst* mtmp) +use_offensive(struct monst *mtmp) { int i; struct obj *otmp = gm.m.offensive; @@ -1824,7 +1823,7 @@ use_offensive(struct monst* mtmp) } int -rnd_offensive_item(struct monst* mtmp) +rnd_offensive_item(struct monst *mtmp) { struct permonst *pm = mtmp->data; int difficulty = mons[(monsndx(pm))].difficulty; @@ -1882,7 +1881,7 @@ rnd_offensive_item(struct monst* mtmp) #define MUSE_BAG 10 boolean -find_misc(struct monst* mtmp) +find_misc(struct monst *mtmp) { register struct obj *obj; struct permonst *mdat = mtmp->data; @@ -1907,7 +1906,7 @@ find_misc(struct monst* mtmp) if (dist2(x, y, mtmp->mux, mtmp->muy) > 36) return FALSE; - if (!stuck && !immobile && (mtmp->cham == NON_PM) + if (!stuck && !immobile && !mtmp->mtrapped && (mtmp->cham == NON_PM) && mons[(pmidx = monsndx(mdat))].difficulty < 6) { boolean ignore_boulders = (verysmall(mdat) || throws_rocks(mdat) || passes_walls(mdat)), @@ -1915,7 +1914,7 @@ find_misc(struct monst* mtmp) for (xx = x - 1; xx <= x + 1; xx++) for (yy = y - 1; yy <= y + 1; yy++) - if (isok(xx, yy) && (xx != u.ux || yy != u.uy) + if (isok(xx, yy) && !u_at(xx, yy) && (diag_ok || xx == x || yy == y) && ((xx == x && yy == y) || !gl.level.monsters[xx][yy])) if ((t = t_at(xx, yy)) != 0 @@ -2035,7 +2034,7 @@ find_misc(struct monst* mtmp) /* type of monster to polymorph into; defaults to one suitable for the current level rather than the totally arbitrary choice of newcham() */ static struct permonst * -muse_newcham_mon(struct monst* mon) +muse_newcham_mon(struct monst *mon) { struct obj *m_armr; @@ -2166,7 +2165,7 @@ mloot_container( DISABLE_WARNING_UNREACHABLE_CODE int -use_misc(struct monst* mtmp) +use_misc(struct monst *mtmp) { char nambuf[BUFSZ]; boolean vis, vismon, vistrapspot, oseen; @@ -2384,7 +2383,7 @@ use_misc(struct monst* mtmp) RESTORE_WARNINGS static void -you_aggravate(struct monst* mtmp) +you_aggravate(struct monst *mtmp) { pline("For some reason, %s presence is known to you.", s_suffix(noit_mon_nam(mtmp))); @@ -2407,7 +2406,7 @@ you_aggravate(struct monst* mtmp) } int -rnd_misc_item(struct monst* mtmp) +rnd_misc_item(struct monst *mtmp) { struct permonst *pm = mtmp->data; int difficulty = mons[(monsndx(pm))].difficulty; @@ -2444,7 +2443,7 @@ rnd_misc_item(struct monst* mtmp) #if 0 /* check whether hero is carrying a corpse or contained petrifier corpse */ static boolean -necrophiliac(struct obj* objlist, boolean any_corpse) +necrophiliac(struct obj *objlist, boolean any_corpse) { while (objlist) { if (objlist->otyp == CORPSE @@ -2459,7 +2458,7 @@ necrophiliac(struct obj* objlist, boolean any_corpse) #endif boolean -searches_for_item(struct monst* mon, struct obj* obj) +searches_for_item(struct monst *mon, struct obj *obj) { int typ = obj->otyp; @@ -2550,7 +2549,7 @@ searches_for_item(struct monst* mon, struct obj* obj) DISABLE_WARNING_FORMAT_NONLITERAL boolean -mon_reflects(struct monst* mon, const char* str) +mon_reflects(struct monst *mon, const char *str) { struct obj *orefl = which_armor(mon, W_ARMS); @@ -2589,7 +2588,7 @@ mon_reflects(struct monst* mon, const char* str) } boolean -ureflects(const char* fmt, const char* str) +ureflects(const char *fmt, const char *str) { /* Check from outermost to innermost objects */ if (EReflecting & W_ARMS) { @@ -2625,7 +2624,7 @@ RESTORE_WARNING_FORMAT_NONLITERAL /* cure mon's blindness (use_defensive, dog_eat, meatobj) */ void -mcureblindness(struct monst* mon, boolean verbos) +mcureblindness(struct monst *mon, boolean verbos) { if (!mon->mcansee) { mon->mcansee = 1; @@ -2637,7 +2636,7 @@ mcureblindness(struct monst* mon, boolean verbos) /* TRUE if the monster ate something */ boolean -munstone(struct monst* mon, boolean by_you) +munstone(struct monst *mon, boolean by_you) { struct obj *obj; boolean tinok; @@ -2738,7 +2737,7 @@ mon_consume_unstone( /* decide whether obj can cure petrification; also used when picking up */ static boolean -cures_stoning(struct monst* mon, struct obj* obj, boolean tinok) +cures_stoning(struct monst *mon, struct obj *obj, boolean tinok) { if (obj->otyp == POT_ACID) return TRUE; @@ -2754,7 +2753,7 @@ cures_stoning(struct monst* mon, struct obj* obj, boolean tinok) } static boolean -mcould_eat_tin(struct monst* mon) +mcould_eat_tin(struct monst *mon) { struct obj *obj, *mwep; boolean welded_wep; @@ -2784,7 +2783,7 @@ mcould_eat_tin(struct monst* mon) /* TRUE if monster does something to avoid turning into green slime */ boolean -munslime(struct monst* mon, boolean by_you) +munslime(struct monst *mon, boolean by_you) { struct obj *obj, odummy; struct permonst *mptr = mon->data; @@ -3019,7 +3018,7 @@ cures_sliming(struct monst *mon, struct obj *obj) the display color, otherwise we just pick things that seem plausibly green (which doesn't necessarily match the TEXTCOLOR categorization) */ static boolean -green_mon(struct monst* mon) +green_mon(struct monst *mon) { struct permonst *ptr = mon->data;