/* ### mon.c ### */
E void NDECL(mon_sanity_check);
+E int FDECL(m_poisongas_ok, (struct monst *));
E int FDECL(undead_to_corpse, (int));
E int FDECL(genus, (int, int));
E int FDECL(pm_to_cham, (int));
#define SHIFT_SEENMSG 0x01 /* put out a message if in sight */
#define SHIFT_MSG 0x02 /* always put out a message */
+/* m_poisongas_ok() return values */
+#define M_POISONGAS_BAD 0 /* poison gas is bad */
+#define M_POISONGAS_MINOR 1 /* poison gas is ok, maybe causes coughing */
+#define M_POISONGAS_OK 2 /* ignores poison gas completely */
+
/* flags for deliver_obj_to_mon */
#define DF_NONE 0x00
#define DF_RANDOM 0x01
}
}
+/* Would monster be OK with poison gas? */
+/* Does not check for actual poison gas at the location. */
+/* Returns one of M_POISONGAS_foo */
+int
+m_poisongas_ok(mtmp)
+struct monst *mtmp;
+{
+ int px, py;
+
+ /* Non living and non breathing monsters are not concerned */
+ if (nonliving(mtmp->data) || is_vampshifter(mtmp)
+ || breathless(mtmp->data))
+ return M_POISONGAS_OK;
+ /* not is_swimmer(); assume that non-fish are swimming on
+ the surface and breathing the air above it periodically
+ unless located at water spot on plane of water */
+ px = (mtmp == &g.youmonst) ? u.ux : mtmp->mx;
+ py = (mtmp == &g.youmonst) ? u.uy : mtmp->my;
+ if ((mtmp->data->mlet == S_EEL || Is_waterlevel(&u.uz))
+ && isok(px, py) && is_pool(px, py))
+ return M_POISONGAS_OK;
+ /* exclude monsters with poison gas breath attack:
+ adult green dragon and Chromatic Dragon (and iron golem,
+ but nonliving() and breathless() tests also catch that) */
+ if (attacktype_fordmg(mtmp->data, AT_BREA, AD_DRST)
+ || attacktype_fordmg(mtmp->data, AT_BREA, AD_RBRE))
+ return M_POISONGAS_OK;
+ if ((mtmp == &g.youmonst)
+ && (u.uinvulnerable || Breathless || Underwater))
+ return M_POISONGAS_OK;
+ if (resists_poison(mtmp) || (mtmp == &g.youmonst) && Poison_resistance)
+ return M_POISONGAS_MINOR;
+ return M_POISONGAS_BAD;
+}
/* convert the monster index of an undead to its living counterpart */
int
if (mdat == &mons[PM_FLOATING_EYE]) /* prefers to avoid heat */
lavaok = FALSE;
thrudoor = ((flag & (ALLOW_WALL | BUSTDOOR)) != 0L);
- poisongas_ok = ((nonliving(mdat) || is_vampshifter(mon)
- || breathless(mdat)) || resists_poison(mon));
+ poisongas_ok = (m_poisongas_ok(mon) == M_POISONGAS_OK);
in_poisongas = ((gas_reg = visible_region_at(x,y)) != 0
&& gas_reg->glyph == gas_glyph);
reg = (NhRegion *) p1;
dam = reg->arg.a_int;
if (p2 == (genericptr_t) 0) { /* This means *YOU* Bozo! */
- if (u.uinvulnerable || nonliving(g.youmonst.data) || Breathless
- || Underwater)
+ if (m_poisongas_ok(&g.youmonst) == M_POISONGAS_OK)
return FALSE;
if (!Blind) {
Your("%s sting.", makeplural(body_part(EYE)));
} else { /* A monster is inside the cloud */
mtmp = (struct monst *) p2;
- /* Non living and non breathing monsters are not concerned;
- adult green dragon is not affected by gas cloud, baby one is */
- if (!(nonliving(mtmp->data) || is_vampshifter(mtmp))
- && !breathless(mtmp->data)
- /* not is_swimmer(); assume that non-fish are swimming on
- the surface and breathing the air above it periodically
- unless located at water spot on plane of water */
- && !((mtmp->data->mlet == S_EEL || Is_waterlevel(&u.uz))
- && is_pool(mtmp->mx, mtmp->my))
- /* exclude monsters with poison gas breath attack:
- adult green dragon and Chromatic Dragon (and iron golem,
- but nonliving() and breathless() tests also catch that) */
- && !(attacktype_fordmg(mtmp->data, AT_BREA, AD_DRST)
- || attacktype_fordmg(mtmp->data, AT_BREA, AD_RBRE))) {
+ if (m_poisongas_ok(mtmp) != M_POISONGAS_OK) {
if (cansee(mtmp->mx, mtmp->my))
pline("%s coughs!", Monnam(mtmp));
if (heros_fault(reg))