Split out harmless-to-monster trap

Also make the code much easier to understand, and
more-or-less match hero trap triggering.
This commit is contained in:
Pasi Kallinen
2024-01-23 19:01:31 +02:00
parent 7fa74d0199
commit 829f9f65f7
3 changed files with 84 additions and 18 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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,