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:
@@ -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
|
||||
|
||||
@@ -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 *));
|
||||
|
||||
26
src/mhitm.c
26
src/mhitm.c
@@ -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;
|
||||
|
||||
42
src/mon.c
42
src/mon.c
@@ -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);
|
||||
|
||||
10
src/uhitm.c
10
src/uhitm.c
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user