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
This commit is contained in:
PatR
2023-02-06 15:50:39 -08:00
parent 1d06fa62a9
commit 5d5445d85b
2 changed files with 31 additions and 29 deletions
+4 -1
View File
@@ -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 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 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 dying in a wall spot (temporary gap or via Passes_walls) shared by two shops
could result in "place_object: \"<item>\" [0] off map <0,0>" warnings could result in "place_object: \"<item>\" [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 Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
+27 -28
View File
@@ -356,7 +356,7 @@ m_sees_sleepy_soldier(struct monst *mtmp)
/* Select a defensive item/action for a monster. Returns TRUE iff one is /* Select a defensive item/action for a monster. Returns TRUE iff one is
found. */ found. */
boolean boolean
find_defensive(struct monst* mtmp, boolean tryescape) find_defensive(struct monst *mtmp, boolean tryescape)
{ {
struct obj *obj; struct obj *obj;
struct trap *t; 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 */ ; /* fleeing by stairs or traps is not possible */
} else if (levl[x][y].typ == STAIRS) { } else if (levl[x][y].typ == STAIRS) {
stway = stairway_at(x,y); 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). * 2: did something and can't attack again (i.e. teleported).
*/ */
int int
use_defensive(struct monst* mtmp) use_defensive(struct monst *mtmp)
{ {
int i, fleetim, how = 0; int i, fleetim, how = 0;
struct obj *otmp = gm.m.defensive; struct obj *otmp = gm.m.defensive;
@@ -1095,7 +1095,7 @@ use_defensive(struct monst* mtmp)
} }
int int
rnd_defensive_item(struct monst* mtmp) rnd_defensive_item(struct monst *mtmp)
{ {
struct permonst *pm = mtmp->data; struct permonst *pm = mtmp->data;
int difficulty = mons[(monsndx(pm))].difficulty; int difficulty = mons[(monsndx(pm))].difficulty;
@@ -1171,7 +1171,7 @@ linedup_chk_corpse(coordxy x, coordxy y)
} }
static void 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, coordxy ax = u.ux + sgn(mtmp->mux - mtmp->mx) * 3,
ay = u.uy + sgn(mtmp->muy - mtmp->my) * 3; ay = u.uy + sgn(mtmp->muy - mtmp->my) * 3;
@@ -1270,7 +1270,7 @@ mon_has_friends(struct monst *mtmp)
* found. * found.
*/ */
boolean boolean
find_offensive(struct monst* mtmp) find_offensive(struct monst *mtmp)
{ {
register struct obj *obj; register struct obj *obj;
boolean reflection_skip = m_seenres(mtmp, M_SEEN_REFL) != 0 boolean reflection_skip = m_seenres(mtmp, M_SEEN_REFL) != 0
@@ -1436,9 +1436,8 @@ find_offensive(struct monst* mtmp)
#undef nomore #undef nomore
} }
static static int
int mbhitm(struct monst *mtmp, struct obj *otmp)
mbhitm(register struct monst* mtmp, register struct obj* otmp)
{ {
int tmp; int tmp;
boolean reveal_invis = FALSE, hits_you = (mtmp == &gy.youmonst); boolean reveal_invis = FALSE, hits_you = (mtmp == &gy.youmonst);
@@ -1637,7 +1636,7 @@ mbhit(
* after find_offensive(). Return values are same as use_defensive(). * after find_offensive(). Return values are same as use_defensive().
*/ */
int int
use_offensive(struct monst* mtmp) use_offensive(struct monst *mtmp)
{ {
int i; int i;
struct obj *otmp = gm.m.offensive; struct obj *otmp = gm.m.offensive;
@@ -1824,7 +1823,7 @@ use_offensive(struct monst* mtmp)
} }
int int
rnd_offensive_item(struct monst* mtmp) rnd_offensive_item(struct monst *mtmp)
{ {
struct permonst *pm = mtmp->data; struct permonst *pm = mtmp->data;
int difficulty = mons[(monsndx(pm))].difficulty; int difficulty = mons[(monsndx(pm))].difficulty;
@@ -1882,7 +1881,7 @@ rnd_offensive_item(struct monst* mtmp)
#define MUSE_BAG 10 #define MUSE_BAG 10
boolean boolean
find_misc(struct monst* mtmp) find_misc(struct monst *mtmp)
{ {
register struct obj *obj; register struct obj *obj;
struct permonst *mdat = mtmp->data; struct permonst *mdat = mtmp->data;
@@ -1907,7 +1906,7 @@ find_misc(struct monst* mtmp)
if (dist2(x, y, mtmp->mux, mtmp->muy) > 36) if (dist2(x, y, mtmp->mux, mtmp->muy) > 36)
return FALSE; return FALSE;
if (!stuck && !immobile && (mtmp->cham == NON_PM) if (!stuck && !immobile && !mtmp->mtrapped && (mtmp->cham == NON_PM)
&& mons[(pmidx = monsndx(mdat))].difficulty < 6) { && mons[(pmidx = monsndx(mdat))].difficulty < 6) {
boolean ignore_boulders = (verysmall(mdat) || throws_rocks(mdat) boolean ignore_boulders = (verysmall(mdat) || throws_rocks(mdat)
|| passes_walls(mdat)), || passes_walls(mdat)),
@@ -1915,7 +1914,7 @@ find_misc(struct monst* mtmp)
for (xx = x - 1; xx <= x + 1; xx++) for (xx = x - 1; xx <= x + 1; xx++)
for (yy = y - 1; yy <= y + 1; yy++) 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) && (diag_ok || xx == x || yy == y)
&& ((xx == x && yy == y) || !gl.level.monsters[xx][yy])) && ((xx == x && yy == y) || !gl.level.monsters[xx][yy]))
if ((t = t_at(xx, yy)) != 0 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 /* type of monster to polymorph into; defaults to one suitable for the
current level rather than the totally arbitrary choice of newcham() */ current level rather than the totally arbitrary choice of newcham() */
static struct permonst * static struct permonst *
muse_newcham_mon(struct monst* mon) muse_newcham_mon(struct monst *mon)
{ {
struct obj *m_armr; struct obj *m_armr;
@@ -2166,7 +2165,7 @@ mloot_container(
DISABLE_WARNING_UNREACHABLE_CODE DISABLE_WARNING_UNREACHABLE_CODE
int int
use_misc(struct monst* mtmp) use_misc(struct monst *mtmp)
{ {
char nambuf[BUFSZ]; char nambuf[BUFSZ];
boolean vis, vismon, vistrapspot, oseen; boolean vis, vismon, vistrapspot, oseen;
@@ -2384,7 +2383,7 @@ use_misc(struct monst* mtmp)
RESTORE_WARNINGS RESTORE_WARNINGS
static void static void
you_aggravate(struct monst* mtmp) you_aggravate(struct monst *mtmp)
{ {
pline("For some reason, %s presence is known to you.", pline("For some reason, %s presence is known to you.",
s_suffix(noit_mon_nam(mtmp))); s_suffix(noit_mon_nam(mtmp)));
@@ -2407,7 +2406,7 @@ you_aggravate(struct monst* mtmp)
} }
int int
rnd_misc_item(struct monst* mtmp) rnd_misc_item(struct monst *mtmp)
{ {
struct permonst *pm = mtmp->data; struct permonst *pm = mtmp->data;
int difficulty = mons[(monsndx(pm))].difficulty; int difficulty = mons[(monsndx(pm))].difficulty;
@@ -2444,7 +2443,7 @@ rnd_misc_item(struct monst* mtmp)
#if 0 #if 0
/* check whether hero is carrying a corpse or contained petrifier corpse */ /* check whether hero is carrying a corpse or contained petrifier corpse */
static boolean static boolean
necrophiliac(struct obj* objlist, boolean any_corpse) necrophiliac(struct obj *objlist, boolean any_corpse)
{ {
while (objlist) { while (objlist) {
if (objlist->otyp == CORPSE if (objlist->otyp == CORPSE
@@ -2459,7 +2458,7 @@ necrophiliac(struct obj* objlist, boolean any_corpse)
#endif #endif
boolean boolean
searches_for_item(struct monst* mon, struct obj* obj) searches_for_item(struct monst *mon, struct obj *obj)
{ {
int typ = obj->otyp; int typ = obj->otyp;
@@ -2550,7 +2549,7 @@ searches_for_item(struct monst* mon, struct obj* obj)
DISABLE_WARNING_FORMAT_NONLITERAL DISABLE_WARNING_FORMAT_NONLITERAL
boolean 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); struct obj *orefl = which_armor(mon, W_ARMS);
@@ -2589,7 +2588,7 @@ mon_reflects(struct monst* mon, const char* str)
} }
boolean boolean
ureflects(const char* fmt, const char* str) ureflects(const char *fmt, const char *str)
{ {
/* Check from outermost to innermost objects */ /* Check from outermost to innermost objects */
if (EReflecting & W_ARMS) { if (EReflecting & W_ARMS) {
@@ -2625,7 +2624,7 @@ RESTORE_WARNING_FORMAT_NONLITERAL
/* cure mon's blindness (use_defensive, dog_eat, meatobj) */ /* cure mon's blindness (use_defensive, dog_eat, meatobj) */
void void
mcureblindness(struct monst* mon, boolean verbos) mcureblindness(struct monst *mon, boolean verbos)
{ {
if (!mon->mcansee) { if (!mon->mcansee) {
mon->mcansee = 1; mon->mcansee = 1;
@@ -2637,7 +2636,7 @@ mcureblindness(struct monst* mon, boolean verbos)
/* TRUE if the monster ate something */ /* TRUE if the monster ate something */
boolean boolean
munstone(struct monst* mon, boolean by_you) munstone(struct monst *mon, boolean by_you)
{ {
struct obj *obj; struct obj *obj;
boolean tinok; boolean tinok;
@@ -2738,7 +2737,7 @@ mon_consume_unstone(
/* decide whether obj can cure petrification; also used when picking up */ /* decide whether obj can cure petrification; also used when picking up */
static boolean 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) if (obj->otyp == POT_ACID)
return TRUE; return TRUE;
@@ -2754,7 +2753,7 @@ cures_stoning(struct monst* mon, struct obj* obj, boolean tinok)
} }
static boolean static boolean
mcould_eat_tin(struct monst* mon) mcould_eat_tin(struct monst *mon)
{ {
struct obj *obj, *mwep; struct obj *obj, *mwep;
boolean welded_wep; boolean welded_wep;
@@ -2784,7 +2783,7 @@ mcould_eat_tin(struct monst* mon)
/* TRUE if monster does something to avoid turning into green slime */ /* TRUE if monster does something to avoid turning into green slime */
boolean boolean
munslime(struct monst* mon, boolean by_you) munslime(struct monst *mon, boolean by_you)
{ {
struct obj *obj, odummy; struct obj *obj, odummy;
struct permonst *mptr = mon->data; 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 the display color, otherwise we just pick things that seem plausibly
green (which doesn't necessarily match the TEXTCOLOR categorization) */ green (which doesn't necessarily match the TEXTCOLOR categorization) */
static boolean static boolean
green_mon(struct monst* mon) green_mon(struct monst *mon)
{ {
struct permonst *ptr = mon->data; struct permonst *ptr = mon->data;