]> granicus.if.org Git - nethack/commitdiff
multiple iron bars fixes
authornethack.rankin <nethack.rankin>
Sun, 7 Apr 2002 10:43:59 +0000 (10:43 +0000)
committernethack.rankin <nethack.rankin>
Sun, 7 Apr 2002 10:43:59 +0000 (10:43 +0000)
Can't push boulders through iron bars; traps can't roll such through either;
likewise for objects thrown by monsters.
Thrown objects susceptible to breaking might do so when they hit iron bars.
Assorted monsters can pass through iron bars; ditto for polymorphed character.
Attempting to dig iron bars will wake nearby monsters instead of yielding
"you swing your pick-axe through thin air".
Autodig won't accept iron bars as candidate location.

12 files changed:
doc/fixes34.1
include/extern.h
include/mfndpos.h
src/dig.c
src/dogmove.c
src/hack.c
src/mon.c
src/mondata.c
src/monmove.c
src/mthrowu.c
src/trap.c
src/zap.c

index 1353c2b3b6c1d8fd218065721856dd717458c2b6..954c35fb259270c1e1a54bc5a6bc5a771826017d 100644 (file)
@@ -55,6 +55,13 @@ reduce insect/monster creation from monster spells
 avoid "couldn't place lregion type 5" warning when arriving at Plane of Fire
 avoid crash due to delayed poly or were change no longer being valid
 ensure that Priest's ability to recognize B/U/C is considered in B/U/C menus
+can't push boulders through iron bars; traps can't roll such through either;
+       likewise for objects thrown by monsters
+thrown objects susceptible to breaking might do so when they hit iron bars
+assorted monsters can pass through iron bars; ditto for polymorphed character
+attempting to dig iron bars will wake nearby monsters instead of yielding
+       "you swing your pick-axe through thin air"
+autodig won't accept iron bars as candidate location
 
 
 Platform- and/or Interface-Specific Fixes
index 3dba1c021073d9def16ebd9ba0e515f5987aaf5d..57094c4d079727dd7f96c8442906df63d3578d74 100644 (file)
@@ -1128,6 +1128,7 @@ E boolean FDECL(resists_blnd, (struct monst *));
 E boolean FDECL(can_blnd, (struct monst *,struct monst *,UCHAR_P,struct obj *));
 E boolean FDECL(ranged_attk, (struct permonst *));
 E boolean FDECL(hates_silver, (struct permonst *));
+E boolean FDECL(passes_bars, (struct permonst *));
 E boolean FDECL(can_track, (struct permonst *));
 E boolean FDECL(breakarm, (struct permonst *));
 E boolean FDECL(sliparm, (struct permonst *));
@@ -1240,6 +1241,7 @@ E boolean FDECL(lined_up, (struct monst *));
 E struct obj *FDECL(m_carrying, (struct monst *,int));
 E void FDECL(m_useup, (struct monst *,struct obj *));
 E void FDECL(m_throw, (struct monst *,int,int,int,int,int,struct obj *));
+E boolean FDECL(hits_bars, (struct obj **,int,int,int,int));
 
 /* ### muse.c ### */
 
index 96c5dd5e751ae5e340a5a7271330176613c30953..01a4bb58045a354c1ed6aaff1ff31a4f8d1c57b5 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)mfndpos.h  3.4     1993/05/15      */
+/*     SCCS Id: @(#)mfndpos.h  3.4     2002/04/06      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -17,6 +17,7 @@
 #define ALLOW_ROCK     0x02000000L     /* pushes rocks */
 #define ALLOW_WALL     0x04000000L     /* walks thru walls */
 #define ALLOW_DIG      0x08000000L     /* digs */
+#define ALLOW_BARS     0x10000000L     /* may pass thru iron bars */
 #define ALLOW_SANCT    0x20000000L     /* enters temples */
 #define ALLOW_SSM      0x40000000L     /* ignores scare monster */
 #ifdef NHSTDC
index d9aa5e5ea3e0b5be84885993e26be8ea1fb0e801..b9ea46f7cd1c997d9984f014007933951153483d 100644 (file)
--- a/src/dig.c
+++ b/src/dig.c
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)dig.c      3.4     2001/09/06      */
+/*     SCCS Id: @(#)dig.c      3.4     2002/04/06      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -874,6 +874,9 @@ struct obj *obj;
                            /* (maybe `move_into_trap()' would be better) */
                            nomul(-d(2,2));
                            nomovemsg = "You pull free.";
+                       } else if (lev->typ == IRONBARS) {
+                           pline("Clang!");
+                           wake_nearby();
                        } else
                            You("swing your %s through thin air.",
                                aobjnam(obj, (char *)0));
index 0a78bb03a8006e33f141639cd72200173a9f6502..23d57573d9fc0bbec7d624dd786ebd4495a5269a 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)dogmove.c  3.4     2002/03/09      */
+/*     SCCS Id: @(#)dogmove.c  3.4     2002/04/06      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -543,7 +543,8 @@ register int after; /* this is extra fast monster movement */
        if (appr == -2) return(0);
 
        allowflags = ALLOW_M | ALLOW_TRAPS | ALLOW_SSM | ALLOW_SANCT;
-       if (passes_walls(mtmp->data)) allowflags |= (ALLOW_ROCK|ALLOW_WALL);
+       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;
        if (Conflict && !resist(mtmp, RING_CLASS, 0, 0)) {
            allowflags |= ALLOW_U;
index a7d25e41bcf43031ca77217a2bd99bbffc38822d..ac84a943995d73017563b7e8043086e52affdd94 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)hack.c     3.4     2002/03/24      */
+/*     SCCS Id: @(#)hack.c     3.4     2002/04/06      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -89,6 +89,7 @@ moverock()
            goto cannot_push;
        }
        if (isok(rx,ry) && !IS_ROCK(levl[rx][ry].typ) &&
+           levl[rx][ry].typ != IRONBARS &&
            (!IS_DOOR(levl[rx][ry].typ) || !(u.dx && u.dy) || (
 #ifdef REINCARNATION
                !Is_rogue_level(&u.uz) &&
@@ -543,6 +544,9 @@ boolean test_only;
        if (Blind && !test_only) feel_location(x,y);
        if (Passes_walls && may_passwall(x,y)) {
            ;   /* do nothing */
+       } else if (tmpr->typ == IRONBARS) {
+           if (!(Passes_walls || passes_bars(youmonst.data)))
+               return FALSE;
        } else if (tunnels(youmonst.data) && !needspick(youmonst.data)) {
            /* Eat the rock. */
            if (!test_only && still_chewing(x,y)) return FALSE;
index 4d8c64b16761ea1724ae82b415b919d79b544b9f..9b06912bf5eda449887778f94365d6226c60c52b 100644 (file)
--- a/src/mon.c
+++ b/src/mon.c
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)mon.c      3.4     2002/03/09      */
+/*     SCCS Id: @(#)mon.c      3.4     2002/04/06      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -963,8 +963,7 @@ nexttry:    /* eels prefer the water, but if there is no water nearby,
               !((flag & ALLOW_WALL) && may_passwall(nx,ny)) &&
               !((flag & ALLOW_DIG) && may_dig(nx,ny))) continue;
            /* KMH -- Added iron bars */
-           if (ntyp == IRONBARS &&
-               !((flag & ALLOW_WALL) && may_passwall(nx,ny))) continue;
+           if (ntyp == IRONBARS && !(flag & ALLOW_BARS)) continue;
            if(IS_DOOR(ntyp) && !amorphous(mdat) &&
               ((levl[nx][ny].doormask & D_CLOSED && !(flag & OPENDOOR)) ||
                (levl[nx][ny].doormask & D_LOCKED && !(flag & UNLOCKDOOR))
index a51722c992ab37e7a6b9fe0691982f5205d3960c..3a9cdb03c22630c9f9fec2e061494d4e31b19684 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)mondata.c  3.4     2002/03/24      */
+/*     SCCS Id: @(#)mondata.c  3.4     2002/04/06      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -247,6 +247,16 @@ register struct permonst *ptr;
                (ptr->mlet==S_IMP && ptr != &mons[PM_TENGU])));
 }
 
+/* true iff the type of monster pass through iron bars */
+boolean
+passes_bars(mptr)
+struct permonst *mptr;
+{
+    return (boolean) (passes_walls(mptr) || amorphous(mptr) ||
+                     is_whirly(mptr) || verysmall(mptr) ||
+                     (slithy(mptr) && !bigmonst(mptr)));
+}
+
 #endif /* OVL0 */
 #ifdef OVL1
 
index 1e3bad4d2f1bfde8f6bdff60ac269f0af303e3aa..3424b730498934cb359d61b0e2e0ccf4c85314f8 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)monmove.c  3.4     2000/08/16      */
+/*     SCCS Id: @(#)monmove.c  3.4     2002/04/06      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -890,6 +890,7 @@ not_special:
        /* unicorn may not be able to avoid hero on a noteleport level */
        if (is_unicorn(ptr) && !level.flags.noteleport) flag |= NOTONL;
        if (passes_walls(ptr)) flag |= (ALLOW_WALL | ALLOW_ROCK);
+       if (passes_bars(ptr)) flag |= ALLOW_BARS;
        if (can_tunnel) flag |= ALLOW_DIG;
        if (is_human(ptr) || ptr == &mons[PM_MINOTAUR]) flag |= ALLOW_SSM;
        if (is_undead(ptr) && ptr->mlet != S_GHOST) flag |= NOGARLIC;
@@ -1048,10 +1049,10 @@ postmov:
 
                    if(here->doormask & (D_LOCKED|D_CLOSED) && amorphous(ptr)) {
                        if (flags.verbose && canseemon(mtmp))
-                           pline("%s %ss under the door.", Monnam(mtmp),
+                           pline("%s %s under the door.", Monnam(mtmp),
                                  (ptr == &mons[PM_FOG_CLOUD] ||
                                   ptr == &mons[PM_YELLOW_LIGHT])
-                                 ? "flow" : "ooze");
+                                 ? "flows" : "oozes");
                    } else if(here->doormask & D_LOCKED && can_unlock) {
                        if(btrapped) {
                            here->doormask = D_NODOOR;
@@ -1110,6 +1111,12 @@ postmov:
                        if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE))
                            add_damage(mtmp->mx, mtmp->my, 0L);
                    }
+               } else if (levl[mtmp->mx][mtmp->my].typ == IRONBARS) {
+                       if (flags.verbose && canseemon(mtmp))
+                           Norep("%s %s %s the iron bars.", Monnam(mtmp),
+                                 /* pluralization fakes verb conjugation */
+                                 makeplural(locomotion(ptr, "pass")),
+                                 passes_walls(ptr) ? "through" : "between");
                }
 
                /* possibly dig */
index a397191cbd083666c4d2f229a8fcd19744c6145c..b4e2aec757370034c6d7dd2f0e17c7ae52ed9d34 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)mthrowu.c  3.4     2001/12/10      */
+/*     SCCS Id: @(#)mthrowu.c  3.4     2002/04/06      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -312,6 +312,16 @@ m_throw(mon, x, y, dx, dy, range, obj)
            }
        }
 
+       /* also need to pre-check for bars regardless of direction,
+          but we know that isok() has already been verified;
+          the random chance for small objects hitting bars is
+          skipped when reaching them at point blank range */
+       if ((levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS &&
+               hits_bars(&singleobj, bhitpos.x, bhitpos.y, 0, 0))) {
+           (void) drop_throw(singleobj, 0, bhitpos.x, bhitpos.y);
+           return;
+       }
+
        /* Note: drop_throw may destroy singleobj.  Since obj must be destroyed
         * early to avoid the dagger bug, anyone who modifies this code should
         * be careful not to use either one after it's been freed.
@@ -437,12 +447,16 @@ m_throw(mon, x, y, dx, dy, range, obj)
                        || !isok(bhitpos.x+dx,bhitpos.y+dy)
                        /* missile hits the wall */
                        || IS_ROCK(levl[bhitpos.x+dx][bhitpos.y+dy].typ)
+                       /* missile might hit iron bars */
+                       || (levl[bhitpos.x+dx][bhitpos.y+dy].typ == IRONBARS &&
+                       hits_bars(&singleobj, bhitpos.x, bhitpos.y, !rn2(2), 0))
 #ifdef SINKS
                        /* Thrown objects "sink" */
                        || IS_SINK(levl[bhitpos.x][bhitpos.y].typ)
 #endif
                                                                ) {
-                   (void) drop_throw(singleobj, 0, bhitpos.x, bhitpos.y);
+                   if (singleobj) /* hits_bars might have destroyed it */
+                       (void) drop_throw(singleobj, 0, bhitpos.x, bhitpos.y);
                    break;
                }
                tmp_at(bhitpos.x, bhitpos.y);
@@ -747,6 +761,80 @@ int type;
        return((struct obj *) 0);
 }
 
+/* TRUE iff thrown/kicked/rolled object doesn't pass through iron bars */
+boolean
+hits_bars(obj_p, x, y, always_hit, whodidit)
+struct obj **obj_p;    /* *obj_p will be set to NULL if object breaks */
+int x, y;
+int always_hit;        /* caller can force a hit for items which would fit through */
+int whodidit;  /* 1==hero, 0=other, -1==just check whether it'll pass thru */
+{
+    struct obj *otmp = *obj_p;
+    int obj_type = otmp->otyp;
+    boolean hits = always_hit;
+
+    if (!hits)
+       switch (otmp->oclass) {
+       case WEAPON_CLASS:
+           {
+               int oskill = objects[obj_type].oc_skill;
+
+               hits = (oskill != -P_BOW  && oskill != -P_CROSSBOW &&
+                       oskill != -P_DART && oskill != -P_SHURIKEN &&
+                       oskill != P_SPEAR && oskill != P_JAVELIN &&
+                       oskill != P_KNIFE);     /* but not dagger */
+               break;
+           }
+       case ARMOR_CLASS:
+               hits = (objects[obj_type].oc_armcat != ARM_GLOVES);
+               break;
+       case TOOL_CLASS:
+               hits = (obj_type != SKELETON_KEY &&
+                       obj_type != LOCK_PICK &&
+#ifdef TOURIST
+                       obj_type != CREDIT_CARD &&
+#endif
+                       obj_type != TALLOW_CANDLE &&
+                       obj_type != WAX_CANDLE &&
+                       obj_type != LENSES &&
+                       obj_type != TIN_WHISTLE &&
+                       obj_type != MAGIC_WHISTLE);
+               break;
+       case ROCK_CLASS:        /* includes boulder */
+               if (obj_type != STATUE ||
+                       mons[otmp->corpsenm].msize > MZ_TINY) hits = TRUE;
+               break;
+       case FOOD_CLASS:
+               if (obj_type == CORPSE &&
+                       mons[otmp->corpsenm].msize > MZ_TINY) hits = TRUE;
+               break;
+       case SPBOOK_CLASS:
+       case WAND_CLASS:
+       case BALL_CLASS:
+       case CHAIN_CLASS:
+               hits = TRUE;
+               break;
+       default:
+               break;
+       }
+
+    if (hits && whodidit != -1) {
+       if (whodidit ? hero_breaks(otmp, x, y, FALSE) : breaks(otmp, x, y))
+           *obj_p = otmp = 0;          /* object is now gone */
+           /* breakage makes its own noises */
+       else if (obj_type == BOULDER || obj_type == HEAVY_IRON_BALL)
+           pline("Whang!");
+       else if (otmp->oclass == GOLD_CLASS ||
+               objects[obj_type].oc_material == GOLD ||
+               objects[obj_type].oc_material == SILVER)
+           pline("Clink!");
+       else
+           pline("Clonk!");
+    }
+
+    return hits;
+}
+
 #endif /* OVL0 */
 
 /*mthrowu.c*/
index cd3aadba4e23d830c27d72fac62a0eed2208cea3..415251345beec4fb3627a8db344a042c045cea08 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)trap.c     3.4     20021/03/29     */
+/*     SCCS Id: @(#)trap.c     3.4     2002/04/06      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -1330,6 +1330,16 @@ int style;
                        levl[bhitpos.x][bhitpos.y].doormask = D_BROKEN;
                        if (dist) unblock_point(bhitpos.x, bhitpos.y);
                }
+
+               /* if about to hit iron bars, do so now */
+               if (dist > 0 && isok(bhitpos.x + dx,bhitpos.y + dy) &&
+                       levl[bhitpos.x + dx][bhitpos.y + dy].typ == IRONBARS) {
+                   x2 = bhitpos.x,  y2 = bhitpos.y;    /* object stops here */
+                   if (hits_bars(&singleobj, x2, y2, !rn2(20), 0)) {
+                       if (!singleobj) used_up = TRUE;
+                       break;
+                   }
+               }
        }
        tmp_at(DISP_END, 0);
        if (!used_up) {
@@ -1340,6 +1350,7 @@ int style;
        } else
                return 2;
 }
+
 #endif /* OVL3 */
 #ifdef OVLB
 
index 87a104e24755359e051f529b92032a84dba26e8d..cc3bf4219593045248814dcfd5b74174174ef0fe 100644 (file)
--- a/src/zap.c
+++ b/src/zap.c
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)zap.c      3.4     2002/03/29      */
+/*     SCCS Id: @(#)zap.c      3.4     2002/04/06      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -28,7 +28,6 @@ STATIC_DCL boolean FDECL(zap_updown, (struct obj *));
 STATIC_DCL int FDECL(zhitm, (struct monst *,int,int,struct obj **));
 STATIC_DCL void FDECL(zhitu, (int,int,const char *,XCHAR_P,XCHAR_P));
 STATIC_DCL void FDECL(revive_egg, (struct obj *));
-STATIC_DCL boolean FDECL(hits_bars, (struct obj *));
 #ifdef STEED
 STATIC_DCL boolean FDECL(zap_steed, (struct obj *));
 #endif
@@ -2550,25 +2549,6 @@ register struct monst *mtmp;
 #endif /*OVL0*/
 #ifdef OVL1
 
-/* return TRUE if obj_type can't pass through iron bars */
-static boolean
-hits_bars(obj)
-struct obj *obj;
-{
-    int obj_type = obj->otyp;
-    /*
-    There should be a _lot_ of things here..., but iron ball
-    started this change and boulders, chests, and boxes were added later...
-    Corpses and statues that are at least medium size are also screened.
-    */
-    if (obj_type == BOULDER || obj_type == HEAVY_IRON_BALL || obj_type == LARGE_BOX ||
-       obj_type == CHEST   || obj_type == ICE_BOX ||
-       ((obj_type == CORPSE || obj_type == STATUE)
-         && mons[obj->corpsenm].msize >= MZ_MEDIUM))
-       return TRUE;
-    return FALSE;
-}
-
 /*
  *  Called for the following distance effects:
  *     when a weapon is thrown (weapon == THROWN_WEAPON)
@@ -2595,9 +2575,9 @@ int FDECL((*fhitm), (MONST_P, OBJ_P)),    /* fns called when mon/obj hit */
     FDECL((*fhito), (OBJ_P, OBJ_P));
 struct obj *obj;                       /* object tossed/used */
 {
-       register struct monst *mtmp;
-       register uchar typ;
-       register boolean shopdoor = FALSE;
+       struct monst *mtmp;
+       uchar typ;
+       boolean shopdoor = FALSE;
 
        if (weapon == KICKED_WEAPON) {
            /* object starts one square in front of player */
@@ -2636,8 +2616,10 @@ struct obj *obj;                 /* object tossed/used */
            typ = levl[bhitpos.x][bhitpos.y].typ;
 
            /* iron bars will block anything big enough */
-           if ((weapon == THROWN_WEAPON || weapon == KICKED_WEAPON)
-                        && typ == IRONBARS && hits_bars(obj)) {
+           if ((weapon == THROWN_WEAPON || weapon == KICKED_WEAPON) &&
+                   typ == IRONBARS &&
+                   hits_bars(&obj, x - ddx, y - ddy, !rn2(20), 1)) {
+               /* caveat: obj might now be null... */
                bhitpos.x -= ddx;
                bhitpos.y -= ddy;
                break;
@@ -2714,13 +2696,11 @@ struct obj *obj;                        /* object tossed/used */
                if(bhitpile(obj,fhito,bhitpos.x,bhitpos.y))
                    range--;
            } else {
-boolean costly = shop_keeper(*in_rooms(bhitpos.x, bhitpos.y, SHOPBASE)) &&
-                               costly_spot(bhitpos.x, bhitpos.y);
-
                if(weapon == KICKED_WEAPON &&
                      ((obj->oclass == GOLD_CLASS &&
                         OBJ_AT(bhitpos.x, bhitpos.y)) ||
-                   ship_object(obj, bhitpos.x, bhitpos.y, costly))) {
+                           ship_object(obj, bhitpos.x, bhitpos.y,
+                                       costly_spot(bhitpos.x, bhitpos.y)))) {
                        tmp_at(DISP_END, 0);
                        return (struct monst *)0;
                }