pull request #1175 - obj->corpsenm fixes
Pull request by mkuoppal: some objects which use the corpsenm field to access the mons[] array can have a corpsenm value of NON_PM (-1) and weren't avoiding array access in those cases. In addition to a fixes entry for it, this makes some revisions to the commited code, handling a few of the cases differently. Closes #1175
This commit is contained in:
@@ -1348,6 +1348,7 @@ if polymorphing a potion turned it into oil, dipping potions produced oil
|
||||
into non-oil kept its relative age (no noticeable effect though)
|
||||
an engulfer capable of passing through iron bars could do so even when hero
|
||||
was engulfed
|
||||
some uses of mons[obj->corpsenm] weren't excluding obj->corpsenm==NON_PM (-1)
|
||||
|
||||
|
||||
Fixes to 3.7.0-x General Problems Exposed Via git Repository
|
||||
|
||||
@@ -199,6 +199,8 @@
|
||||
|
||||
#define touch_petrifies(ptr) \
|
||||
((ptr) == &mons[PM_COCKATRICE] || (ptr) == &mons[PM_CHICKATRICE])
|
||||
/* Medusa doesn't pass touch_petrifies() but does petrify if eaten */
|
||||
#define flesh_petrifies(pm) (touch_petrifies(pm) || (pm) == &mons[PM_MEDUSA])
|
||||
|
||||
/* missiles made of rocks don't harm these: xorns and earth elementals
|
||||
(but not ghosts and shades because that would impact all missile use
|
||||
|
||||
11
src/dog.c
11
src/dog.c
@@ -929,17 +929,16 @@ dogfood(struct monst *mon, struct obj *obj)
|
||||
switch (obj->oclass) {
|
||||
case FOOD_CLASS:
|
||||
fx = (obj->otyp == CORPSE || obj->otyp == TIN || obj->otyp == EGG)
|
||||
/* corpsenm might be NON_PM (special tin, unhatachable egg) */
|
||||
? obj->corpsenm
|
||||
: NUMMONS; /* valid mons[mndx] to pacify static analyzer */
|
||||
|
||||
fptr = fx >= LOW_PM ? &mons[fx] : NULL;
|
||||
: NON_PM;
|
||||
/* mons[NUMMONS] is valid; predicate tests against it will fail */
|
||||
fptr = &mons[(fx >= LOW_PM) ? fx : NUMMONS];
|
||||
|
||||
if (obj->otyp == CORPSE && is_rider(fptr))
|
||||
return TABU;
|
||||
if ((obj->otyp == CORPSE || obj->otyp == EGG)
|
||||
/* Medusa's corpse doesn't pass the touch_petrifies() test
|
||||
but does cause petrification if eaten */
|
||||
&& ((fptr && touch_petrifies(fptr)) || obj->corpsenm == PM_MEDUSA)
|
||||
&& flesh_petrifies(fptr) /* c*ckatrice or Medusa */
|
||||
&& !resists_ston(mon))
|
||||
return POISON;
|
||||
if (obj->otyp == LUMP_OF_ROYAL_JELLY
|
||||
|
||||
32
src/eat.c
32
src/eat.c
@@ -48,9 +48,6 @@ static int tin_ok(struct obj *);
|
||||
/* also used to see if you're allowed to eat cats and dogs */
|
||||
#define CANNIBAL_ALLOWED() (Role_if(PM_CAVE_DWELLER) || Race_if(PM_ORC))
|
||||
|
||||
/* monster types that cause hero to be turned into stone if eaten */
|
||||
#define flesh_petrifies(pm) (touch_petrifies(pm) || (pm) == &mons[PM_MEDUSA])
|
||||
|
||||
/* Rider corpses are treated as non-rotting so that attempting to eat one
|
||||
will be sure to reach the stage of eating where that meal is fatal;
|
||||
acid blob corpses eventually rot away to nothing but before that happens
|
||||
@@ -58,7 +55,7 @@ static int tin_ok(struct obj *);
|
||||
become rotten */
|
||||
#define nonrotting_corpse(mnum) \
|
||||
((mnum) == PM_LIZARD || (mnum) == PM_LICHEN \
|
||||
|| ((mnum) >= LOW_PM && is_rider(&mons[mnum])) \
|
||||
|| is_rider(&mons[mnum]) \
|
||||
|| (mnum) == PM_ACID_BLOB)
|
||||
|
||||
/* non-rotting non-corpses; unlike lizard corpses, these items will behave
|
||||
@@ -1415,12 +1412,12 @@ tin_details(struct obj *obj, int mnum, char *buf)
|
||||
void
|
||||
set_tin_variety(struct obj *obj, int forcetype)
|
||||
{
|
||||
register int r;
|
||||
int r, mnum = obj->corpsenm;
|
||||
|
||||
if (forcetype == SPINACH_TIN
|
||||
|| (forcetype == HEALTHY_TIN
|
||||
&& (obj->corpsenm == NON_PM /* empty or already spinach */
|
||||
|| !vegetarian(&mons[obj->corpsenm])))) { /* replace meat */
|
||||
&& (mnum == NON_PM /* empty or already spinach */
|
||||
|| !vegetarian(&mons[mnum])))) { /* replace meat */
|
||||
obj->corpsenm = NON_PM; /* not based on any monster */
|
||||
obj->spe = 1; /* spinach */
|
||||
return;
|
||||
@@ -1434,17 +1431,18 @@ set_tin_variety(struct obj *obj, int forcetype)
|
||||
r = forcetype;
|
||||
} else { /* RANDOM_TIN */
|
||||
r = rn2(TTSZ - 1); /* take your pick */
|
||||
if (r == ROTTEN_TIN && nonrotting_corpse(obj->corpsenm))
|
||||
if (r == ROTTEN_TIN && (mnum >= LOW_PM && nonrotting_corpse(mnum)))
|
||||
r = HOMEMADE_TIN; /* lizards don't rot */
|
||||
}
|
||||
obj->spe = -(r + 1); /* offset by 1 to allow index 0 */
|
||||
}
|
||||
|
||||
static int
|
||||
tin_variety(struct obj *obj,
|
||||
boolean displ) /* we're just displaying so leave things alone */
|
||||
tin_variety(
|
||||
struct obj *obj,
|
||||
boolean displ) /* we're just displaying so leave things alone */
|
||||
{
|
||||
register int r;
|
||||
int r, mnum = obj->corpsenm;
|
||||
|
||||
if (obj->spe == 1) {
|
||||
r = SPINACH_TIN;
|
||||
@@ -1453,13 +1451,14 @@ tin_variety(struct obj *obj,
|
||||
} else if (obj->spe < 0) {
|
||||
r = -(obj->spe);
|
||||
--r; /* get rid of the offset */
|
||||
} else
|
||||
} else {
|
||||
r = rn2(TTSZ - 1);
|
||||
}
|
||||
|
||||
if (!displ && r == HOMEMADE_TIN && !obj->blessed && !rn2(7))
|
||||
r = ROTTEN_TIN; /* some homemade tins go bad */
|
||||
|
||||
if (r == ROTTEN_TIN && nonrotting_corpse(obj->corpsenm))
|
||||
if (r == ROTTEN_TIN && (mnum >= LOW_PM && nonrotting_corpse(mnum)))
|
||||
r = HOMEMADE_TIN; /* lizards don't rot */
|
||||
return r;
|
||||
}
|
||||
@@ -1762,12 +1761,15 @@ eatcorpse(struct obj *otmp)
|
||||
int retcode = 0, tp = 0, mnum = otmp->corpsenm;
|
||||
long rotted = 0L;
|
||||
int ll_conduct = 0;
|
||||
boolean stoneable = (flesh_petrifies(&mons[mnum]) && !Stone_resistance
|
||||
&& !poly_when_stoned(gy.youmonst.data)),
|
||||
boolean stoneable,
|
||||
slimeable = (mnum == PM_GREEN_SLIME && !Slimed && !Unchanging
|
||||
&& !slimeproof(gy.youmonst.data)),
|
||||
glob = otmp->globby ? TRUE : FALSE;
|
||||
|
||||
assert(mnum >= LOW_PM);
|
||||
stoneable = (flesh_petrifies(&mons[mnum]) && !Stone_resistance
|
||||
&& !poly_when_stoned(gy.youmonst.data));
|
||||
|
||||
/* KMH, conduct */
|
||||
if (!vegan(&mons[mnum]))
|
||||
if (!u.uconduct.unvegan++) {
|
||||
|
||||
28
src/mon.c
28
src/mon.c
@@ -11,7 +11,6 @@ static void sanity_check_single_mon(struct monst *, boolean, const char *);
|
||||
static struct obj *make_corpse(struct monst *, unsigned);
|
||||
static int minliquid_core(struct monst *);
|
||||
static void m_calcdistress(struct monst *);
|
||||
static boolean mstoning(const struct obj *obj);
|
||||
static boolean monlineu(struct monst *, int, int);
|
||||
static long mm_2way_aggression(struct monst *, struct monst *);
|
||||
static long mm_aggression(struct monst *, struct monst *);
|
||||
@@ -1157,24 +1156,13 @@ meatbox(struct monst *mon, struct obj *otmp)
|
||||
}
|
||||
}
|
||||
|
||||
static boolean
|
||||
mstoning(const struct obj *obj)
|
||||
{
|
||||
const int nm = obj->corpsenm;
|
||||
#define mstoning(obj) \
|
||||
(ofood(obj) && obj->corpsenm >= LOW_PM \
|
||||
&& flesh_petrifies(&mons[obj->corpsenm]))
|
||||
|
||||
if (nm < LOW_PM)
|
||||
return FALSE;
|
||||
|
||||
if (nm == PM_MEDUSA)
|
||||
return TRUE;
|
||||
|
||||
return ofood(obj) && touch_petrifies(&mons[nm]);
|
||||
}
|
||||
|
||||
/* monster consumes an object.
|
||||
|
||||
monster may die, polymorph, grow up, heal, etc; meating is not changed.
|
||||
object is extracted from any linked list and freed. */
|
||||
/* Monster mtmp consumes an object.
|
||||
Monster may die, polymorph, grow up, heal, etc; meating is not changed.
|
||||
Object is extracted from any linked list and freed. */
|
||||
void
|
||||
m_consume_obj(struct monst *mtmp, struct obj *otmp)
|
||||
{
|
||||
@@ -1429,8 +1417,10 @@ meatobj(struct monst* mtmp) /* for gelatinous cubes */
|
||||
return (count > 0 || ecount > 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
#undef mstoning
|
||||
|
||||
/* Monster eats a corpse off the ground.
|
||||
* Return value is 0 = nothing eaten, 1 = ate a corpse, 2 = died */
|
||||
Return value is 0 = nothing eaten, 1 = ate a corpse, 2 = died. */
|
||||
int
|
||||
meatcorpse(
|
||||
struct monst *mtmp) /* for purple worms and other voracious monsters */
|
||||
|
||||
Reference in New Issue
Block a user