multiple iron bars fixes

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.
This commit is contained in:
nethack.rankin
2002-04-07 10:43:59 +00:00
parent b940ca0ee7
commit 812b53799d
12 changed files with 158 additions and 45 deletions

View 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

View 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 ### */

View 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

View File

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

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

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

View File

@@ -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))

View 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

View 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 */

View 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*/

View 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

View File

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