From 829f9f65f7f5fe0e6c036c1f40ec540ca9fc4625 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 23 Jan 2024 19:01:31 +0200 Subject: [PATCH] Split out harmless-to-monster trap Also make the code much easier to understand, and more-or-less match hero trap triggering. --- include/extern.h | 1 + src/mon.c | 19 +---------- src/trap.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 18 deletions(-) diff --git a/include/extern.h b/include/extern.h index 67544d1b1..6e637b2e3 100644 --- a/include/extern.h +++ b/include/extern.h @@ -3099,6 +3099,7 @@ extern struct monst *activate_statue_trap(struct trap *, coordxy, coordxy, extern int immune_to_trap(struct monst *, unsigned) NO_NNARGS; /* revisit */ extern void set_utrap(unsigned, unsigned); extern void reset_utrap(boolean); +extern boolean m_harmless_trap(struct monst *, struct trap *); extern void dotrap(struct trap *, unsigned) NONNULLARG1; extern void seetrap(struct trap *) NONNULLARG1; extern void feeltrap(struct trap *) NONNULLARG1; diff --git a/src/mon.c b/src/mon.c index c3e44b590..b6c0bff0e 100644 --- a/src/mon.c +++ b/src/mon.c @@ -2128,24 +2128,7 @@ mfndpos( ttmp->ttyp); continue; } - if ((ttmp->ttyp != RUST_TRAP - || mdat == &mons[PM_IRON_GOLEM]) - && ttmp->ttyp != STATUE_TRAP - && ttmp->ttyp != VIBRATING_SQUARE - && ((!is_pit(ttmp->ttyp) && !is_hole(ttmp->ttyp)) - || (!is_flyer(mdat) && !is_floater(mdat) - && !is_clinger(mdat)) || Sokoban) - && (ttmp->ttyp != SLP_GAS_TRAP || !resists_sleep(mon)) - && (ttmp->ttyp != BEAR_TRAP - || (mdat->msize > MZ_SMALL && !amorphous(mdat) - && !is_flyer(mdat) && !is_floater(mdat) - && !is_whirly(mdat) && !unsolid(mdat))) - && (ttmp->ttyp != FIRE_TRAP || !resists_fire(mon)) - && (ttmp->ttyp != SQKY_BOARD || !is_flyer(mdat)) - && (ttmp->ttyp != WEB - || (!amorphous(mdat) && !webmaker(mdat) - && !is_whirly(mdat) && !unsolid(mdat))) - && (ttmp->ttyp != ANTI_MAGIC || !resists_magm(mon))) { + if (!m_harmless_trap(mon, ttmp)) { if (!(flag & ALLOW_TRAPS)) { if (mon_knows_traps(mon, ttmp->ttyp)) continue; diff --git a/src/trap.c b/src/trap.c index f14590290..5e46a03b6 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1049,6 +1049,88 @@ check_in_air(struct monst *mtmp, unsigned trflags) || ((is_you ? Flying : is_flyer(mtmp->data)) && !plunged)); } +/* is trap ttmp harmless to monster mtmp? */ +boolean +m_harmless_trap(struct monst *mtmp, struct trap *ttmp) +{ + struct permonst *mdat = mtmp->data; + + /* this handles most of the traps, but those are still included + in the switch case below for completeness */ + if (!Sokoban && floor_trigger(ttmp->ttyp) && check_in_air(mtmp, 0L)) + return TRUE; + + switch (ttmp->ttyp) { + case ARROW_TRAP: + break; + case DART_TRAP: + break; + case ROCKTRAP: + break; + case SQKY_BOARD: + break; + case BEAR_TRAP: + if (mdat->msize <= MZ_SMALL || amorphous(mdat) + || is_whirly(mdat) || unsolid(mdat)) + return TRUE; + break; + case LANDMINE: + break; + case ROLLING_BOULDER_TRAP: + break; + case SLP_GAS_TRAP: + if (resists_sleep(mtmp) || defended(mtmp, AD_SLEE)) + return TRUE; + break; + case RUST_TRAP: + if (mdat != &mons[PM_IRON_GOLEM]) + return TRUE; + break; + case FIRE_TRAP: + if (resists_fire(mtmp) || defended(mtmp, AD_FIRE)) + return TRUE; + break; + case PIT: + /*FALLTHRU*/ + case SPIKED_PIT: + /*FALLTHRU*/ + case HOLE: + /*FALLTHRU*/ + case TRAPDOOR: + if (is_clinger(mdat) && !Sokoban) + return TRUE; + break; + case TELEP_TRAP: + break; + case LEVEL_TELEP: + break; + case MAGIC_PORTAL: + break; + case WEB: + if (amorphous(mdat) || webmaker(mdat) + || is_whirly(mdat) || unsolid(mdat)) + return TRUE; + break; + case STATUE_TRAP: + return TRUE; + case MAGIC_TRAP: + return TRUE; /* usually */ + case ANTI_MAGIC: + if (resists_magm(mtmp) || defended(mtmp, AD_MAGM)) + return TRUE; + break; + case POLY_TRAP: + break; + case VIBRATING_SQUARE: + return TRUE; + default: + impossible("m_harmless_trap: unknown trap %i", ttmp->ttyp); + break; + } + + return FALSE; +} + static int trapeffect_arrow_trap( struct monst *mtmp,