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:
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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*/
|
||||
|
||||
13
src/trap.c
13
src/trap.c
@@ -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
|
||||
|
||||
|
||||
40
src/zap.c
40
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user