slime groundwork

New macro slimeproof() to decide whether something is susceptible
to turning into green slime.  Most of this is just making use of existing
cached permonst values in damageum() and mdamagem() and shouldn't affect
anything.  I wanted to avoid mixing that in with the actual slime changes
which are coming.
This commit is contained in:
nethack.rankin
2007-04-30 02:18:03 +00:00
parent 94327317c2
commit 9870c9aaa3
4 changed files with 36 additions and 39 deletions

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)mondata.h 3.5 2005/10/05 */ /* SCCS Id: @(#)mondata.h 3.5 2007/04/27 */
/* Copyright (c) 1989 Mike Threepoint */ /* Copyright (c) 1989 Mike Threepoint */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -57,6 +57,8 @@
#define slithy(ptr) (((ptr)->mflags1 & M1_SLITHY) != 0L) #define slithy(ptr) (((ptr)->mflags1 & M1_SLITHY) != 0L)
#define is_wooden(ptr) ((ptr) == &mons[PM_WOOD_GOLEM]) #define is_wooden(ptr) ((ptr) == &mons[PM_WOOD_GOLEM])
#define thick_skinned(ptr) (((ptr)->mflags1 & M1_THICK_HIDE) != 0L) #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 lays_eggs(ptr) (((ptr)->mflags1 & M1_OVIPAROUS) != 0L)
#define regenerates(ptr) (((ptr)->mflags1 & M1_REGEN) != 0L) #define regenerates(ptr) (((ptr)->mflags1 & M1_REGEN) != 0L)
#define perceives(ptr) (((ptr)->mflags1 & M1_SEE_INVIS) != 0L) #define perceives(ptr) (((ptr)->mflags1 & M1_SEE_INVIS) != 0L)

View File

@@ -687,8 +687,7 @@ register int pm;
return; return;
} }
case PM_GREEN_SLIME: case PM_GREEN_SLIME:
if (!Slimed && !Unchanging && !flaming(youmonst.data) && if (!Slimed && !Unchanging && !slimeproof(youmonst.data)) {
youmonst.data != &mons[PM_GREEN_SLIME]) {
You("don't feel very well."); You("don't feel very well.");
make_slimed(10L, (char*) 0); make_slimed(10L, (char*) 0);
delayed_killer(SLIMED, KILLED_BY_AN, nul); delayed_killer(SLIMED, KILLED_BY_AN, nul);
@@ -2146,8 +2145,7 @@ struct obj *otmp;
!poly_when_stoned(youmonst.data)); !poly_when_stoned(youmonst.data));
if (mnum == PM_GREEN_SLIME) if (mnum == PM_GREEN_SLIME)
stoneorslime = (!Unchanging && !flaming(youmonst.data) && stoneorslime = (!Unchanging && !slimeproof(youmonst.data));
youmonst.data != &mons[PM_GREEN_SLIME]);
if (cadaver && !nonrotting_corpse(mnum)) { if (cadaver && !nonrotting_corpse(mnum)) {
long age = peek_at_iced_corpse_age(otmp); long age = peek_at_iced_corpse_age(otmp);

View File

@@ -693,12 +693,12 @@ mdamagem(magr, mdef, mattk)
switch(mattk->adtyp) { switch(mattk->adtyp) {
case AD_DGST: case AD_DGST:
/* eating a Rider or its corpse is fatal */ /* eating a Rider or its corpse is fatal */
if (is_rider(mdef->data)) { if (is_rider(pd)) {
if (vis) if (vis)
pline("%s %s!", Monnam(magr), pline("%s %s!", Monnam(magr),
mdef->data == &mons[PM_FAMINE] ? pd == &mons[PM_FAMINE] ?
"belches feebly, shrivels up and dies" : "belches feebly, shrivels up and dies" :
mdef->data == &mons[PM_PESTILENCE] ? pd == &mons[PM_PESTILENCE] ?
"coughs spasmodically and collapses" : "coughs spasmodically and collapses" :
"vomits violently and drops dead"); "vomits violently and drops dead");
mondied(magr); mondied(magr);
@@ -720,7 +720,7 @@ mdamagem(magr, mdef, mattk)
* No nutrition from G_NOCORPSE monster, eg, undead. * No nutrition from G_NOCORPSE monster, eg, undead.
* DGST monsters don't die from undead corpses * DGST monsters don't die from undead corpses
*/ */
num = monsndx(mdef->data); num = monsndx(pd);
if (magr->mtame && !magr->isminion && if (magr->mtame && !magr->isminion &&
!(mvitals[num].mvflags & G_NOCORPSE)) { !(mvitals[num].mvflags & G_NOCORPSE)) {
struct obj *virtualcorpse = mksobj(CORPSE, FALSE, FALSE); struct obj *virtualcorpse = mksobj(CORPSE, FALSE, FALSE);
@@ -740,7 +740,7 @@ mdamagem(magr, mdef, mattk)
if (magr->mcan) break; if (magr->mcan) break;
if (canseemon(mdef)) if (canseemon(mdef))
pline("%s %s for a moment.", Monnam(mdef), pline("%s %s for a moment.", Monnam(mdef),
makeplural(stagger(mdef->data, "stagger"))); makeplural(stagger(pd, "stagger")));
mdef->mstun = 1; mdef->mstun = 1;
goto physical; goto physical;
case AD_LEGS: case AD_LEGS:
@@ -770,8 +770,8 @@ mdamagem(magr, mdef, mattk)
if (tmp) if (tmp)
mrustm(magr, mdef, otmp); mrustm(magr, mdef, otmp);
} }
} else if (magr->data == &mons[PM_PURPLE_WORM] && } else if (pa == &mons[PM_PURPLE_WORM] &&
mdef->data == &mons[PM_SHRIEKER]) { pd == &mons[PM_SHRIEKER]) {
/* hack to enhance mm_aggression(); we don't want purple /* hack to enhance mm_aggression(); we don't want purple
worm's bite attack to kill a shrieker because then it worm's bite attack to kill a shrieker because then it
won't swallow the corpse; but if the target survives, won't swallow the corpse; but if the target survives,
@@ -785,8 +785,7 @@ mdamagem(magr, mdef, mattk)
break; break;
} }
if (vis) if (vis)
pline("%s is %s!", Monnam(mdef), pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk));
on_fire(mdef->data, mattk));
if (pd == &mons[PM_STRAW_GOLEM] || if (pd == &mons[PM_STRAW_GOLEM] ||
pd == &mons[PM_PAPER_GOLEM]) { pd == &mons[PM_PAPER_GOLEM]) {
if (vis) pline("%s burns completely!", Monnam(mdef)); if (vis) pline("%s burns completely!", Monnam(mdef));
@@ -1114,8 +1113,7 @@ mdamagem(magr, mdef, mattk)
if (mdef->mhp <= 0) if (mdef->mhp <= 0)
return (MM_DEF_DIED | (grow_up(magr,mdef) ? return (MM_DEF_DIED | (grow_up(magr,mdef) ?
0 : MM_AGR_DIED)); 0 : MM_AGR_DIED));
if (magr->data->mlet == S_NYMPH && if (pa->mlet == S_NYMPH && !tele_restrict(magr)) {
!tele_restrict(magr)) {
(void) rloc(magr, FALSE); (void) rloc(magr, FALSE);
if (vis && !canspotmon(magr)) if (vis && !canspotmon(magr))
pline("%s suddenly disappears!", buf); pline("%s suddenly disappears!", buf);
@@ -1163,11 +1161,11 @@ mdamagem(magr, mdef, mattk)
break; break;
case AD_SLIM: case AD_SLIM:
if (cancelled) break; /* physical damage only */ if (cancelled) break; /* physical damage only */
if (!rn2(4) && !flaming(mdef->data) && if (!rn2(4) && !slimeproof(pd)) {
!noncorporeal(mdef->data) && if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, vis))
mdef->data != &mons[PM_GREEN_SLIME]) { pd = mdef->data;
(void) newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, vis);
mdef->mstrategy &= ~STRAT_WAITFORU; mdef->mstrategy &= ~STRAT_WAITFORU;
res = MM_HIT;
tmp = 0; tmp = 0;
} }
break; break;
@@ -1202,16 +1200,17 @@ mdamagem(magr, mdef, mattk)
* after monkilled() to provide better message ordering */ * after monkilled() to provide better message ordering */
if (mdef->cham >= LOW_PM) { if (mdef->cham >= LOW_PM) {
(void) newcham(magr, (struct permonst *)0, FALSE, TRUE); (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); (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); (void) grow_up(magr, (struct monst *)0);
/* don't grow up twice */ /* don't grow up twice */
return (MM_DEF_DIED | (magr->mhp > 0 ? 0 : MM_AGR_DIED)); 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; 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)); return (MM_DEF_DIED | (grow_up(magr,mdef) ? 0 : MM_AGR_DIED));
} }

View File

@@ -1348,7 +1348,7 @@ register struct attack *mattk;
case AD_STUN: case AD_STUN:
if(!Blind) if(!Blind)
pline("%s %s for a moment.", Monnam(mdef), pline("%s %s for a moment.", Monnam(mdef),
makeplural(stagger(mdef->data, "stagger"))); makeplural(stagger(pd, "stagger")));
mdef->mstun = 1; mdef->mstun = 1;
goto physical; goto physical;
case AD_LEGS: case AD_LEGS:
@@ -1364,8 +1364,8 @@ register struct attack *mattk;
if(mattk->aatyp == AT_WEAP) { if(mattk->aatyp == AT_WEAP) {
if(uwep) tmp = 0; if(uwep) tmp = 0;
} else if(mattk->aatyp == AT_KICK) { } else if(mattk->aatyp == AT_KICK) {
if(thick_skinned(mdef->data)) tmp = 0; if (thick_skinned(pd)) tmp = 0;
if(mdef->data == &mons[PM_SHADE]) { if (pd == &mons[PM_SHADE]) {
if (!(uarmf && uarmf->blessed)) { if (!(uarmf && uarmf->blessed)) {
impossible("bad shade attack function flow?"); impossible("bad shade attack function flow?");
tmp = 0; tmp = 0;
@@ -1390,8 +1390,7 @@ register struct attack *mattk;
break; break;
} }
if (!Blind) if (!Blind)
pline("%s is %s!", Monnam(mdef), pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk));
on_fire(mdef->data, mattk));
if (pd == &mons[PM_STRAW_GOLEM] || if (pd == &mons[PM_STRAW_GOLEM] ||
pd == &mons[PM_PAPER_GOLEM]) { pd == &mons[PM_PAPER_GOLEM]) {
if (!Blind) if (!Blind)
@@ -1515,7 +1514,7 @@ register struct attack *mattk;
break; break;
case AD_CURS: case AD_CURS:
if (night() && !rn2(10) && !mdef->mcan) { if (night() && !rn2(10) && !mdef->mcan) {
if (mdef->data == &mons[PM_CLAY_GOLEM]) { if (pd == &mons[PM_CLAY_GOLEM]) {
if (!Blind) if (!Blind)
pline("Some writing vanishes from %s head!", pline("Some writing vanishes from %s head!",
s_suffix(mon_nam(mdef))); s_suffix(mon_nam(mdef)));
@@ -1582,10 +1581,10 @@ register struct attack *mattk;
{ {
struct obj *helmet; struct obj *helmet;
if (notonhead || !has_head(mdef->data)) { if (notonhead || !has_head(pd)) {
pline("%s doesn't seem harmed.", Monnam(mdef)); pline("%s doesn't seem harmed.", Monnam(mdef));
tmp = 0; tmp = 0;
if (!Unchanging && mdef->data == &mons[PM_GREEN_SLIME]) { if (!Unchanging && pd == &mons[PM_GREEN_SLIME]) {
if (!Slimed) { if (!Slimed) {
You("suck in some slime and don't feel very well."); You("suck in some slime and don't feel very well.");
make_slimed(10L, (char*) 0); make_slimed(10L, (char*) 0);
@@ -1606,11 +1605,11 @@ register struct attack *mattk;
break; break;
} }
case AD_STCK: case AD_STCK:
if (!negated && !sticks(mdef->data)) if (!negated && !sticks(pd))
u.ustuck = mdef; /* it's now stuck to you */ u.ustuck = mdef; /* it's now stuck to you */
break; break;
case AD_WRAP: case AD_WRAP:
if (!sticks(mdef->data)) { if (!sticks(pd)) {
if (!u.ustuck && !rn2(10)) { if (!u.ustuck && !rn2(10)) {
if (m_slips_free(mdef, mattk)) { if (m_slips_free(mdef, mattk)) {
tmp = 0; tmp = 0;
@@ -1621,8 +1620,8 @@ register struct attack *mattk;
} }
} else if(u.ustuck == mdef) { } else if(u.ustuck == mdef) {
/* Monsters don't wear amulets of magical breathing */ /* Monsters don't wear amulets of magical breathing */
if (is_pool(u.ux,u.uy) && !is_swimmer(mdef->data) && if (is_pool(u.ux,u.uy) && !is_swimmer(pd) &&
!amphibious(mdef->data)) { !amphibious(pd)) {
You("drown %s...", mon_nam(mdef)); You("drown %s...", mon_nam(mdef));
tmp = mdef->mhp; tmp = mdef->mhp;
} else if(mattk->aatyp == AT_HUGS) } else if(mattk->aatyp == AT_HUGS)
@@ -1652,11 +1651,10 @@ register struct attack *mattk;
break; break;
case AD_SLIM: case AD_SLIM:
if (negated) break; /* physical damage only */ if (negated) break; /* physical damage only */
if (!rn2(4) && !flaming(mdef->data) && if (!rn2(4) && !slimeproof(pd)) {
!noncorporeal(mdef->data) &&
mdef->data != &mons[PM_GREEN_SLIME]) {
You("turn %s into slime.", mon_nam(mdef)); 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; tmp = 0;
} }
break; break;