Monsters can gain resistances by eating corpses

This is based on both the EvilHack implementation by
k21971 <keith.simpson1971@gmail.com>, and xNetHack
implementation by copperwater <aosdict@gmail.com>.
This commit is contained in:
Pasi Kallinen
2021-05-23 19:02:38 +03:00
parent 20cbadcf85
commit 8d2407f1f2
8 changed files with 149 additions and 50 deletions

View File

@@ -1247,6 +1247,8 @@ meatobj(struct monst* mtmp) /* for gelatinous cubes */
if (otmp->oclass == SCROLL_CLASS
&& objdescr_is(otmp, "YUM YUM"))
pline("Yum%c", otmp->blessed ? '!' : '.');
if (otmp->otyp == CORPSE)
mon_givit(mtmp, &mons[otmp->corpsenm]);
} else {
if (flags.verbose)
You_hear("a slurping sound.");
@@ -1360,6 +1362,8 @@ meatcorpse(struct monst* mtmp) /* for purple worms and other voracious monsters
You_hear("a masticating sound.");
}
mon_givit(mtmp, &mons[otmp->corpsenm]);
/* [should include quickmimic but can't handle that unless this
gets changed to set mtmp->meating] */
poly = polyfodder(otmp);
@@ -1391,6 +1395,67 @@ meatcorpse(struct monst* mtmp) /* for purple worms and other voracious monsters
return 0;
}
/* Maybe give an intrinsic to a monster from eating a corpse that confers it. */
void
mon_givit(struct monst* mtmp, struct permonst* ptr)
{
int prop = corpse_intrinsic(ptr);
boolean vis = canseemon(mtmp);
const char* msg = NULL;
unsigned short intrinsic = 0; /* MR_* constant */
if (prop == 0)
return; /* no intrinsic from this corpse */
if (!should_givit(prop, ptr))
return; /* failed die roll */
/* Pets don't have all the fields that the hero does, so they can't get all
* the same intrinsics. If it happens to choose strength gain or teleport
* control or whatever, ignore it. */
switch (prop) {
case FIRE_RES:
intrinsic = MR_FIRE;
msg = "%s shivers slightly.";
break;
case COLD_RES:
intrinsic = MR_COLD;
msg = "%s looks quite warm.";
break;
case SLEEP_RES:
intrinsic = MR_SLEEP;
msg = "%s looks wide awake.";
break;
case DISINT_RES:
intrinsic = MR_DISINT;
msg = "%s looks very firm.";
break;
case SHOCK_RES:
intrinsic = MR_ELEC;
msg = "%s crackles with static electricity.";
break;
case POISON_RES:
intrinsic = MR_POISON;
msg = "%s looks healthy.";
break;
default:
break;
}
/* Don't give message if it already had this property intrinsically, but
* still do grant the intrinsic if it only had it from mresists.
* Do print the message if it only had this property extrinsically, which is
* why mon_resistancebits isn't used here. */
if ((mtmp->data->mresists | mtmp->mintrinsics) & intrinsic)
msg = (const char *) 0;
if (intrinsic)
mtmp->mintrinsics |= intrinsic;
if (vis && msg)
pline(msg, Monnam(mtmp));
}
void
mpickgold(register struct monst* mtmp)
{