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

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
-----------------------------------
@@ -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: \"<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

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
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;