purple worm digestion

Generally modify the AD_DGST damage type so that:
- players and pets get no AD_DGST nutrition from G_NOCORPSE monsters
- undead no longer convey any nutrition, to either monsters or you-as-monster
  I decided on this based on the age typically assigned to undead corpses.
- digestion conveys 50% or normal nutrition, and takes 25% the time to eat.
- all AD_DGST attacks are now subject to gas spore explosions, including player
This commit is contained in:
cohrs
2002-02-18 23:36:46 +00:00
parent 839947d423
commit cad85663de
5 changed files with 68 additions and 12 deletions

View File

@@ -433,6 +433,7 @@ if you float_down on a trap in which you're already trapped, don't retrap
applying whip toward hidden mimic displays mimic name before "Wait!" message
stealing a container didn't multiply cost of stolen contained objects by quan
halve air elemental damage to compensate for side effect of speed system
pet purple worms get nutrition from engulfing attack
Platform- and/or Interface-Specific Fixes

View File

@@ -1079,6 +1079,7 @@ E void NDECL(mcalcdistress);
E void FDECL(replmon, (struct monst *,struct monst *));
E void FDECL(relmon, (struct monst *));
E struct obj *FDECL(mlifesaver, (struct monst *));
E boolean FDECL(corpse_chance,(struct monst *,struct monst *,BOOLEAN_P));
E void FDECL(mondead, (struct monst *));
E void FDECL(mondied, (struct monst *));
E void FDECL(mongone, (struct monst *));

View File

@@ -557,6 +557,7 @@ mdamagem(magr, mdef, mattk)
int protector =
mattk->aatyp == AT_TENT ? 0 :
mattk->aatyp == AT_KICK ? W_ARMF : W_ARMG;
int num;
if (touch_petrifies(pd) && !resists_ston(magr) &&
(mattk->aatyp != AT_WEAP || !otmp) &&
@@ -595,6 +596,31 @@ mdamagem(magr, mdef, mattk)
tmp = mdef->mhp;
/* Use up amulet of life saving */
if (!!(obj = mlifesaver(mdef))) m_useup(mdef, obj);
/* Is a corpse for nutrition possible? It may kill magr */
if (!corpse_chance(mdef, magr, TRUE) || magr->mhp < 1)
break;
/* Pets get nutrition from swallowing monster whole.
* No nutrition from G_NOCORPSE monster, eg, undead.
* DGST monsters don't die from undead corpses
*/
num = monsndx(mdef->data);
if (magr->mtame && !magr->isminion &&
!(mvitals[num].mvflags & G_NOCORPSE)) {
struct obj *virtualcorpse = mksobj(CORPSE, FALSE, FALSE);
int nutrit;
virtualcorpse->corpsenm = num;
virtualcorpse->owt = weight(virtualcorpse);
nutrit = dog_nutrition(magr, virtualcorpse);
dealloc_obj(virtualcorpse);
/* only 50% nutrition, 25% of normal eating time */
if (magr->meating > 1) magr->meating = (magr->meating+3)/4;
if (nutrit > 1) nutrit /= 2;
EDOG(magr)->hungrytime += nutrit;
}
break;
case AD_STUN:
if (magr->mcan) break;

View File

@@ -12,7 +12,6 @@
#include "edog.h"
#include <ctype.h>
STATIC_DCL boolean FDECL(corpse_chance,(struct monst *));
STATIC_DCL boolean FDECL(restrap,(struct monst *));
STATIC_DCL long FDECL(mm_aggression, (struct monst *,struct monst *));
#ifdef OVL2
@@ -1381,19 +1380,20 @@ register struct monst *mtmp;
m_detach(mtmp, mptr);
}
STATIC_OVL boolean
corpse_chance(mon)
/* TRUE if corpse might be dropped, magr may die if mon was swallowed */
boolean
corpse_chance(mon, magr, swallowed)
struct monst *mon;
struct monst *magr; /* killer, if swallowed */
boolean swallowed; /* digestion */
{
struct permonst *mdat = mon->data;
int i, tmp;
if (mdat == &mons[PM_VLAD_THE_IMPALER] || mdat->mlet == S_LICH) {
if (cansee(mon->mx, mon->my))
pline("%s body crumbles into dust.",
s_suffix(Monnam(mon)));
return FALSE;
if (cansee(mon->mx, mon->my) && !swallowed)
pline("%s body crumbles into dust.", s_suffix(Monnam(mon)));
return FALSE;
}
/* Gas spores always explode upon death */
@@ -1405,6 +1405,28 @@ struct monst *mon;
else if(mdat->mattk[i].damd)
tmp = d((int)mdat->mlevel+1, (int)mdat->mattk[i].damd);
else tmp = 0;
if (swallowed && magr) {
if (magr == &youmonst) {
There("is an explosion in your %s!",
body_part(STOMACH));
Sprintf(killer_buf, "%s explosion",
s_suffix(mdat->mname));
losehp(tmp, killer_buf, KILLED_BY_AN);
} else {
if (flags.soundok) You_hear("an explosion.");
magr->mhp -= tmp;
if (magr->mhp < 1) mondied(magr);
if (magr->mhp < 1) { /* maybe lifesaved */
if (canspotmon(magr))
pline("%s rips open!", Monnam(magr));
} else if (canseemon(magr))
pline("%s seems to have indigestion.",
Monnam(magr));
}
return FALSE;
}
Sprintf(killer_buf, "%s explosion", s_suffix(mdat->mname));
killer = killer_buf;
killer_format = KILLED_BY_AN;
@@ -1440,7 +1462,7 @@ register struct monst *mdef;
mondead(mdef);
if (mdef->mhp > 0) return; /* lifesaved */
if (corpse_chance(mdef))
if (corpse_chance(mdef, (struct monst *)0, FALSE))
(void) make_corpse(mdef);
}
@@ -1708,7 +1730,7 @@ xkilled(mtmp, dest)
* different from whether or not the corpse is "special";
* if we want both, we have to specify it explicitly.
*/
if (corpse_chance(mtmp))
if (corpse_chance(mtmp, (struct monst *)0, FALSE))
(void) make_corpse(mtmp);
}
if(redisp) newsym(x,y);

View File

@@ -1616,10 +1616,16 @@ register struct attack *mattk;
You("hurriedly regurgitate the sizzling in your %s.",
body_part(STOMACH));
} else {
u.uhunger += mdef->data->cnutrit;
tmp = 1 + (mdef->data->cwt >> 8);
if (corpse_chance(mdef, &youmonst, TRUE) &&
!(mvitals[monsndx(mdef->data)].mvflags &
G_NOCORPSE)) {
/* nutrition only if there can be a corpse */
u.uhunger += (mdef->data->cnutrit+1) / 2;
} else tmp = 0;
Sprintf(msgbuf, "You totally digest %s.",
mon_nam(mdef));
if ((tmp = 3 + (mdef->data->cwt >> 6)) != 0) {
if (tmp != 0) {
/* setting afternmv = end_engulf is tempting,
* but will cause problems if the player is
* attacked (which uses his real location) or