steed's (when riding, wounded leg injury applies to steed, not hero)
drinking uncursed potion of full healing or blessed potion of extra healing
heal hero's wounded legs when not riding; no effect on steed if riding
+cancellation explodes most magical traps
Platform- and/or Interface-Specific New Features
#define BURNING_OIL (MAXOCLASSES + 1) /* Can be used as input to explode. */
#define MON_EXPLODE (MAXOCLASSES + 2) /* Exploding monster (e.g. gas spore) */
+#define TRAP_EXPLODE (MAXOCLASSES + 3)
#if 0 /* moved to decl.h so that makedefs.c won't see them */
extern const struct class_sym
#define is_pit(ttyp) ((ttyp) == PIT || (ttyp) == SPIKED_PIT)
#define is_hole(ttyp) ((ttyp) == HOLE || (ttyp) == TRAPDOOR)
+#define undestroyable_trap(ttyp) ((ttyp) == MAGIC_PORTAL \
+ || (ttyp) == VIBRATING_SQUARE)
+#define is_magical_trap(ttyp) ((ttyp) == TELEP_TRAP \
+ || (ttyp) == LEVEL_TELEP \
+ || (ttyp) == MAGIC_TRAP \
+ || (ttyp) == ANTI_MAGIC \
+ || (ttyp) == POLY_TRAP)
/* "transportation" traps */
#define is_xport(ttyp) ((ttyp) >= TELEP_TRAP && (ttyp) <= MAGIC_PORTAL)
} else if ((IS_ROCK(levl[x][y].typ) && levl[x][y].typ != SDOOR
&& (levl[x][y].wall_info & W_NONDIGGABLE) != 0)
|| (ttmp
- && (ttmp->ttyp == MAGIC_PORTAL
- || ttmp->ttyp == VIBRATING_SQUARE
+ && (undestroyable_trap(ttmp->ttyp)
|| (!Can_dig_down(&u.uz) && !levl[x][y].candig)))) {
if (verbose)
pline_The("%s here is too hard to %s.", surface(x, y), verb);
nohole = (!Can_dig_down(&u.uz) && !lev->candig);
old_typ = lev->typ;
- if ((ttmp && (ttmp->ttyp == MAGIC_PORTAL
- || ttmp->ttyp == VIBRATING_SQUARE || nohole))
+ if ((ttmp && (undestroyable_trap(ttmp->ttyp) || nohole))
|| (IS_ROCK(old_typ) && old_typ != SDOOR
&& (lev->wall_info & W_NONDIGGABLE) != 0)) {
pline_The("%s %shere is too hard to dig in.", surface(dig_x, dig_y),
tmp_at(DISP_END, 0); /* clear the explosion */
} else {
- if (olet == MON_EXPLODE) {
+ if (olet == MON_EXPLODE || olet == TRAP_EXPLODE) {
str = "explosion";
generic = TRUE;
}
It might still fail if there's a dungeon feature here. */
struct trap *t = t_at(x, y);
- if (t && t->ttyp != MAGIC_PORTAL && t->ttyp != VIBRATING_SQUARE)
+ if (t && !undestroyable_trap(t->ttyp))
deltrap(t);
if (bad_location(x, y, nlx, nly, nhx, nhy))
return FALSE;
}
while (ttmp) {
- if ((ttmp->ttyp == MAGIC_PORTAL || ttmp->ttyp == VIBRATING_SQUARE
- || is_hole(ttmp->ttyp))
+ if ((undestroyable_trap(ttmp->ttyp) || is_hole(ttmp->ttyp))
&& !selection_getpoint(ttmp->tx, ttmp->ty, ov))
selection_floodfill(ov, ttmp->tx, ttmp->ty, TRUE);
ttmp = ttmp->ntrap;
struct rm *lev = &levl[x][y];
if ((ttmp = t_at(x, y)) != 0) {
- if (ttmp->ttyp == MAGIC_PORTAL || ttmp->ttyp == VIBRATING_SQUARE)
+ if (undestroyable_trap(ttmp->ttyp))
return (struct trap *) 0;
oldplace = TRUE;
if (u.utrap && x == u.ux && y == u.uy
trapname(ttype, FALSE));
return;
}
- if (!Fumbling && ttype != MAGIC_PORTAL && ttype != VIBRATING_SQUARE
+ if (!Fumbling && !undestroyable_trap(ttype)
&& ttype != ANTI_MAGIC && !forcebungle && !plunged
&& !conj_pit && !adj_pit
&& (!rn2(5) || (is_pit(ttype)
static void revive_egg(struct obj *);
static boolean zap_steed(struct obj *);
static void skiprange(int, int *, int *);
+static void maybe_explode_trap(struct trap *, struct obj *);
static int zap_hit(int, int);
static void disintegrate_mon(struct monst *, int, const char *);
static int adtyp_to_prop(int);
break;
}
}
+
+ maybe_explode_trap(ttmp, obj);
+ /* note: ttmp might be now gone */
+
} else if (u.dz < 0) {
/* zapping upward */
*skipend = tmp - 1;
}
+/* maybe explode a trap hit by object otmp's effect;
+ cancellation beam hitting a magical trap causes an explosion.
+ might delete the trap. */
+static void
+maybe_explode_trap(struct trap *ttmp, struct obj *otmp)
+{
+ if (!ttmp || !otmp)
+ return;
+ if (otmp->otyp == WAN_CANCELLATION || otmp->otyp == SPE_CANCELLATION) {
+ xchar x = ttmp->tx, y = ttmp->ty;
+
+ if (undestroyable_trap(ttmp->ttyp)) {
+ shieldeff(x, y);
+ if (cansee(x, y)) {
+ ttmp->tseen = 1;
+ newsym(x, y);
+ }
+ } else if (is_magical_trap(ttmp->ttyp)) {
+ if (!Deaf)
+ pline("Kaboom!");
+ explode(x, y, -WAN_CANCELLATION,
+ 20+d(3,6), TRAP_EXPLODE, EXPL_MAGICAL);
+ deltrap(ttmp);
+ newsym(x, y);
+ }
+ }
+}
+
/*
* Called for the following distance effects:
* when a weapon is thrown (weapon == THROWN_WEAPON)
learnwand(obj);
}
+ if (weapon == ZAPPED_WAND)
+ maybe_explode_trap(t_at(g.bhitpos.x, g.bhitpos.y), obj);
+
mtmp = m_at(g.bhitpos.x, g.bhitpos.y);
/*