-/* SCCS Id: @(#)mondata.h 3.5 2005/10/05 */
+/* SCCS Id: @(#)mondata.h 3.5 2007/04/27 */
/* Copyright (c) 1989 Mike Threepoint */
/* NetHack may be freely redistributed. See license for details. */
#define slithy(ptr) (((ptr)->mflags1 & M1_SLITHY) != 0L)
#define is_wooden(ptr) ((ptr) == &mons[PM_WOOD_GOLEM])
#define thick_skinned(ptr) (((ptr)->mflags1 & M1_THICK_HIDE) != 0L)
+#define slimeproof(ptr) ((ptr) == &mons[PM_GREEN_SLIME] || \
+ flaming(ptr) || noncorporeal(ptr))
#define lays_eggs(ptr) (((ptr)->mflags1 & M1_OVIPAROUS) != 0L)
#define regenerates(ptr) (((ptr)->mflags1 & M1_REGEN) != 0L)
#define perceives(ptr) (((ptr)->mflags1 & M1_SEE_INVIS) != 0L)
return;
}
case PM_GREEN_SLIME:
- if (!Slimed && !Unchanging && !flaming(youmonst.data) &&
- youmonst.data != &mons[PM_GREEN_SLIME]) {
+ if (!Slimed && !Unchanging && !slimeproof(youmonst.data)) {
You("don't feel very well.");
make_slimed(10L, (char*) 0);
delayed_killer(SLIMED, KILLED_BY_AN, nul);
!poly_when_stoned(youmonst.data));
if (mnum == PM_GREEN_SLIME)
- stoneorslime = (!Unchanging && !flaming(youmonst.data) &&
- youmonst.data != &mons[PM_GREEN_SLIME]);
+ stoneorslime = (!Unchanging && !slimeproof(youmonst.data));
if (cadaver && !nonrotting_corpse(mnum)) {
long age = peek_at_iced_corpse_age(otmp);
switch(mattk->adtyp) {
case AD_DGST:
/* eating a Rider or its corpse is fatal */
- if (is_rider(mdef->data)) {
+ if (is_rider(pd)) {
if (vis)
pline("%s %s!", Monnam(magr),
- mdef->data == &mons[PM_FAMINE] ?
+ pd == &mons[PM_FAMINE] ?
"belches feebly, shrivels up and dies" :
- mdef->data == &mons[PM_PESTILENCE] ?
+ pd == &mons[PM_PESTILENCE] ?
"coughs spasmodically and collapses" :
"vomits violently and drops dead");
mondied(magr);
* No nutrition from G_NOCORPSE monster, eg, undead.
* DGST monsters don't die from undead corpses
*/
- num = monsndx(mdef->data);
+ num = monsndx(pd);
if (magr->mtame && !magr->isminion &&
!(mvitals[num].mvflags & G_NOCORPSE)) {
struct obj *virtualcorpse = mksobj(CORPSE, FALSE, FALSE);
if (magr->mcan) break;
if (canseemon(mdef))
pline("%s %s for a moment.", Monnam(mdef),
- makeplural(stagger(mdef->data, "stagger")));
+ makeplural(stagger(pd, "stagger")));
mdef->mstun = 1;
goto physical;
case AD_LEGS:
if (tmp)
mrustm(magr, mdef, otmp);
}
- } else if (magr->data == &mons[PM_PURPLE_WORM] &&
- mdef->data == &mons[PM_SHRIEKER]) {
+ } else if (pa == &mons[PM_PURPLE_WORM] &&
+ pd == &mons[PM_SHRIEKER]) {
/* hack to enhance mm_aggression(); we don't want purple
worm's bite attack to kill a shrieker because then it
won't swallow the corpse; but if the target survives,
break;
}
if (vis)
- pline("%s is %s!", Monnam(mdef),
- on_fire(mdef->data, mattk));
+ pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk));
if (pd == &mons[PM_STRAW_GOLEM] ||
pd == &mons[PM_PAPER_GOLEM]) {
if (vis) pline("%s burns completely!", Monnam(mdef));
if (mdef->mhp <= 0)
return (MM_DEF_DIED | (grow_up(magr,mdef) ?
0 : MM_AGR_DIED));
- if (magr->data->mlet == S_NYMPH &&
- !tele_restrict(magr)) {
+ if (pa->mlet == S_NYMPH && !tele_restrict(magr)) {
(void) rloc(magr, FALSE);
if (vis && !canspotmon(magr))
pline("%s suddenly disappears!", buf);
break;
case AD_SLIM:
if (cancelled) break; /* physical damage only */
- if (!rn2(4) && !flaming(mdef->data) &&
- !noncorporeal(mdef->data) &&
- mdef->data != &mons[PM_GREEN_SLIME]) {
- (void) newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, vis);
+ if (!rn2(4) && !slimeproof(pd)) {
+ if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, vis))
+ pd = mdef->data;
mdef->mstrategy &= ~STRAT_WAITFORU;
+ res = MM_HIT;
tmp = 0;
}
break;
* after monkilled() to provide better message ordering */
if (mdef->cham >= LOW_PM) {
(void) newcham(magr, (struct permonst *)0, FALSE, TRUE);
- } else if (mdef->data == &mons[PM_GREEN_SLIME]) {
+ } else if (pd == &mons[PM_GREEN_SLIME] && !slimeproof(pa)) {
(void) newcham(magr, &mons[PM_GREEN_SLIME], FALSE, TRUE);
- } else if (mdef->data == &mons[PM_WRAITH]) {
+ } else if (pd == &mons[PM_WRAITH]) {
(void) grow_up(magr, (struct monst *)0);
/* don't grow up twice */
return (MM_DEF_DIED | (magr->mhp > 0 ? 0 : MM_AGR_DIED));
- } else if (mdef->data == &mons[PM_NURSE]) {
+ } else if (pd == &mons[PM_NURSE]) {
magr->mhp = magr->mhpmax;
}
}
+ /* caveat: above digestion handling doesn't keep `pa' up to date */
return (MM_DEF_DIED | (grow_up(magr,mdef) ? 0 : MM_AGR_DIED));
}
case AD_STUN:
if(!Blind)
pline("%s %s for a moment.", Monnam(mdef),
- makeplural(stagger(mdef->data, "stagger")));
+ makeplural(stagger(pd, "stagger")));
mdef->mstun = 1;
goto physical;
case AD_LEGS:
if(mattk->aatyp == AT_WEAP) {
if(uwep) tmp = 0;
} else if(mattk->aatyp == AT_KICK) {
- if(thick_skinned(mdef->data)) tmp = 0;
- if(mdef->data == &mons[PM_SHADE]) {
+ if (thick_skinned(pd)) tmp = 0;
+ if (pd == &mons[PM_SHADE]) {
if (!(uarmf && uarmf->blessed)) {
impossible("bad shade attack function flow?");
tmp = 0;
break;
}
if (!Blind)
- pline("%s is %s!", Monnam(mdef),
- on_fire(mdef->data, mattk));
+ pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk));
if (pd == &mons[PM_STRAW_GOLEM] ||
pd == &mons[PM_PAPER_GOLEM]) {
if (!Blind)
break;
case AD_CURS:
if (night() && !rn2(10) && !mdef->mcan) {
- if (mdef->data == &mons[PM_CLAY_GOLEM]) {
+ if (pd == &mons[PM_CLAY_GOLEM]) {
if (!Blind)
pline("Some writing vanishes from %s head!",
s_suffix(mon_nam(mdef)));
{
struct obj *helmet;
- if (notonhead || !has_head(mdef->data)) {
+ if (notonhead || !has_head(pd)) {
pline("%s doesn't seem harmed.", Monnam(mdef));
tmp = 0;
- if (!Unchanging && mdef->data == &mons[PM_GREEN_SLIME]) {
+ if (!Unchanging && pd == &mons[PM_GREEN_SLIME]) {
if (!Slimed) {
You("suck in some slime and don't feel very well.");
make_slimed(10L, (char*) 0);
break;
}
case AD_STCK:
- if (!negated && !sticks(mdef->data))
+ if (!negated && !sticks(pd))
u.ustuck = mdef; /* it's now stuck to you */
break;
case AD_WRAP:
- if (!sticks(mdef->data)) {
+ if (!sticks(pd)) {
if (!u.ustuck && !rn2(10)) {
if (m_slips_free(mdef, mattk)) {
tmp = 0;
}
} else if(u.ustuck == mdef) {
/* Monsters don't wear amulets of magical breathing */
- if (is_pool(u.ux,u.uy) && !is_swimmer(mdef->data) &&
- !amphibious(mdef->data)) {
+ if (is_pool(u.ux,u.uy) && !is_swimmer(pd) &&
+ !amphibious(pd)) {
You("drown %s...", mon_nam(mdef));
tmp = mdef->mhp;
} else if(mattk->aatyp == AT_HUGS)
break;
case AD_SLIM:
if (negated) break; /* physical damage only */
- if (!rn2(4) && !flaming(mdef->data) &&
- !noncorporeal(mdef->data) &&
- mdef->data != &mons[PM_GREEN_SLIME]) {
+ if (!rn2(4) && !slimeproof(pd)) {
You("turn %s into slime.", mon_nam(mdef));
- (void) newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, FALSE);
+ if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, FALSE))
+ pd = mdef->data;
tmp = 0;
}
break;