]> granicus.if.org Git - nethack/commitdiff
monsters moving other monsters (trunk only)
authornethack.allison <nethack.allison>
Sun, 16 Nov 2003 20:10:30 +0000 (20:10 +0000)
committernethack.allison <nethack.allison>
Sun, 16 Nov 2003 20:10:30 +0000 (20:10 +0000)
For now, the code is conditional on BARGETHROUGH
being defined, while it gets tested further. While behavior is
different with and without BARGETHROUGH defined, savefiles
are the same either way.

After this patch is applied, only the riders have the M3_DISPLACES
bit set, but the Wizard and Vlad probably should too. Any others?

13 files changed:
include/config.h
include/extern.h
include/mfndpos.h
include/mondata.h
include/monflag.h
include/patchlevel.h
src/dogmove.c
src/mhitm.c
src/mon.c
src/monmove.c
src/monst.c
src/teleport.c
util/makedefs.c

index e1f418064edb91e059ec942eb8dccde59d0a0f56..ab0a154557ccb9f54aca61898eb3219b24a275d9 100644 (file)
@@ -335,6 +335,7 @@ typedef unsigned char       uchar;
 #if !defined(MAC)
 # define CLIPPING      /* allow smaller screens -- ERS */
 #endif
+#define BARGETHROUGH   /* allow some monster to move others out of their way */
 
 #ifdef REDO
 # define DOAGAIN '\001' /* ^A, the "redo" key used in cmd.c and getline.c */
index 6df504e5d987ed1ff0be45b1b7fc574d60e6195a..720a83d74a1fb05ece7c554f893951c50354fa97 100644 (file)
@@ -463,6 +463,9 @@ E void FDECL(switch_graphics, (int));
 #ifdef REINCARNATION
 E void FDECL(assign_rogue_graphics, (BOOLEAN_P));
 #endif
+#ifdef BARGETHROUGH
+E boolean FDECL(cursed_object_at, (int, int));
+#endif
 
 /* ### dungeon.c ### */
 
@@ -966,6 +969,9 @@ E int FDECL(buzzmu, (struct monst *,struct attack *));
 
 E int FDECL(fightm, (struct monst *));
 E int FDECL(mattackm, (struct monst *,struct monst *));
+#ifdef BARGETHROUGH
+E int FDECL(mdisplacem, (struct monst *,struct monst *,BOOLEAN_P));
+#endif
 E int FDECL(noattacks, (struct permonst *));
 E int FDECL(sleep_monst, (struct monst *,int,int));
 E void FDECL(slept_monst, (struct monst *));
@@ -1216,6 +1222,11 @@ E boolean FDECL(closed_door, (int,int));
 E boolean FDECL(accessible, (int,int));
 E void FDECL(set_apparxy, (struct monst *));
 E boolean FDECL(can_ooze, (struct monst *));
+#ifdef BARGETHROUGH
+E boolean FDECL(should_displace, (struct monst *,coord *,long *,int,
+                                       XCHAR_P,XCHAR_P));
+E boolean FDECL(undesirable_disp, (struct monst *,XCHAR_P,XCHAR_P));
+#endif
 
 /* ### monst.c ### */
 
index 01a4bb58045a354c1ed6aaff1ff31a4f8d1c57b5..a5643b1f1728db89958de1509550f80eed347aa6 100644 (file)
@@ -5,6 +5,9 @@
 #ifndef MFNDPOS_H
 #define MFNDPOS_H
 
+#ifdef BARGETHROUGH
+#define ALLOW_MDISP    0x00001000L     /* can displace a monster out of its way */
+#endif
 #define ALLOW_TRAPS    0x00020000L     /* can enter traps */
 #define ALLOW_U                0x00040000L     /* can attack you */
 #define ALLOW_M                0x00080000L     /* can attack other monsters */
index 7d86d59388e922190e0058c0a89f55b38258e715..8c37db24572ab929a70610111fd99f38ca93bb27 100644 (file)
 #define is_covetous(ptr)       ((ptr->mflags3 & M3_COVETOUS))
 #define infravision(ptr)       ((ptr->mflags3 & M3_INFRAVISION))
 #define infravisible(ptr)      ((ptr->mflags3 & M3_INFRAVISIBLE))
+#ifdef BARGETHROUGH
+#define is_displacer(ptr)      (((ptr)->mflags3 & M3_DISPLACES) != 0L) 
+#endif
 #define is_mplayer(ptr)                (((ptr) >= &mons[PM_ARCHEOLOGIST]) && \
                                 ((ptr) <= &mons[PM_WIZARD]))
 #define is_rider(ptr)          ((ptr) == &mons[PM_DEATH] || \
index 8ea8c15a122bd7960df5771af663fc742d19d670..5af876dde61af03faa3f92b0a229f69a24a28116 100644 (file)
 #define M3_INFRAVISION 0x0100          /* has infravision */
 #define M3_INFRAVISIBLE 0x0200         /* visible by infravision */
 
+/* define the bit even if BARGETHROUGH is not defined for savefile compat. */
+#define M3_DISPLACES   0x0400          /* moves monsters out of its way */
+
 #define MZ_TINY                0               /* < 2' */
 #define MZ_SMALL       1               /* 2-4' */
 #define MZ_MEDIUM      2               /* 4-7' */
index 4bb7b6388746019ea9cb81d3d6d2cfc403cdc6e9..f1df6c6ace367793b76cc73169e9073c2f757f24 100644 (file)
@@ -13,7 +13,7 @@
  * Incrementing EDITLEVEL can be used to force invalidation of old bones
  * and save files.
  */
-#define EDITLEVEL      7
+#define EDITLEVEL      8
 
 #define COPYRIGHT_BANNER_A \
 "NetHack, Copyright 1985-2003"
index 987d31f969f68ee8d65be2a1cf085d19194b094a..fe0b90db23cd7174b1cd018b38ad98aed7b4e961 100644 (file)
@@ -48,13 +48,19 @@ register struct monst *mon;
 
 static NEARDATA const char nofetch[] = { BALL_CLASS, CHAIN_CLASS, ROCK_CLASS, 0 };
 
+#ifndef BARGETHROUGH
 STATIC_OVL boolean FDECL(cursed_object_at, (int, int));
+#endif /* not BARGETHROUGH */
 
 STATIC_VAR xchar gtyp, gx, gy; /* type and position of dog's current goal */
 
 STATIC_PTR void FDECL(wantdoor, (int, int, genericptr_t));
 
+#ifdef BARGETHROUGH
+boolean
+#else
 STATIC_OVL boolean
+#endif
 cursed_object_at(x, y)
 int x, y;
 {
@@ -489,6 +495,9 @@ register int after; /* this is extra fast monster movement */
        struct obj *obj = (struct obj *) 0;
        xchar otyp;
        boolean has_edog, cursemsg[9], do_eat = FALSE;
+#ifdef BARGETHROUGH
+       boolean better_with_displacing = FALSE;
+#endif
        xchar nix, niy;         /* position mtmp is (considering) moving to */
        register int nx, ny;    /* temporary coordinates */
        xchar cnt, uncursedcnt, chcnt;
@@ -546,6 +555,9 @@ register int after; /* this is extra fast monster movement */
        if (passes_walls(mtmp->data)) allowflags |= (ALLOW_ROCK | ALLOW_WALL);
        if (passes_bars(mtmp->data)) allowflags |= ALLOW_BARS;
        if (throws_rocks(mtmp->data)) allowflags |= ALLOW_ROCK;
+#ifdef BARGETHROUGH
+       if (is_displacer(mtmp->data)) allowflags |= ALLOW_MDISP;
+#endif
        if (Conflict && !resist(mtmp, RING_CLASS, 0, 0)) {
            allowflags |= ALLOW_U;
            if (!has_edog) {
@@ -590,11 +602,20 @@ register int after;       /* this is extra fast monster movement */
        uncursedcnt = 0;
        for (i = 0; i < cnt; i++) {
                nx = poss[i].x; ny = poss[i].y;
+#ifdef BARGETHROUGH
+               if (MON_AT(nx,ny) && !((info[i] & ALLOW_M) || info[i] & ALLOW_MDISP))
+                       continue;
+#else
                if (MON_AT(nx,ny) && !(info[i] & ALLOW_M)) continue;
+#endif
                if (cursed_object_at(nx, ny)) continue;
                uncursedcnt++;
        }
 
+#ifdef BARGETHROUGH
+       better_with_displacing = should_displace(mtmp,poss,info,cnt,gx,gy);
+#endif
+
        chcnt = 0;
        chi = -1;
        nidist = GDIST(nix,niy);
@@ -645,9 +666,19 @@ register int after;        /* this is extra fast monster movement */
                        mstatus = mattackm(mtmp2, mtmp);  /* return attack */
                        if (mstatus & MM_DEF_DIED) return 2;
                    }
-
                    return 0;
                }
+#ifdef BARGETHROUGH
+               if ((info[i] & ALLOW_MDISP) && MON_AT(nx, ny) &&
+                       better_with_displacing &&
+                       !undesirable_disp(mtmp,nx,ny)) {
+                   int mstatus;
+                   register struct monst *mtmp2 = m_at(nx,ny);
+                   mstatus = mdisplacem(mtmp, mtmp2, FALSE);   /* displace monster */
+                   if (mstatus && MM_DEF_DIED) return 2;
+                   return 0;
+               }
+#endif /* BARGETHROUGH */
 
                {   /* Dog avoids harmful traps, but perhaps it has to pass one
                     * in order to follow player.  (Non-harmful traps do not
index f5ba47149121db96b005d76ca3f39181a38396c7..1a74dbf831bf6637df8d902ce393c941a4fe2047 100644 (file)
@@ -168,10 +168,114 @@ fightm(mtmp)             /* have monsters fight each other */
        return 0;
 }
 
+#ifdef BARGETHROUGH
 /*
- * mattackm() -- a monster attacks another monster.
+ * mattackm() and mdisplacem() below both return a result bitfield:
  *
- * This function returns a result bitfield:
+ *         --------- aggressor died
+ *        /  ------- defender died
+ *       /  /  ----- defender was hit
+ *      /  /  /
+ *     x  x  x
+ *
+ *     0x4     MM_AGR_DIED
+ *     0x2     MM_DEF_DIED
+ *     0x1     MM_HIT
+ *     0x0     MM_MISS
+ *
+ */
+
+/*
+ * mdisplacem() -- a monster moves another monster out of the way.
+ */
+int
+mdisplacem(magr, mdef, quietly)
+register struct monst *magr,*mdef;
+boolean quietly;
+{
+       struct permonst *pa, *pd;
+       struct monst *mon;                      /* displaced monster */
+       int tx = mdef->mx, ty = mdef->my;       /* destination */
+       int fx = magr->mx, fy = magr->my;       /* current location */
+       boolean struck = FALSE;
+       
+       pa = magr->data;  pd = mdef->data;
+
+       /* The 1 in 7 failure below matches the chance in attack()
+        * for pet displacement.
+        */
+       if (!rn2(7)) return(MM_MISS);
+
+       /* Grid bugs cannot displace at an angle. */
+       if (pa == &mons[PM_GRID_BUG] && magr->mx != mdef->mx
+                                               && magr->my != mdef->my)
+               return(MM_MISS);
+
+
+       /* undetected monsters become un-hidden if they are displaced */
+       if (mdef->mundetected)
+               mdef->mundetected = 0;
+
+       /*
+        * Set up the visibility of action.
+        * You can observe monster displacement if you can see both of
+        * the monsters involved.
+        */
+       vis = (canspotmon(magr) && canspotmon(mdef));
+
+
+       if (touch_petrifies(pd) && !resists_ston(magr)) {
+               if (which_armor(magr, W_ARMG) != 0) {
+                       if (poly_when_stoned(pa)) {
+                           mon_to_stone(magr);
+                           return MM_HIT; /* no damage during the polymorph */
+                       }
+                       if (!quietly && canspotmon(magr))
+                               pline("%s turns to stone!", Monnam(magr));
+                       monstone(magr);
+                       if (magr->mhp > 0) return 0;
+                       else if (magr->mtame && !vis)
+                           You(brief_feeling, "peculiarly sad");
+                       return MM_AGR_DIED;
+               }
+       }
+
+       if (m_at(fx, fy) == magr)
+               remove_monster(fx, fy);         /* pick up from orig position */
+       if ((mon = m_at(tx, ty)) == mdef) {
+               if (!quietly && (vis))
+                       pline("%s moves %s out of %s way!",
+                               Monnam(magr), mon_nam(mdef),
+                               is_rider(pa) ? "the" : mhis(magr));
+               remove_monster(tx, ty);
+       }
+       place_monster(magr,tx,ty);      /* put magr down */
+
+       /* Restore original mon */
+       if (mon) {
+           if ((mon->mx != tx) || (mon->my != ty))
+               place_worm_seg(mon, fx, fy);
+           else
+               place_monster(mon, fx, fy);
+           struck = TRUE;
+       } else 
+           remove_monster(fx, fy);     /* shouldn't happen */
+       newsym(fx,fy);                  /* see it */
+       newsym(tx,ty);                  /*   all happen */
+       flush_screen(0);                /* make sure it shows up */
+
+       /*
+        *  Wake up the displaced defender.
+        */
+       mdef->msleeping = 0;
+       
+       return(struck ? MM_HIT : MM_MISS);
+}
+#endif /* BARGETHROUGH */
+
+/*
+ * mattackm() -- a monster attacks another monster.
+#ifndef BARGETHROUGH
  *
  *         --------- aggressor died
  *        /  ------- defender died
@@ -184,6 +288,7 @@ fightm(mtmp)                /* have monsters fight each other */
  *     0x1     MM_HIT
  *     0x0     MM_MISS
  *
+#endif
  * Each successive attack has a lower probability of hitting.  Some rely on the
  * success of previous attacks.  ** this doen't seem to be implemented -dl **
  *
index ffa2c66d860aa4c71572da83fe0223ba9aeb4631..18a0d4003853e61f44e4e1d9fd7e6369845768b3 100644 (file)
--- a/src/mon.c
+++ b/src/mon.c
@@ -14,6 +14,9 @@
 
 STATIC_DCL boolean FDECL(restrap,(struct monst *));
 STATIC_DCL long FDECL(mm_aggression, (struct monst *,struct monst *));
+#ifdef BARGETHROUGH
+STATIC_DCL long FDECL(mm_displacement, (struct monst *,struct monst *));
+#endif
 STATIC_DCL int NDECL(pick_animal);
 STATIC_DCL int FDECL(select_newcham_form, (struct monst *));
 STATIC_DCL void FDECL(kill_eggs, (struct obj *));
@@ -1092,11 +1095,24 @@ nexttry:        /* eels prefer the water, but if there is no water nearby,
                                struct monst *mtmp2 = m_at(nx, ny);
                                long mmflag = flag | mm_aggression(mon, mtmp2);
 
+#ifndef BARGETHROUGH
                                if (!(mmflag & ALLOW_M)) continue;
                                info[cnt] |= ALLOW_M;
                                if (mtmp2->mtame) {
                                        if (!(mmflag & ALLOW_TM)) continue;
                                        info[cnt] |= ALLOW_TM;
+#else /* BARGETHROUGH */
+                               if (mmflag & ALLOW_M) {
+                                       info[cnt] |= ALLOW_M;
+                                       if (mtmp2->mtame) {
+                                               if (!(mmflag & ALLOW_TM)) continue;
+                                               info[cnt] |= ALLOW_TM;
+                                       }
+                               } else {
+                                       mmflag = flag | mm_displacement(mon, mtmp2);
+                                       if (!(mmflag & ALLOW_MDISP)) continue;
+                                       info[cnt] |= ALLOW_MDISP;
+#endif /* BARGETHROUGH */
                                }
                        }
                        /* Note: ALLOW_SANCT only prevents movement, not */
@@ -1199,6 +1215,25 @@ struct monst *magr,      /* monster that is currently deciding where to move */
        return 0L;
 }
 
+#ifdef BARGETHROUGH
+/* Monster displacing another monster out of the way */
+STATIC_OVL long
+mm_displacement(magr, mdef)
+struct monst *magr,    /* monster that is currently deciding where to move */
+            *mdef;     /* another monster which is next to it */
+{
+       struct permonst *pa = magr->data;
+       struct permonst *pd = mdef->data;
+       if ((pa->mflags3 & M3_DISPLACES) &&
+           !is_longworm(pd)             &&             /* no displacing longworms  */
+           !mdef->mtrapped              &&             /* complex to do right      */
+           (is_rider(pa) ||                            /* riders can move anything */
+             pa->msize >= pd->msize))                  /* same or smaller only     */
+               return ALLOW_MDISP;
+       return 0L;
+}
+#endif /* BARGETHROUGH */
+
 boolean
 monnear(mon, x, y)
 register struct monst *mon;
index 9f2696a5d277b976d6139c8bca14cee1c84004df..282a1fa4bb16c519c166c3da6301884b9d38bbc8 100644 (file)
@@ -570,6 +570,52 @@ register struct monst *mtmp;
        return(FALSE);
 }
 
+#ifdef BARGETHROUGH
+/*
+ * should_displace()
+ *
+ * Displacement of another monster is a last resort and only
+ * used on approach. If there are better ways to get to target,
+ * those should be used instead. This function does that evaluation.
+ */
+boolean
+should_displace(mtmp, poss, info, cnt, gx, gy)
+struct monst *mtmp;
+coord *poss;   /* coord poss[9] */
+long *info;    /* long info[9] */
+int cnt;
+xchar gx, gy;
+{
+       int shortest_with_displacing = -1;
+       int shortest_without_displacing = -1;
+       int count_without_displacing = 0;
+       register int i, nx, ny;
+       int ndist;
+
+       for (i = 0; i < cnt; i++) {
+               nx = poss[i].x; ny = poss[i].y;
+               ndist = dist2(nx,ny,gx,gy);
+               if (MON_AT(nx,ny) &&
+                       (info[i] & ALLOW_MDISP) && !(info[i] & ALLOW_M) &&
+                       !undesirable_disp(mtmp,nx,ny)) {
+                       if (shortest_with_displacing == -1 ||
+                           (ndist < shortest_with_displacing))
+                               shortest_with_displacing = ndist;
+               } else {
+                       if ((shortest_without_displacing == -1) ||
+                           (ndist < shortest_without_displacing))
+                               shortest_without_displacing = ndist;
+                       count_without_displacing++;
+               }
+        }
+       if (shortest_with_displacing > -1 &&
+           (shortest_with_displacing < shortest_without_displacing ||
+           !count_without_displacing))
+               return TRUE;
+       return FALSE;
+}
+#endif /* BARGETHROUGH */
+
 /* Return values:
  * 0: did not move, but can still attack and do other stuff.
  * 1: moved, possibly can attack.
@@ -589,6 +635,9 @@ register int after;
        boolean can_open=0, can_unlock=0, doorbuster=0;
        boolean uses_items=0, setlikes=0;
        boolean avoid=FALSE;
+#ifdef BARGETHROUGH
+       boolean better_with_displacing = FALSE;
+#endif
        struct permonst *ptr;
        struct monst *mtoo;
        schar mmoved = 0;       /* not strictly nec.: chi >= 0 will do */
@@ -909,12 +958,19 @@ not_special:
                for(i = 0; i < cnt; i++)
                    if(!(info[i] & NOTONL)) avoid=TRUE;
            }
-
+#ifdef BARGETHROUGH
+           better_with_displacing = should_displace(mtmp,poss,info,cnt,gx,gy);
+#endif
            for(i=0; i < cnt; i++) {
                if (avoid && (info[i] & NOTONL)) continue;
                nx = poss[i].x;
                ny = poss[i].y;
 
+#ifdef BARGETHROUGH
+               if (MON_AT(nx,ny) &&
+                       (info[i] & ALLOW_MDISP) && !(info[i] & ALLOW_M) &&
+                       !better_with_displacing) continue;
+#endif
                if (appr != 0) {
                    mtrk = &mtmp->mtrack[0];
                    for(j=0; j < jcnt; mtrk++, j++)
@@ -1010,6 +1066,19 @@ not_special:
                return 3;
            }
 
+#ifdef BARGETHROUGH
+           if((info[chi] & ALLOW_MDISP)) {
+               struct monst *mtmp2;
+               int mstatus;
+               mtmp2 = m_at(nix,niy);
+               mstatus = mdisplacem(mtmp, mtmp2, FALSE);
+               if ((mstatus & MM_AGR_DIED) || (mstatus & MM_DEF_DIED))
+                       return 2;
+               if (mstatus & MM_HIT) return 1;
+               return 3;
+           }
+#endif /* BARGETHROUGH */
+
            if (!m_in_out_region(mtmp,nix,niy))
                return 3;
            remove_monster(omx, omy);
@@ -1287,6 +1356,41 @@ found_you:
        mtmp->muy = my;
 }
 
+#ifdef BARGETHROUGH
+/*
+ * mon-to-mon displacement is a deliberate "get out of my way" act,
+ * not an accidental bump, so we don't consider mstun or mconf in
+ * undesired_disp().
+ *
+ * We do consider many other things about the target and its
+ * location however.
+ */
+boolean
+undesirable_disp(mtmp, x, y)
+struct monst *mtmp;
+xchar x,y;
+{
+       struct permonst *mdat = mtmp->data;
+       boolean is_pet = (mtmp && mtmp->mtame && !mtmp->isminion);
+       struct trap *trap = t_at(x,y);
+
+        if (is_pet) {
+               /* Pets avoid a trap if you've seen it usually. */
+               if (trap && trap->tseen && rn2(40))
+                       return TRUE;
+               /* Pets avoid cursed locations */
+               if (cursed_object_at(x,y))
+                       return TRUE;
+        }
+        /* Monsters avoid a trap if they've seen that type before */
+        else if (trap && rn2(40) &&
+                       (mtmp->mtrapseen & (1 << (trap->ttyp -1))) != 0)
+               return TRUE;
+
+        return FALSE;
+}
+#endif /* BARGETHROUGH */
+
 boolean
 can_ooze(mtmp)
 struct monst *mtmp;
index c241f3d3a9be064bf1a502de3544e0392ad0cad3..db30c29992bc46ab74dfa2831b2545522834a7f2 100644 (file)
@@ -2748,7 +2748,7 @@ struct permonst _mons2[] = {
        MR_FIRE|MR_COLD|MR_ELEC|MR_SLEEP|MR_POISON|MR_STONE, 0,
        M1_FLY|M1_HUMANOID|M1_REGEN|M1_SEE_INVIS|M1_TPORT_CNTRL,
        M2_NOPOLY|M2_STALK|M2_HOSTILE|M2_PNAME|M2_STRONG|M2_NASTY,
-       M3_INFRAVISIBLE|M3_INFRAVISION, HI_LORD),
+       M3_INFRAVISIBLE|M3_INFRAVISION|M3_DISPLACES, HI_LORD),
     MON("Pestilence", S_DEMON,
        LVL(30, 12, -5, 100, 0), (G_UNIQ|G_NOGEN),
        A(ATTK(AT_TUCH, AD_PEST, 8, 8), ATTK(AT_TUCH, AD_PEST, 8, 8),
@@ -2757,7 +2757,7 @@ struct permonst _mons2[] = {
        MR_FIRE|MR_COLD|MR_ELEC|MR_SLEEP|MR_POISON|MR_STONE, 0,
        M1_FLY|M1_HUMANOID|M1_REGEN|M1_SEE_INVIS|M1_TPORT_CNTRL,
        M2_NOPOLY|M2_STALK|M2_HOSTILE|M2_PNAME|M2_STRONG|M2_NASTY,
-       M3_INFRAVISIBLE|M3_INFRAVISION, HI_LORD),
+       M3_INFRAVISIBLE|M3_INFRAVISION|M3_DISPLACES, HI_LORD),
     MON("Famine", S_DEMON,
        LVL(30, 12, -5, 100, 0), (G_UNIQ|G_NOGEN),
        A(ATTK(AT_TUCH, AD_FAMN, 8, 8), ATTK(AT_TUCH, AD_FAMN, 8, 8),
@@ -2766,7 +2766,7 @@ struct permonst _mons2[] = {
        MR_FIRE|MR_COLD|MR_ELEC|MR_SLEEP|MR_POISON|MR_STONE, 0,
        M1_FLY|M1_HUMANOID|M1_REGEN|M1_SEE_INVIS|M1_TPORT_CNTRL,
        M2_NOPOLY|M2_STALK|M2_HOSTILE|M2_PNAME|M2_STRONG|M2_NASTY,
-       M3_INFRAVISIBLE|M3_INFRAVISION, HI_LORD),
+       M3_INFRAVISIBLE|M3_INFRAVISION|M3_DISPLACES, HI_LORD),
        /* other demons
         */
 #ifdef MAIL
index 6627eebe63a4e61ee2b6062bff5c351267950fb9..bc0a46f50570dbd53f4cb1375f0f6e9ed1c3f93b 100644 (file)
@@ -416,6 +416,9 @@ tele()
 
        if ((u.uhave.amulet || On_W_tower_level(&u.uz)) && !rn2(3)) {
            You_feel("disoriented for a moment.");
+#ifdef WIZARD
+           if (wizard && yn("Override?") != 'y')
+#endif
            return;
        }
        if ((Teleport_control && !Stunned)
index 5e221958aca2eca6e0659e6dbc74acb3aae0518e..34a3c64aec0fef24c54d879cad40aaf71142a04b 100644 (file)
@@ -676,6 +676,9 @@ static const char *build_opts[] = {
 #ifdef MAIL
                "mail daemon",
 #endif
+#ifdef BARGETHROUGH
+               "monsters moving monsters",
+#endif
 #ifdef GNUDOS
                "MSDOS protected mode",
 #endif