Most traps now require touching the floor to trigger
It was silly how some clearly mechanical traps didn't consider flight or levitation when to trigger. Do those checks in dotrap/mintrap making hero and monster trap triggering match more closely.
This commit is contained in:
@@ -818,6 +818,7 @@ discovering an object on first turn with persistent inventory enabled might
|
|||||||
not update inventory info for that item (autopickup a blank scroll
|
not update inventory info for that item (autopickup a blank scroll
|
||||||
or spellbook and read it as first action; it becomes discovered but
|
or spellbook and read it as first action; it becomes discovered but
|
||||||
will still be shown as if undiscovered until next inventory update)
|
will still be shown as if undiscovered until next inventory update)
|
||||||
|
most traps now require touching the floor to trigger
|
||||||
|
|
||||||
|
|
||||||
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
|
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
|
||||||
|
|||||||
+63
-19
@@ -11,6 +11,8 @@ static boolean keep_saddle_with_steedcorpse(unsigned, struct obj *,
|
|||||||
struct obj *);
|
struct obj *);
|
||||||
static boolean mu_maybe_destroy_web(struct monst *, boolean, struct trap *);
|
static boolean mu_maybe_destroy_web(struct monst *, boolean, struct trap *);
|
||||||
static struct obj *t_missile(int, struct trap *);
|
static struct obj *t_missile(int, struct trap *);
|
||||||
|
static boolean floor_trigger(int);
|
||||||
|
static boolean check_in_air(struct monst *, unsigned);
|
||||||
static int trapeffect_arrow_trap(struct monst *, struct trap *, unsigned);
|
static int trapeffect_arrow_trap(struct monst *, struct trap *, unsigned);
|
||||||
static int trapeffect_dart_trap(struct monst *, struct trap *, unsigned);
|
static int trapeffect_dart_trap(struct monst *, struct trap *, unsigned);
|
||||||
static int trapeffect_rocktrap(struct monst *, struct trap *, unsigned);
|
static int trapeffect_rocktrap(struct monst *, struct trap *, unsigned);
|
||||||
@@ -930,6 +932,43 @@ reset_utrap(boolean msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* is trap type ttyp triggered by touching the floor? */
|
||||||
|
static boolean
|
||||||
|
floor_trigger(int ttyp)
|
||||||
|
{
|
||||||
|
switch (ttyp) {
|
||||||
|
case ARROW_TRAP:
|
||||||
|
case DART_TRAP:
|
||||||
|
case ROCKTRAP:
|
||||||
|
case SQKY_BOARD:
|
||||||
|
case BEAR_TRAP:
|
||||||
|
case LANDMINE:
|
||||||
|
case ROLLING_BOULDER_TRAP:
|
||||||
|
case SLP_GAS_TRAP:
|
||||||
|
case RUST_TRAP:
|
||||||
|
case FIRE_TRAP:
|
||||||
|
case PIT:
|
||||||
|
case SPIKED_PIT:
|
||||||
|
case HOLE:
|
||||||
|
case TRAPDOOR:
|
||||||
|
return TRUE;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return TRUE if monster mtmp is up in the air, considering trap flags */
|
||||||
|
static boolean
|
||||||
|
check_in_air(struct monst *mtmp, unsigned trflags)
|
||||||
|
{
|
||||||
|
boolean plunged = (trflags & TOOKPLUNGE) != 0;
|
||||||
|
|
||||||
|
return (is_floater(mtmp->data)
|
||||||
|
|| (is_flyer(mtmp->data) && !plunged)
|
||||||
|
|| (mtmp == &g.youmonst ?
|
||||||
|
(Levitation || (Flying && !plunged)) : 0));
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
trapeffect_arrow_trap(
|
trapeffect_arrow_trap(
|
||||||
struct monst *mtmp,
|
struct monst *mtmp,
|
||||||
@@ -2456,15 +2495,17 @@ dotrap(register struct trap* trap, unsigned int trflags)
|
|||||||
a_your[trap->madeby_u],
|
a_your[trap->madeby_u],
|
||||||
trapname(ttype, TRUE)); /* do force "pit" while hallucinating */
|
trapname(ttype, TRUE)); /* do force "pit" while hallucinating */
|
||||||
/* then proceed to normal trap effect */
|
/* then proceed to normal trap effect */
|
||||||
} else if (already_seen && !forcetrap) {
|
} else if (!forcetrap) {
|
||||||
if ((Levitation || (Flying && !plunged))
|
if (floor_trigger(ttype) && check_in_air(&g.youmonst, trflags)) {
|
||||||
&& (is_pit(ttype) || ttype == HOLE || ttype == BEAR_TRAP)) {
|
if (already_seen) {
|
||||||
You("%s over %s %s.", Levitation ? "float" : "fly",
|
You("%s over %s %s.", Levitation ? "float" : "fly",
|
||||||
a_your[trap->madeby_u],
|
(ttype == ARROW_TRAP && !trap->madeby_u)
|
||||||
trapname(ttype, FALSE));
|
? "an" : a_your[trap->madeby_u],
|
||||||
|
trapname(ttype, FALSE));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!Fumbling && !undestroyable_trap(ttype)
|
if (already_seen && !Fumbling && !undestroyable_trap(ttype)
|
||||||
&& ttype != ANTI_MAGIC && !forcebungle && !plunged
|
&& ttype != ANTI_MAGIC && !forcebungle && !plunged
|
||||||
&& !conj_pit && !adj_pit
|
&& !conj_pit && !adj_pit
|
||||||
&& (!rn2(5) || (is_pit(ttype)
|
&& (!rn2(5) || (is_pit(ttype)
|
||||||
@@ -3130,21 +3171,24 @@ mintrap(register struct monst *mtmp, long mintrapflags)
|
|||||||
} else {
|
} else {
|
||||||
register int tt = trap->ttyp;
|
register int tt = trap->ttyp;
|
||||||
boolean forcetrap = ((mintrapflags & FORCETRAP) != 0);
|
boolean forcetrap = ((mintrapflags & FORCETRAP) != 0);
|
||||||
boolean inescapable = (forcetrap
|
/* monster has seen such a trap before */
|
||||||
|| ((tt == HOLE || tt == PIT)
|
boolean already_seen = ((mtmp->mtrapseen & (1 << (tt - 1))) != 0
|
||||||
&& Sokoban && !trap->madeby_u));
|
|| (tt == HOLE && !mindless(mptr)));
|
||||||
|
|
||||||
/* true when called from dotrap, inescapable is not an option */
|
if (mtmp == u.usteed) {
|
||||||
if (mtmp == u.usteed)
|
/* true when called from dotrap, inescapable is not an option */
|
||||||
inescapable = TRUE;
|
} else if (Sokoban && (is_pit(tt) || is_hole(tt)) && !trap->madeby_u) {
|
||||||
if (!inescapable && ((mtmp->mtrapseen & (1 << (tt - 1))) != 0
|
/* nothing here, the trap effects will handle messaging */
|
||||||
|| (tt == HOLE && !mindless(mptr)))) {
|
} else if (!forcetrap) {
|
||||||
/* it has been in such a trap - perhaps it escapes */
|
if (floor_trigger(tt) && check_in_air(mtmp, mintrapflags)) {
|
||||||
if (rn2(4))
|
return Trap_Effect_Finished;
|
||||||
|
}
|
||||||
|
if (already_seen && rn2(4))
|
||||||
return Trap_Effect_Finished;
|
return Trap_Effect_Finished;
|
||||||
} else {
|
|
||||||
mtmp->mtrapseen |= (1 << (tt - 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mtmp->mtrapseen |= (1 << (tt - 1));
|
||||||
|
|
||||||
/* Monster is aggravated by being trapped by you.
|
/* Monster is aggravated by being trapped by you.
|
||||||
Recognizing who made the trap isn't completely
|
Recognizing who made the trap isn't completely
|
||||||
unreasonable; everybody has their own style. */
|
unreasonable; everybody has their own style. */
|
||||||
|
|||||||
Reference in New Issue
Block a user