]> granicus.if.org Git - nethack/commitdiff
fix github issue #972 - moving while trapped
authorPatR <rankin@nethack.org>
Mon, 6 Feb 2023 23:50:39 +0000 (15:50 -0800)
committerPatR <rankin@nethack.org>
Mon, 6 Feb 2023 23:50:39 +0000 (15:50 -0800)
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

doc/fixes3-7-0.txt
src/muse.c

index eece26df014bfcb16a9caa70d259b72afa4e3c0c..0d44f3886632e184164c5087fe50c0bf71be43b0 100644 (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
index 22a412adc78a0b9adc1a8c3c846120ce1f5bf3b1..5507fcc6888b229a9b5c005385d37478aeedce3e 100644 (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 monstmtmp, 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 monstmtmp)
+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 monstmtmp)
+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 monstmtmp)
+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 monstmtmp)
+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 monstmtmp)
+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 monstmtmp)
+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 monstmon)
+muse_newcham_mon(struct monst *mon)
 {
     struct obj *m_armr;
 
@@ -2166,7 +2165,7 @@ mloot_container(
 DISABLE_WARNING_UNREACHABLE_CODE
 
 int
-use_misc(struct monstmtmp)
+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 monstmtmp)
+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 monstmtmp)
+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 objobjlist, 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 monstmon, 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 monstmon, 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 monstmon)
+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 monstmon, 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 monstmon)
+green_mon(struct monst *mon)
 {
     struct permonst *ptr = mon->data;