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
|
make hezrous emit poison clouds when they move
|
||||||
stepping from one type of terrain to another was triggering an unnecessary
|
stepping from one type of terrain to another was triggering an unnecessary
|
||||||
status update
|
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
|
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 NDECL(movemon);
|
||||||
E int FDECL(meatmetal, (struct monst *));
|
E int FDECL(meatmetal, (struct monst *));
|
||||||
E int FDECL(meatobj, (struct monst *));
|
E int FDECL(meatobj, (struct monst *));
|
||||||
|
E int FDECL(meatcorpse, (struct monst *));
|
||||||
E void FDECL(mpickgold, (struct monst *));
|
E void FDECL(mpickgold, (struct monst *));
|
||||||
E boolean FDECL(mpickstuff, (struct monst *, const char *));
|
E boolean FDECL(mpickstuff, (struct monst *, const char *));
|
||||||
E int FDECL(curr_mon_load, (struct monst *));
|
E int FDECL(curr_mon_load, (struct monst *));
|
||||||
|
|||||||
@@ -205,6 +205,7 @@ struct monst {
|
|||||||
given the current level difficulty and the hero's level. */
|
given the current level difficulty and the hero's level. */
|
||||||
#define monmax_difficulty(levdif) (((levdif) + u.ulevel) / 2)
|
#define monmax_difficulty(levdif) (((levdif) + u.ulevel) / 2)
|
||||||
#define monmin_difficulty(levdif) ((levdif) / 6)
|
#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. */
|
/* Macros for whether a type of monster is too strong for a specific level. */
|
||||||
#define montoostrong(monindx, lev) (mons[monindx].difficulty > lev)
|
#define montoostrong(monindx, lev) (mons[monindx].difficulty > lev)
|
||||||
|
|||||||
@@ -1143,6 +1143,69 @@ struct monst *mtmp;
|
|||||||
return (count > 0 || ecount > 0) ? 1 : 0;
|
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
|
void
|
||||||
mpickgold(mtmp)
|
mpickgold(mtmp)
|
||||||
register struct monst *mtmp;
|
register struct monst *mtmp;
|
||||||
@@ -1602,9 +1665,11 @@ mm_aggression(magr, mdef)
|
|||||||
struct monst *magr, /* monster that is currently deciding where to move */
|
struct monst *magr, /* monster that is currently deciding where to move */
|
||||||
*mdef; /* another monster which is next to it */
|
*mdef; /* another monster which is next to it */
|
||||||
{
|
{
|
||||||
|
int mndx = monsndx(magr->data);
|
||||||
|
|
||||||
/* supposedly purple worms are attracted to shrieking because they
|
/* supposedly purple worms are attracted to shrieking because they
|
||||||
like to eat shriekers, so attack the latter when feasible */
|
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])
|
&& mdef->data == &mons[PM_SHRIEKER])
|
||||||
return ALLOW_M | ALLOW_TM;
|
return ALLOW_M | ALLOW_TM;
|
||||||
/* Various other combinations such as dog vs cat, cat vs rat, and
|
/* Various other combinations such as dog vs cat, cat vs rat, and
|
||||||
@@ -2930,9 +2995,13 @@ struct monst *mtmp;
|
|||||||
stop_occupation();
|
stop_occupation();
|
||||||
}
|
}
|
||||||
if (!rn2(10)) {
|
if (!rn2(10)) {
|
||||||
if (!rn2(13))
|
if (!rn2(13)) {
|
||||||
(void) makemon(&mons[PM_PURPLE_WORM], 0, 0, NO_MM_FLAGS);
|
/* don't generate purple worms if they would be too difficult */
|
||||||
else
|
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);
|
(void) makemon((struct permonst *) 0, 0, 0, NO_MM_FLAGS);
|
||||||
}
|
}
|
||||||
aggravate();
|
aggravate();
|
||||||
|
|||||||
@@ -1534,6 +1534,13 @@ register int after;
|
|||||||
return 2; /* it died */
|
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)) {
|
if (!*in_rooms(mtmp->mx, mtmp->my, SHOPBASE) || !rn2(25)) {
|
||||||
boolean picked = FALSE;
|
boolean picked = FALSE;
|
||||||
|
|
||||||
|
|||||||
@@ -1908,6 +1908,7 @@ polysense()
|
|||||||
|
|
||||||
switch (u.umonnum) {
|
switch (u.umonnum) {
|
||||||
case PM_PURPLE_WORM:
|
case PM_PURPLE_WORM:
|
||||||
|
case PM_BABY_PURPLE_WORM:
|
||||||
warnidx = PM_SHRIEKER;
|
warnidx = PM_SHRIEKER;
|
||||||
break;
|
break;
|
||||||
case PM_VAMPIRE:
|
case PM_VAMPIRE:
|
||||||
|
|||||||
Reference in New Issue
Block a user