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

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