Purple worm changes
Shriekers only spawn purple worms when they're appropriate difficulty. Non-tame Purple worms eat corpses off the ground. Baby purple worms attack shriekers. Hero polyed into baby purple worm is warned against shriekers. Original changes by copperwater <aosdict@gmail.com>, added with some formatting adjustments and consolidation.
This commit is contained in:
@@ -103,6 +103,10 @@ for farlook, describe water in the castle moat and in Juiblex's swamp as moat
|
||||
make hezrous emit poison clouds when they move
|
||||
stepping from one type of terrain to another was triggering an unnecessary
|
||||
status update
|
||||
make shriekers summon baby purple worms if purple worms would be too tough
|
||||
make non-tame (baby) purple worms eat corpses off the ground
|
||||
make baby purple worms attack shriekers
|
||||
make hero polymorphed into baby purple worm warned against shriekers
|
||||
|
||||
|
||||
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
|
||||
|
||||
@@ -1458,6 +1458,7 @@ E int FDECL(minliquid, (struct monst *));
|
||||
E int NDECL(movemon);
|
||||
E int FDECL(meatmetal, (struct monst *));
|
||||
E int FDECL(meatobj, (struct monst *));
|
||||
E int FDECL(meatcorpse, (struct monst *));
|
||||
E void FDECL(mpickgold, (struct monst *));
|
||||
E boolean FDECL(mpickstuff, (struct monst *, const char *));
|
||||
E int FDECL(curr_mon_load, (struct monst *));
|
||||
|
||||
@@ -205,6 +205,7 @@ struct monst {
|
||||
given the current level difficulty and the hero's level. */
|
||||
#define monmax_difficulty(levdif) (((levdif) + u.ulevel) / 2)
|
||||
#define monmin_difficulty(levdif) ((levdif) / 6)
|
||||
#define monmax_difficulty_lev() (monmax_difficulty(level_difficulty()))
|
||||
|
||||
/* Macros for whether a type of monster is too strong for a specific level. */
|
||||
#define montoostrong(monindx, lev) (mons[monindx].difficulty > lev)
|
||||
|
||||
77
src/mon.c
77
src/mon.c
@@ -1143,6 +1143,69 @@ struct monst *mtmp;
|
||||
return (count > 0 || ecount > 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Monster eats a corpse off the ground.
|
||||
* Return value is 0 = nothing eaten, 1 = ate a corpse, 2 = died */
|
||||
int
|
||||
meatcorpse(mtmp) /* for purple worms and other voracious monsters */
|
||||
struct monst* mtmp;
|
||||
{
|
||||
struct obj *otmp;
|
||||
struct permonst *ptr, *original_ptr = mtmp->data, *corpsepm;
|
||||
boolean poly, grow, heal, eyes = FALSE;
|
||||
int x = mtmp->mx, y = mtmp->my;
|
||||
|
||||
/* if a pet, eating is handled separately, in dog.c */
|
||||
if (mtmp->mtame)
|
||||
return 0;
|
||||
|
||||
for (otmp = g.level.objects[x][y]; otmp; otmp = otmp->nexthere) {
|
||||
if (otmp->otyp != CORPSE)
|
||||
continue;
|
||||
|
||||
corpsepm = &mons[otmp->corpsenm];
|
||||
if (is_rider(corpsepm)) {
|
||||
revive_corpse(otmp);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* don't eat harmful corpses */
|
||||
if (touch_petrifies(corpsepm) && !resists_ston(mtmp))
|
||||
continue;
|
||||
|
||||
if (cansee(x, y) && canseemon(mtmp)) {
|
||||
if (flags.verbose)
|
||||
pline("%s eats %s!", Monnam(mtmp), distant_name(otmp, doname));
|
||||
} else if (flags.verbose)
|
||||
You_hear("a masticating sound.");
|
||||
|
||||
poly = polyfodder(otmp);
|
||||
grow = mlevelgain(otmp);
|
||||
heal = mhealup(otmp);
|
||||
eyes = (otmp->otyp == CARROT);
|
||||
delobj(otmp);
|
||||
if (poly) {
|
||||
if (newcham(mtmp, NULL, FALSE, FALSE))
|
||||
ptr = mtmp->data;
|
||||
} else if (grow) {
|
||||
ptr = grow_up(mtmp, (struct monst *) 0);
|
||||
} else if (heal) {
|
||||
mtmp->mhp = mtmp->mhpmax;
|
||||
}
|
||||
if ((eyes || heal) && !mtmp->mcansee)
|
||||
mcureblindness(mtmp, canseemon(mtmp));
|
||||
/* in case it polymorphed or died */
|
||||
if (ptr != original_ptr)
|
||||
return !ptr ? 2 : 1;
|
||||
|
||||
/* Engulf & devour is instant, so don't set meating */
|
||||
if (mtmp->minvis)
|
||||
newsym(x, y);
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
mpickgold(mtmp)
|
||||
register struct monst *mtmp;
|
||||
@@ -1602,9 +1665,11 @@ mm_aggression(magr, mdef)
|
||||
struct monst *magr, /* monster that is currently deciding where to move */
|
||||
*mdef; /* another monster which is next to it */
|
||||
{
|
||||
int mndx = monsndx(magr->data);
|
||||
|
||||
/* supposedly purple worms are attracted to shrieking because they
|
||||
like to eat shriekers, so attack the latter when feasible */
|
||||
if (magr->data == &mons[PM_PURPLE_WORM]
|
||||
if ((mndx == PM_PURPLE_WORM || mndx == PM_BABY_PURPLE_WORM)
|
||||
&& mdef->data == &mons[PM_SHRIEKER])
|
||||
return ALLOW_M | ALLOW_TM;
|
||||
/* Various other combinations such as dog vs cat, cat vs rat, and
|
||||
@@ -2930,9 +2995,13 @@ struct monst *mtmp;
|
||||
stop_occupation();
|
||||
}
|
||||
if (!rn2(10)) {
|
||||
if (!rn2(13))
|
||||
(void) makemon(&mons[PM_PURPLE_WORM], 0, 0, NO_MM_FLAGS);
|
||||
else
|
||||
if (!rn2(13)) {
|
||||
/* don't generate purple worms if they would be too difficult */
|
||||
int pm = montoostrong(PM_PURPLE_WORM, monmax_difficulty_lev())
|
||||
? PM_BABY_PURPLE_WORM : PM_PURPLE_WORM;
|
||||
|
||||
(void) makemon(&mons[pm], 0, 0, NO_MM_FLAGS);
|
||||
} else
|
||||
(void) makemon((struct permonst *) 0, 0, 0, NO_MM_FLAGS);
|
||||
}
|
||||
aggravate();
|
||||
|
||||
@@ -1534,6 +1534,13 @@ register int after;
|
||||
return 2; /* it died */
|
||||
}
|
||||
|
||||
/* Maybe a purple worm ate a corpse */
|
||||
if (ptr == &mons[PM_PURPLE_WORM]
|
||||
|| ptr == &mons[PM_BABY_PURPLE_WORM]) {
|
||||
if (meatcorpse(mtmp) == 2)
|
||||
return 2; /* it died */
|
||||
}
|
||||
|
||||
if (!*in_rooms(mtmp->mx, mtmp->my, SHOPBASE) || !rn2(25)) {
|
||||
boolean picked = FALSE;
|
||||
|
||||
|
||||
@@ -1908,6 +1908,7 @@ polysense()
|
||||
|
||||
switch (u.umonnum) {
|
||||
case PM_PURPLE_WORM:
|
||||
case PM_BABY_PURPLE_WORM:
|
||||
warnidx = PM_SHRIEKER;
|
||||
break;
|
||||
case PM_VAMPIRE:
|
||||
|
||||
Reference in New Issue
Block a user