new effect for reading a scroll of light while confused
allow digging an adjacent pit with wand of digging while trapped in a pit
#terrain command for debug mode
+digging can activate or disarm some types of traps
Platform- and/or Interface-Specific New Features
E int NDECL(holetime);
E boolean FDECL(dig_check, (struct monst *, BOOLEAN_P, int, int));
E void FDECL(digactualhole, (int,int,struct monst *,int));
-E boolean FDECL(dighole, (BOOLEAN_P, coord *));
+E boolean FDECL(dighole, (BOOLEAN_P,BOOLEAN_P,coord *));
E int FDECL(use_pick_axe, (struct obj *));
E int FDECL(use_pick_axe2, (struct obj *));
E boolean FDECL(mdig_tunnel, (struct monst *));
E boolean NDECL(drown);
E void FDECL(drain_en, (int));
E int NDECL(dountrap);
+E void FDECL(cnv_trap_obj, (int,int,struct trap *,BOOLEAN_P));
E int FDECL(untrap, (BOOLEAN_P));
E boolean FDECL(chest_trap, (struct obj *,int,BOOLEAN_P));
E void FDECL(deltrap, (struct trap *));
-/* SCCS Id: @(#)hack.h 3.5 2006/02/03 */
+/* SCCS Id: @(#)hack.h 3.5 2006/04/07 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
#define PICK_RIGID 1
/* Flags to control dotrap() in trap.c */
-#define NOWEBMSG 0x01 /* suppress stumble into web message */
-#define FORCEBUNGLE 0x02 /* adjustments appropriate for bungling */
-#define RECURSIVETRAP 0x04 /* trap changed into another type this same turn */
-#define TOOKPLUNGE 0x08 /* used '>' to enter pit below you */
+#define FORCETRAP 0x01 /* triggering not left to chance */
+#define NOWEBMSG 0x02 /* suppress stumble into web message */
+#define FORCEBUNGLE 0x04 /* adjustments appropriate for bungling */
+#define RECURSIVETRAP 0x08 /* trap changed into another type this same turn */
+#define TOOKPLUNGE 0x10 /* used '>' to enter pit below you */
/* Flags to control test_move in hack.c */
#define DO_MOVE 0 /* really doing the move */
if (context.digging.effort > 250 ||
(ttmp && ttmp->ttyp == HOLE)) {
- (void) dighole(FALSE, (coord *)0);
+ (void) dighole(FALSE, FALSE, (coord *)0);
(void) memset((genericptr_t)&context.digging, 0,
- sizeof (struct dig_info));
+ sizeof context.digging);
return(0); /* done with digging */
}
if (context.digging.effort <= 50 ||
(ttmp && (ttmp->ttyp == TRAPDOOR ||
- ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT)))
+ ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT))) {
return(1);
+ } else if (ttmp && (ttmp->ttyp == LANDMINE ||
+ (ttmp->ttyp == BEAR_TRAP && !u.utrap))) {
+ /* digging onto a set object trap triggers it;
+ hero should have used #untrap first */
+ dotrap(ttmp, FORCETRAP);
+ /* restart completely from scratch if we resume digging */
+ (void) memset((genericptr_t)&context.digging, 0,
+ sizeof context.digging);
+ return 0;
+ } else if (ttmp && ttmp->ttyp == BEAR_TRAP && u.utrap) {
+ if (rnl(7) > (Fumbling ? 1 : 4)) {
+ char kbuf[BUFSZ];
+ int dmg = dmgval(uwep, &youmonst) + dbon();
+
+ if (dmg < 1) dmg = 1;
+ else if (uarmf) dmg = (dmg + 1) / 2;
+ You("hit yourself in the %s.", body_part(FOOT));
+ Sprintf(kbuf, "chopping off %s own %s",
+ uhis(), body_part(FOOT));
+ losehp(Maybe_Half_Phys(dmg), kbuf, KILLED_BY);
+ } else {
+ You("destroy the bear trap with %s.",
+ yobjnam(uwep, (const char *)0));
+ u.utrap = 0; /* release from trap */
+ deltrap(ttmp);
+ }
+ /* we haven't made any progress toward a pit yet */
+ context.digging.effort = 0;
+ return 0;
+ }
if (IS_ALTAR(lev->typ)) {
altar_wrath(dpx, dpy);
angry_priest();
}
- if (dighole(TRUE, (coord *)0)) { /* make pit at <u.ux,u.uy> */
+ /* make pit at <u.ux,u.uy> */
+ if (dighole(TRUE, FALSE, (coord *)0)) {
context.digging.level.dnum = 0;
context.digging.level.dlevel = -1;
}
/* return TRUE if digging succeeded, FALSE otherwise */
boolean
-dighole(pit_only, cc)
-boolean pit_only;
+dighole(pit_only, by_magic, cc)
+boolean pit_only, by_magic;
coord *cc;
{
register struct trap *ttmp;
return TRUE;
}
+ /* magical digging disarms settable traps */
+ if (by_magic && ttmp &&
+ (ttmp->ttyp == LANDMINE || ttmp->ttyp == BEAR_TRAP)) {
+ int otyp = (ttmp->ttyp == LANDMINE) ? LAND_MINE : BEARTRAP;
+
+ /* convert trap into buried object (deletes trap) */
+ cnv_trap_obj(otyp, 1, ttmp, TRUE);
+ }
+
/* finally we get to make a hole */
if (nohole || pit_only)
digactualhole(dig_x, dig_y, BY_YOU, PIT);
dotrap(trap, FORCEBUNGLE);
/* might escape trap and still be teetering at brink */
if (!u.utrap) cant_reach_floor(u.ux, u.uy, FALSE, TRUE);
- } else if (!ispick) {
+ } else if (!ispick &&
+ /* can only dig down with an axe if stuck in a bear trap */
+ (!trap || !u.utrap || u.utraptype != TT_BEARTRAP)) {
pline("%s merely scratches the %s.",
Yobjnam2(obj, (char *)0), surface(u.ux,u.uy));
u_wipe_engr(3);
} else {
- if (context.digging.pos.x != u.ux || context.digging.pos.y != u.uy ||
- !on_level(&context.digging.level, &u.uz) || !context.digging.down) {
+ if (context.digging.pos.x != u.ux ||
+ context.digging.pos.y != u.uy ||
+ !on_level(&context.digging.level, &u.uz) ||
+ !context.digging.down) {
context.digging.chew = FALSE;
context.digging.down = TRUE;
context.digging.warned = FALSE;
newsym(u.ux, u.uy);
} else {
watch_dig((struct monst *)0, u.ux, u.uy, TRUE);
- (void) dighole(FALSE, (coord *)0);
+ (void) dighole(FALSE, TRUE, (coord *)0);
}
}
return;
if (buf[0]) pline("%s", buf);
} else {
/* this can also result in a pool at zx,zy */
- dighole(TRUE, &cc);
+ dighole(TRUE, TRUE, &cc);
adjpit = t_at(zx,zy);
}
}
"ooze" : "phase", surface(u.ux, u.uy));
if(tunnels(youmonst.data) && !needspick(youmonst.data))
- good = dighole(TRUE, (coord *)0);
+ good = dighole(TRUE, FALSE, (coord *)0);
else good = TRUE;
if(good) unearth_you();
}
STATIC_DCL void NDECL(domagictrap);
STATIC_DCL boolean FDECL(emergency_disrobe,(boolean *));
STATIC_DCL int FDECL(untrap_prob, (struct trap *ttmp));
-STATIC_DCL void FDECL(cnv_trap_obj, (int, int, struct trap *));
STATIC_DCL void FDECL(move_into_trap, (struct trap *));
STATIC_DCL int FDECL(try_disarm, (struct trap *,BOOLEAN_P));
STATIC_DCL void FDECL(reward_untrap, (struct trap *, struct monst *));
{
register int ttype = trap->ttyp;
register struct obj *otmp;
- boolean already_seen = trap->tseen;
- boolean webmsgok = (!(trflags & NOWEBMSG));
- boolean forcebungle = (trflags & FORCEBUNGLE);
- boolean plunged = (trflags & TOOKPLUNGE);
- boolean adj_pit = conjoined_pits(trap, t_at(u.ux0,u.uy0), TRUE);
+ boolean already_seen = trap->tseen,
+ forcetrap = (trflags & FORCETRAP) != 0,
+ webmsgok = (trflags & NOWEBMSG) == 0,
+ forcebungle = (trflags & FORCEBUNGLE) != 0,
+ plunged = (trflags & TOOKPLUNGE) != 0,
+ adj_pit = conjoined_pits(trap, t_at(u.ux0,u.uy0), TRUE);
#ifdef STEED
int steed_article = ARTICLE_THE;
#endif
a_your[trap->madeby_u],
defsyms[trap_to_defsym(ttype)].explanation);
/* then proceed to normal trap effect */
- } else if (already_seen) {
+ } else if (already_seen && !forcetrap) {
if ((Levitation || Flying) &&
(ttype == PIT || ttype == SPIKED_PIT || ttype == HOLE ||
ttype == BEAR_TRAP)) {
break;
case SQKY_BOARD: /* stepped on a squeaky board */
- if (Levitation || Flying) {
+ if ((Levitation || Flying) && !forcetrap) {
if (!Blind) {
seetrap(trap);
if (Hallucination)
break;
case BEAR_TRAP:
- if(Levitation || Flying) break;
+ if ((Levitation || Flying) && !forcetrap) break;
feeltrap(trap);
if(amorphous(youmonst.data) || is_whirly(youmonst.data) ||
unsolid(youmonst.data)) {
unsigned steed_mid = 0;
struct obj *saddle = 0;
#endif
- if (Levitation || Flying) {
+ if ((Levitation || Flying) && !forcetrap) {
if (!already_seen && rn2(3)) break;
feeltrap(trap);
pline("%s %s in a pile of soil below you.",
}
/* Replace trap with object(s). Helge Hafting */
-STATIC_OVL void
-cnv_trap_obj(otyp, cnt, ttmp)
+void
+cnv_trap_obj(otyp, cnt, ttmp, bury_it)
int otyp;
int cnt;
struct trap *ttmp;
+boolean bury_it;
{
struct obj *otmp = mksobj(otyp, TRUE, FALSE);
- otmp->quan=cnt;
+
+ otmp->quan = cnt;
otmp->owt = weight(otmp);
/* Only dart traps are capable of being poisonous */
if (otyp != DART)
otmp->opoisoned = 0;
place_object(otmp, ttmp->tx, ttmp->ty);
- /* Sell your own traps only... */
- if (ttmp->madeby_u) sellobj(otmp, ttmp->tx, ttmp->ty);
- stackobj(otmp);
+ if (bury_it) {
+ /* magical digging first disarms this trap, then will unearth it */
+ (void) bury_an_obj(otmp);
+ } else {
+ /* Sell your own traps only... */
+ if (ttmp->madeby_u) sellobj(otmp, ttmp->tx, ttmp->ty);
+ stackobj(otmp);
+ }
newsym(ttmp->tx, ttmp->ty);
+ if (u.utrap && ttmp->tx == u.ux && ttmp->ty == u.uy) u.utrap = 0;
deltrap(ttmp);
}
} else {
if (ttmp->ttyp == BEAR_TRAP) {
You("disarm %s bear trap.", the_your[ttmp->madeby_u]);
- cnv_trap_obj(BEARTRAP, 1, ttmp);
+ cnv_trap_obj(BEARTRAP, 1, ttmp, FALSE);
} else /* if (ttmp->ttyp == WEB) */ {
You("succeed in removing %s web.", the_your[ttmp->madeby_u]);
deltrap(ttmp);
if (fails < 2) return fails;
You("disarm %s land mine.", the_your[ttmp->madeby_u]);
- cnv_trap_obj(LAND_MINE, 1, ttmp);
+ cnv_trap_obj(LAND_MINE, 1, ttmp, FALSE);
return 1;
}
if (fails < 2) return fails;
You("disarm %s trap.", the_your[ttmp->madeby_u]);
- cnv_trap_obj(otyp, 50-rnl(50), ttmp);
+ cnv_trap_obj(otyp, 50-rnl(50), ttmp, FALSE);
return 1;
}