diff --git a/include/monst.h b/include/monst.h index 77160c8e8..4cff71fae 100644 --- a/include/monst.h +++ b/include/monst.h @@ -285,4 +285,7 @@ struct monst { #define is_lminion(mon) \ (is_minion((mon)->data) && mon_aligntyp(mon) == A_LAWFUL) +/* x is a valid index into mons[] array */ +#define ismnum(x) ((x) >= LOW_PM && (x) < NUMMONS) + #endif /* MONST_H */ diff --git a/include/permonst.h b/include/permonst.h index 852984da9..436da22eb 100644 --- a/include/permonst.h +++ b/include/permonst.h @@ -13,6 +13,13 @@ enum monnums { NUMMONS, NON_PM = -1, /* "not a monster */ LOW_PM = NON_PM + 1, /* first monster in mons */ + LEAVESTATUE = NON_PM - 1, /* leave statue instead of corpse; + * there are two lower values assigned + * in end.c so that (x == LEAVESTATUE) + * will test FALSE in bones.c: + * (NON_PM - 2) for no corpse + * (NON_PM - 3) for no corpse, no grave */ + HIGH_PM = NUMMONS - 1, SPECIAL_PM = PM_LONG_WORM_TAIL /* [normal] < ~ < [special] */ /* mons[SPECIAL_PM] through mons[NUMMONS-1], inclusive, are never generated randomly and cannot be polymorphed into */ diff --git a/src/allmain.c b/src/allmain.c index e0167d835..25ceaddac 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -297,7 +297,7 @@ moveloop_core(void) mvl_change = 0; if (Polymorph && !rn2(100)) mvl_change = 1; - else if (u.ulycn >= LOW_PM && !Upolyd + else if (ismnum(u.ulycn) && !Upolyd && !rn2(80 - (20 * night()))) mvl_change = 2; if (mvl_change && !Unchanging) { diff --git a/src/artifact.c b/src/artifact.c index 50876499a..fc3a62774 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -930,7 +930,7 @@ spec_applies(const struct artifact *weap, struct monst *mtmp) return ((ptr->mflags2 & weap->mtype) || (yours && ((!Upolyd && (gu.urace.selfmask & weap->mtype)) - || ((weap->mtype & M2_WERE) && u.ulycn >= LOW_PM)))); + || ((weap->mtype & M2_WERE) && ismnum(u.ulycn))))); } else if (weap->spfx & SPFX_DALIGN) { return yours ? (u.ualign.type != weap->alignment) : (ptr->maligntyp == A_NONE diff --git a/src/attrib.c b/src/attrib.c index 6c401c433..31c88d237 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -338,7 +338,7 @@ poisoned( /* suppress killer prefix if it already has one */ i = name_to_mon(pkiller, (int *) 0); - if (i >= LOW_PM && (mons[i].geno & G_UNIQ)) { + if (ismnum(i) && (mons[i].geno & G_UNIQ)) { kprefix = KILLED_BY; if (!type_is_pname(&mons[i])) pkiller = the(pkiller); @@ -837,7 +837,7 @@ is_innate(int propidx) int innateness; /* innately() would report FROM_FORM for this; caller wants specificity */ - if (propidx == DRAIN_RES && u.ulycn >= LOW_PM) + if (propidx == DRAIN_RES && ismnum(u.ulycn)) return FROM_LYCN; if (propidx == FAST && Very_fast) return FROM_NONE; /* can't become very fast innately */ diff --git a/src/bones.c b/src/bones.c index 587c58afc..90a2c314b 100644 --- a/src/bones.c +++ b/src/bones.c @@ -139,7 +139,7 @@ resetobjs(struct obj *ochain, boolean restore) otmp->spe = 0; /* not "laid by you" in next game */ } else if (otmp->otyp == TIN) { /* make tins of unique monster's meat be empty */ - if (otmp->corpsenm >= LOW_PM + if (ismnum(otmp->corpsenm) && unique_corpstat(&mons[otmp->corpsenm])) otmp->corpsenm = NON_PM; } else if (otmp->otyp == CORPSE || otmp->otyp == STATUE) { @@ -451,32 +451,7 @@ savebones(int how, time_t when, struct obj *corpse) set_ghostly_objlist(gi.invent); /* dispose of your possessions, usually cursed */ - if (u.ugrave_arise == (NON_PM - 1)) { - struct obj *otmp; - - /* embed your possessions in your statue */ - otmp = mk_named_object(STATUE, &mons[u.umonnum], u.ux, u.uy, - gp.plname); - - drop_upon_death((struct monst *) 0, otmp, u.ux, u.uy); - if (!otmp) - return; /* couldn't make statue */ - mtmp = (struct monst *) 0; - } else if (u.ugrave_arise < LOW_PM) { - /* drop everything */ - drop_upon_death((struct monst *) 0, (struct obj *) 0, u.ux, u.uy); - /* trick makemon() into allowing monster creation - * on your location - */ - gi.in_mklev = TRUE; - mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy, MM_NONAME); - gi.in_mklev = FALSE; - if (!mtmp) - return; - mtmp = christen_monst(mtmp, gp.plname); - if (corpse) - (void) obj_attach_mid(corpse, mtmp->m_id); - } else { + if (ismnum(u.ugrave_arise)) { /* give your possessions to the monster you become */ gi.in_mklev = TRUE; /* use as-is */ mtmp = makemon(&mons[u.ugrave_arise], u.ux, u.uy, NO_MINVENT); @@ -498,6 +473,31 @@ savebones(int how, time_t when, struct obj *corpse) if (mtmp->data->mlet == S_MUMMY && !m_carrying(mtmp, MUMMY_WRAPPING)) (void) mongets(mtmp, MUMMY_WRAPPING); m_dowear(mtmp, TRUE); + } else if (u.ugrave_arise == LEAVESTATUE) { + struct obj *otmp; + + /* embed your possessions in your statue */ + otmp = mk_named_object(STATUE, &mons[u.umonnum], u.ux, u.uy, + gp.plname); + + drop_upon_death((struct monst *) 0, otmp, u.ux, u.uy); + if (!otmp) + return; /* couldn't make statue */ + mtmp = (struct monst *) 0; + } else { /* u.ugrave_arise < LEAVESTATUE */ + /* drop everything */ + drop_upon_death((struct monst *) 0, (struct obj *) 0, u.ux, u.uy); + /* trick makemon() into allowing monster creation + * on your location + */ + gi.in_mklev = TRUE; + mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy, MM_NONAME); + gi.in_mklev = FALSE; + if (!mtmp) + return; + mtmp = christen_monst(mtmp, gp.plname); + if (corpse) + (void) obj_attach_mid(corpse, mtmp->m_id); } if (mtmp) { mtmp->m_lev = (u.ulevel ? u.ulevel : 1); diff --git a/src/do_name.c b/src/do_name.c index 3a43ab9ad..f7e1ab764 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -2419,12 +2419,12 @@ obj_pmname(struct obj *obj) struct monst *m = OMONST(obj); /* obj->oextra->omonst->data is Null but ...->mnum is set */ - if (m->mnum >= LOW_PM) + if (ismnum(m->mnum)) return pmname(&mons[m->mnum], m->female ? FEMALE : MALE); } #endif if ((obj->otyp == CORPSE || obj->otyp == STATUE || obj->otyp == FIGURINE) - && obj->corpsenm >= LOW_PM) { + && ismnum(obj->corpsenm)) { int cgend = (obj->spe & CORPSTAT_GENDER), mgend = ((cgend == CORPSTAT_MALE) ? MALE : (cgend == CORPSTAT_FEMALE) ? FEMALE diff --git a/src/dog.c b/src/dog.c index 85c04f3ec..74ba4a541 100644 --- a/src/dog.c +++ b/src/dog.c @@ -933,7 +933,7 @@ dogfood(struct monst *mon, struct obj *obj) ? obj->corpsenm : NON_PM; /* mons[NUMMONS] is valid; predicate tests against it will fail */ - fptr = &mons[(fx >= LOW_PM) ? fx : NUMMONS]; + fptr = &mons[(ismnum(fx)) ? fx : NUMMONS]; if (obj->otyp == CORPSE && is_rider(fptr)) return TABU; @@ -1103,7 +1103,7 @@ tamedog(struct monst *mtmp, struct obj *obj) /* pet will "catch" and eat this thrown food */ if (canseemon(mtmp)) { boolean big_corpse = - (obj->otyp == CORPSE && obj->corpsenm >= LOW_PM + (obj->otyp == CORPSE && ismnum(obj->corpsenm) && mons[obj->corpsenm].msize > mtmp->data->msize); pline("%s catches %s%s", Monnam(mtmp), the(xname(obj)), !big_corpse ? "." : ", or vice versa!"); diff --git a/src/dokick.c b/src/dokick.c index f1b1f273a..e0735771f 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -440,7 +440,7 @@ container_impact_dmg( /* eggs laid by you. penalty is -1 per egg, max 5, * but it's always exactly 1 that breaks */ - if (otmp->otyp == EGG && otmp->spe && otmp->corpsenm >= LOW_PM) + if (otmp->otyp == EGG && otmp->spe && ismnum(otmp->corpsenm)) change_luck(-1); if (otmp->otyp == EGG) { Soundeffect(se_egg_cracking, 25); @@ -1699,7 +1699,7 @@ ship_object(struct obj *otmp, coordxy x, coordxy y, boolean shop_floor_obj) result = "crash"; } else { /* penalty for breaking eggs laid by you */ - if (otmp->otyp == EGG && otmp->spe && otmp->corpsenm >= LOW_PM) + if (otmp->otyp == EGG && otmp->spe && ismnum(otmp->corpsenm)) change_luck((schar) -min(otmp->quan, 5L)); result = "splat"; } diff --git a/src/dothrow.c b/src/dothrow.c index 23d359843..763a97dc9 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1263,7 +1263,7 @@ toss_up(struct obj *obj, boolean hitsroof) const char *action; int otyp = obj->otyp; boolean petrifier = ((otyp == EGG || otyp == CORPSE) - && obj->corpsenm >= LOW_PM + && ismnum(obj->corpsenm) && touch_petrifies(&mons[obj->corpsenm])); /* note: obj->quan == 1 */ @@ -2479,7 +2479,7 @@ breakobj( break; case EGG: /* breaking your own eggs is bad luck */ - if (hero_caused && obj->spe && obj->corpsenm >= LOW_PM) + if (hero_caused && obj->spe && ismnum(obj->corpsenm)) change_luck((schar) -min(obj->quan, 5L)); break; case BOULDER: diff --git a/src/eat.c b/src/eat.c index 804686dda..dfe054b55 100644 --- a/src/eat.c +++ b/src/eat.c @@ -745,7 +745,7 @@ maybe_cannibal(int pm, boolean allowmsg) about cannibalism--hero's innate traits aren't altered) */ && (your_race(fptr) || (Upolyd && same_race(gy.youmonst.data, fptr)) - || (u.ulycn >= LOW_PM && were_beastie(pm) == u.ulycn))) { + || (ismnum(u.ulycn) && were_beastie(pm) == u.ulycn))) { if (allowmsg) { if (Upolyd && your_race(fptr)) You("have a bad feeling deep inside."); @@ -1272,7 +1272,7 @@ cpostfx(int pm) givit(tmp, ptr); } /* check_intrinsics */ - if (catch_lycanthropy >= LOW_PM) { + if (ismnum(catch_lycanthropy)) { set_ulycn(catch_lycanthropy); retouch_equipment(2); } @@ -1431,7 +1431,7 @@ set_tin_variety(struct obj *obj, int forcetype) r = forcetype; } else { /* RANDOM_TIN */ r = rn2(TTSZ - 1); /* take your pick */ - if (r == ROTTEN_TIN && (mnum >= LOW_PM && nonrotting_corpse(mnum))) + if (r == ROTTEN_TIN && (ismnum(mnum) && nonrotting_corpse(mnum))) r = HOMEMADE_TIN; /* lizards don't rot */ } obj->spe = -(r + 1); /* offset by 1 to allow index 0 */ @@ -1458,7 +1458,7 @@ tin_variety( if (!displ && r == HOMEMADE_TIN && !obj->blessed && !rn2(7)) r = ROTTEN_TIN; /* some homemade tins go bad */ - if (r == ROTTEN_TIN && (mnum >= LOW_PM && nonrotting_corpse(mnum))) + if (r == ROTTEN_TIN && (ismnum(mnum) && nonrotting_corpse(mnum))) r = HOMEMADE_TIN; /* lizards don't rot */ return r; } @@ -1766,7 +1766,7 @@ eatcorpse(struct obj *otmp) && !slimeproof(gy.youmonst.data)), glob = otmp->globby ? TRUE : FALSE; - assert(mnum >= LOW_PM); + assert(ismnum(mnum)); stoneable = (flesh_petrifies(&mons[mnum]) && !Stone_resistance && !poly_when_stoned(gy.youmonst.data)); @@ -2398,7 +2398,7 @@ fpostfx(struct obj *otmp) { switch (otmp->otyp) { case SPRIG_OF_WOLFSBANE: - if (u.ulycn >= LOW_PM || is_were(gy.youmonst.data)) + if (ismnum(u.ulycn) || is_were(gy.youmonst.data)) you_unwere(TRUE); break; case CARROT: @@ -2445,7 +2445,7 @@ fpostfx(struct obj *otmp) heal_legs(0); break; case EGG: - if (otmp->corpsenm >= LOW_PM + if (ismnum(otmp->corpsenm) && flesh_petrifies(&mons[otmp->corpsenm])) { if (!Stone_resistance && !(poly_when_stoned(gy.youmonst.data) @@ -2529,7 +2529,7 @@ edibility_prompts(struct obj *otmp) if (cadaver || otmp->otyp == EGG || otmp->otyp == TIN || otmp->otyp == GLOB_OF_GREEN_SLIME) { /* These checks must match those in eatcorpse() */ - stoneorslime = (mnum >= LOW_PM + stoneorslime = (ismnum(mnum) && flesh_petrifies(&mons[mnum]) && !Stone_resistance && !poly_when_stoned(gy.youmonst.data)); @@ -3808,7 +3808,7 @@ Popeye(int threat) return (boolean) (mndx != NON_PM || otin->spe == 1); /* flesh from lizards and acidic critters stops petrification */ case STONED: - return (boolean) (mndx >= LOW_PM + return (boolean) (ismnum(mndx) && (mndx == PM_LIZARD || acidic(&mons[mndx]))); /* polymorph into a fiery monster */ case SLIMED: diff --git a/src/end.c b/src/end.c index 45805e201..7d12473f9 100644 --- a/src/end.c +++ b/src/end.c @@ -671,8 +671,8 @@ done_in_by(struct monst *mtmp, int how) { char buf[BUFSZ]; struct permonst *mptr = mtmp->data, - *champtr = (mtmp->cham >= LOW_PM) ? &mons[mtmp->cham] - : mptr; + *champtr = ismnum(mtmp->cham) ? &mons[mtmp->cham] + : mptr; boolean distorted = (boolean) (Hallucination && canspotmon(mtmp)), mimicker = (M_AP_TYPE(mtmp) == M_AP_MONSTER), imitator = (mptr != champtr || mimicker); @@ -1438,7 +1438,7 @@ fuzzer_savelife(int how) /* get rid of temporary potion with obfree() rather than useup() because it doesn't get entered into inventory */ - if (u.ulycn >= LOW_PM && !rn2(3)) { + if (ismnum(u.ulycn) && !rn2(3)) { potion = mksobj(POT_WATER, TRUE, FALSE); bless(potion); (void) peffects(potion); @@ -1671,7 +1671,7 @@ really_done(int how) else if (how == BURNING || how == DISSOLVED) /* corpse burns up too */ u.ugrave_arise = (NON_PM - 2); /* leave no corpse */ else if (how == STONING) - u.ugrave_arise = (NON_PM - 1); /* statue instead of corpse */ + u.ugrave_arise = LEAVESTATUE; /* statue instead of corpse */ else if (how == TURNED_SLIME /* it's possible to turn into slime even though green slimes have been genocided: genocide could occur after hero is @@ -1808,7 +1808,7 @@ really_done(int how) } } - if (u.ugrave_arise >= LOW_PM && !done_stopprint) { + if (ismnum(u.ugrave_arise) && !done_stopprint) { /* give this feedback even if bones aren't going to be created, so that its presence or absence doesn't tip off the player to new bones or their lack; it might be a lie if makemon fails */ diff --git a/src/insight.c b/src/insight.c index 2055689b1..0b8149daa 100644 --- a/src/insight.c +++ b/src/insight.c @@ -1567,7 +1567,7 @@ attributes_enlightenment( you_are(buf, ""); } warnspecies = gc.context.warntype.speciesidx; - if (Warn_of_mon && warnspecies >= LOW_PM) { + if (Warn_of_mon && ismnum(warnspecies)) { Sprintf(buf, "aware of the presence of %s", makeplural(mons[warnspecies].pmnames[NEUTRAL])); you_are(buf, from_what(WARN_OF_MON)); @@ -1791,7 +1791,7 @@ attributes_enlightenment( /* blocked shape changes */ if (Polymorph) what = !final ? "polymorph" : "have polymorphed"; - else if (u.ulycn >= LOW_PM) + else if (ismnum(u.ulycn)) what = !final ? "change shape" : "have changed shape"; if (what) { Sprintf(buf, "would %s periodically", what); @@ -1826,7 +1826,7 @@ attributes_enlightenment( } if (lays_eggs(gy.youmonst.data) && flags.female) /* Upolyd */ you_can("lay eggs", ""); - if (u.ulycn >= LOW_PM) { + if (ismnum(u.ulycn)) { /* "you are a werecreature [in beast form]" */ Strcpy(buf, an(pmname(&mons[u.ulycn], flags.female ? FEMALE : MALE))); @@ -3215,7 +3215,7 @@ mstatusline(struct monst *mtmp) segndx, ordin(segndx), nsegs); } } - if (mtmp->cham >= LOW_PM && mtmp->data != &mons[mtmp->cham]) + if (ismnum(mtmp->cham) && mtmp->data != &mons[mtmp->cham]) /* don't reveal the innate form (chameleon, vampire, &c), just expose the fact that this current form isn't it */ Strcat(info, ", shapechanger"); diff --git a/src/mcastu.c b/src/mcastu.c index 8839894c5..795a9c103 100644 --- a/src/mcastu.c +++ b/src/mcastu.c @@ -393,7 +393,7 @@ death_inflicted_by( Strcpy(outbuf, deathreason); if (mtmp) { struct permonst *mptr = mtmp->data, - *champtr = (mtmp->cham >= LOW_PM) ? &mons[mtmp->cham] : mptr; + *champtr = (ismnum(mtmp->cham)) ? &mons[mtmp->cham] : mptr; const char *realnm = pmname(champtr, Mgender(mtmp)), *fakenm = pmname(mptr, Mgender(mtmp)); diff --git a/src/mhitm.c b/src/mhitm.c index 33b9f8548..7bae772d7 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1084,7 +1084,7 @@ mdamagem( if (mattk->adtyp == AD_DGST) { /* various checks similar to dog_eat and meatobj. * after monkilled() to provide better message ordering */ - if (mdef->cham >= LOW_PM) { + if (ismnum(mdef->cham)) { (void) newcham(magr, (struct permonst *) 0, NC_SHOW_MSG); } else if (pd == &mons[PM_GREEN_SLIME] && !slimeproof(pa)) { (void) newcham(magr, &mons[PM_GREEN_SLIME], NC_SHOW_MSG); diff --git a/src/mkobj.c b/src/mkobj.c index 9361fa304..7cc5ae225 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1840,7 +1840,7 @@ weight(struct obj *obj) struct obj *contents; int cwt; - if (obj->otyp == STATUE && obj->corpsenm >= LOW_PM) { + if (obj->otyp == STATUE && ismnum(obj->corpsenm)) { int msize = (int) mons[obj->corpsenm].msize, /* 0..7 */ minwt = (msize + msize + 1) * 100; @@ -1882,7 +1882,7 @@ weight(struct obj *obj) return wt + cwt; } - if (obj->otyp == CORPSE && obj->corpsenm >= LOW_PM) { + if (obj->otyp == CORPSE && ismnum(obj->corpsenm)) { long long_wt = obj->quan * (long) mons[obj->corpsenm].cwt; wt = (long_wt > LARGEST_INT) ? LARGEST_INT : (int) long_wt; diff --git a/src/mon.c b/src/mon.c index 96c112e6f..855a3a4ae 100644 --- a/src/mon.c +++ b/src/mon.c @@ -60,7 +60,7 @@ sanity_check_single_mon( struct permonst *mptr = mtmp->data; coordxy mx = mtmp->mx, my = mtmp->my; - if (!mptr || mptr < &mons[LOW_PM] || mptr >= &mons[NUMMONS]) { + if (!mptr || mptr < &mons[LOW_PM] || mptr > &mons[HIGH_PM]) { /* most sanity checks issue warnings if they detect a problem, but this would be too extreme to keep going */ panic("illegal mon data %s; mnum=%d (%s)", @@ -466,7 +466,7 @@ genus(int mndx, int mode) mndx = mode ? PM_VALKYRIE : PM_HUMAN; break; default: - if (mndx >= LOW_PM && mndx < NUMMONS) { + if (ismnum(mndx)) { struct permonst *ptr = &mons[mndx]; if (is_human(ptr)) @@ -495,7 +495,7 @@ pm_to_cham(int mndx) * As of 3.6.0 we just check M2_SHAPESHIFTER instead of having a * big switch statement with hardcoded shapeshifter types here. */ - if (mndx >= LOW_PM && is_shapeshifter(&mons[mndx])) + if (ismnum(mndx) && is_shapeshifter(&mons[mndx])) mcham = mndx; return mcham; } @@ -961,7 +961,7 @@ m_calcdistress(struct monst *mtmp) mon_regen(mtmp, FALSE); /* possibly polymorph shapechangers and lycanthropes */ - if (mtmp->cham >= LOW_PM) + if (ismnum(mtmp->cham)) decide_to_shapeshift(mtmp, (canspotmon(mtmp) || engulfing_u(mtmp)) ? SHIFT_MSG : 0); @@ -1157,7 +1157,7 @@ meatbox(struct monst *mon, struct obj *otmp) } #define mstoning(obj) \ - (ofood(obj) && obj->corpsenm >= LOW_PM \ + (ofood(obj) && ismnum(obj->corpsenm) \ && flesh_petrifies(&mons[obj->corpsenm])) /* Monster mtmp consumes an object. @@ -2641,7 +2641,7 @@ vamprises(struct monst *mtmp) { int mndx = mtmp->cham; - if (mndx >= LOW_PM && mndx != monsndx(mtmp->data) + if (ismnum(mndx) && mndx != monsndx(mtmp->data) && !(gm.mvitals[mndx].mvflags & G_GENOD)) { coord new_xy; char buf[BUFSZ]; @@ -2823,7 +2823,7 @@ mondead(struct monst *mtmp) mptr = mtmp->data; /* save this for m_detach() */ /* restore chameleon, lycanthropes to true form at death */ - if (mtmp->cham >= LOW_PM) { + if (ismnum(mtmp->cham)) { set_mon_data(mtmp, &mons[mtmp->cham]); mtmp->cham = NON_PM; } else if (mtmp->data == &mons[PM_WEREJACKAL]) @@ -3499,7 +3499,7 @@ vamp_stone(struct monst *mtmp) newsym(mtmp->mx, mtmp->my); return FALSE; /* didn't petrify */ } - } else if (mtmp->cham >= LOW_PM + } else if (ismnum(mtmp->cham) && (mons[mtmp->cham].mresists & MR_STONE)) { /* sandestins are stoning-immune so if hit by stoning damage they revert to innate shape rather than become a statue */ @@ -4090,7 +4090,7 @@ normal_shape(struct monst *mon) { int mcham = (int) mon->cham; - if (mcham >= LOW_PM) { + if (ismnum(mcham)) { unsigned mcan = mon->mcan; (void) newcham(mon, &mons[mcham], NC_SHOW_MSG); @@ -4469,7 +4469,7 @@ decide_to_shapeshift(struct monst *mon, int shiftflags) */ if (mon->data->mlet != S_VAMPIRE) { if ((mon->mhp <= (mon->mhpmax + 5) / 6) && rn2(4) - && mon->cham >= LOW_PM) { + && ismnum(mon->cham)) { ptr = &mons[mon->cham]; dochng = TRUE; } else if (mon->data == &mons[PM_FOG_CLOUD] @@ -4481,7 +4481,7 @@ decide_to_shapeshift(struct monst *mon, int shiftflags) tame--and then switch back to vampire; they'll also switch to fog cloud if they encounter a closed door */ mndx = pickvampshape(mon); - if (mndx >= LOW_PM) { + if (ismnum(mndx)) { ptr = &mons[mndx]; dochng = (ptr != mon->data); } @@ -4605,7 +4605,7 @@ validvamp(struct monst* mon, int* mndx_p, int monclass) *mndx_p = PM_VLAD_THE_IMPALER; return TRUE; } - if (*mndx_p >= LOW_PM && is_shapeshifter(&mons[*mndx_p])) { + if (ismnum(*mndx_p) && is_shapeshifter(&mons[*mndx_p])) { /* player picked some type of shapeshifter; use mon's self (vampire or chameleon) */ *mndx_p = mon->cham; @@ -4693,7 +4693,7 @@ wiz_force_cham_form(struct monst *mon) if (monclass && mndx == NON_PM) mndx = mkclass_poly(monclass); } - if (mndx >= LOW_PM) { + if (ismnum(mndx)) { /* got a specific type of monster; use it if we can */ if (validvamp(mon, &mndx, monclass)) break; @@ -4745,6 +4745,7 @@ select_newcham_form(struct monst* mon) tryct = 5; do { mndx = rn1(SPECIAL_PM - LOW_PM, LOW_PM); + /* assert(ismnum(mndx)); */ if (humanoid(&mons[mndx]) && polyok(&mons[mndx])) break; } while (--tryct > 0); @@ -4782,6 +4783,7 @@ select_newcham_form(struct monst* mon) tryct = 50; do { mndx = rn1(SPECIAL_PM - LOW_PM, LOW_PM); + /* assert(ismnum(mndx); */ } while (--tryct > 0 && !validspecmon(mon, mndx) /* try harder to select uppercase monster on rogue level */ && (tryct > 40 && Is_rogue_level(&u.uz) @@ -4811,7 +4813,7 @@ accept_newcham_form(struct monst *mon, int mndx) /* shapeshifters are rejected by polyok() but allow a shapeshifter to take on its 'natural' form */ if (is_shapeshifter(mdat) - && mon->cham >= LOW_PM && mdat == &mons[mon->cham]) + && ismnum(mon->cham) && mdat == &mons[mon->cham]) return mdat; /* polyok() rules out M2_PNAME, M2_WERE, and all humans except Kops */ return polyok(mdat) ? mdat : 0; @@ -5142,6 +5144,7 @@ dead_species(int m_idx, boolean egg) * fortunately, none of them have eggs. Species extinction due to * overpopulation does not kill eggs. */ + /* assert(ismnum(m_idx)); */ alt_idx = egg ? big_to_little(m_idx) : m_idx; return (boolean) ((gm.mvitals[m_idx].mvflags & G_GENOD) != 0 || (gm.mvitals[alt_idx].mvflags & G_GENOD) != 0); @@ -5201,10 +5204,10 @@ kill_genocided_monsters(void) if (DEADMONSTER(mtmp)) continue; mndx = monsndx(mtmp->data); - kill_cham = (mtmp->cham >= LOW_PM + kill_cham = (ismnum(mtmp->cham) && (gm.mvitals[mtmp->cham].mvflags & G_GENOD)); if ((gm.mvitals[mndx].mvflags & G_GENOD) || kill_cham) { - if (mtmp->cham >= LOW_PM && !kill_cham) + if (ismnum(mtmp->cham) && !kill_cham) (void) newcham(mtmp, (struct permonst *) 0, NC_SHOW_MSG); else mondead(mtmp); diff --git a/src/muse.c b/src/muse.c index 3a5849be8..29ab74982 100644 --- a/src/muse.c +++ b/src/muse.c @@ -2648,7 +2648,7 @@ searches_for_item(struct monst *mon, struct obj *obj) return (boolean) (mcould_eat_tin(mon) && (!resists_ston(mon) && cures_stoning(mon, obj, TRUE))); - if (typ == EGG && obj->corpsenm >= LOW_PM) + if (typ == EGG && ismnum(obj->corpsenm)) return (boolean) touch_petrifies(&mons[obj->corpsenm]); break; default: diff --git a/src/objnam.c b/src/objnam.c index 571aa8cce..2036b6322 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1362,7 +1362,7 @@ doname_base( if (known && stale_egg(obj)) Strcat(prefix, "stale "); #endif - if (omndx >= LOW_PM + if (ismnum(omndx) && (known || (gm.mvitals[omndx].mvflags & MV_KNOWS_EGG))) { Strcat(prefix, mons[omndx].pmnames[NEUTRAL]); Strcat(prefix, " "); @@ -4838,7 +4838,7 @@ readobjnam(char *bp, struct obj *no_wish) case STATUE: /* otmp->cobj already done in mksobj() */ case FIGURINE: case CORPSE: { - struct permonst *P = (d.mntmp >= LOW_PM) ? &mons[d.mntmp] : 0; + struct permonst *P = (ismnum(d.mntmp)) ? &mons[d.mntmp] : 0; d.otmp->spe = !P ? CORPSTAT_RANDOM /* if neuter, force neuter regardless of wish request */ @@ -4878,7 +4878,7 @@ readobjnam(char *bp, struct obj *no_wish) } /* set otmp->corpsenm or dragon scale [mail] */ - if (d.mntmp >= LOW_PM) { + if (ismnum(d.mntmp)) { int humanwere; if (d.mntmp == PM_LONG_WORM_TAIL) diff --git a/src/options.c b/src/options.c index dabbc7e7f..2a938c6ca 100644 --- a/src/options.c +++ b/src/options.c @@ -8220,13 +8220,13 @@ fruitadd(char *str, struct fruit *replace_fruit) || !strncmp(gp.pl_fruit, "partly eaten ", 13) || (!strncmp(gp.pl_fruit, "tin of ", 7) && (!strcmp(gp.pl_fruit + 7, "spinach") - || name_to_mon(gp.pl_fruit + 7, (int *) 0) >= LOW_PM)) + || ismnum(name_to_mon(gp.pl_fruit + 7, (int *) 0)))) || !strcmp(gp.pl_fruit, "empty tin") || (!strcmp(gp.pl_fruit, "glob") || (globpfx > 0 && !strcmp("glob", &gp.pl_fruit[globpfx]))) || ((str_end_is(gp.pl_fruit, " corpse") || str_end_is(gp.pl_fruit, " egg")) - && name_to_mon(gp.pl_fruit, (int *) 0) >= LOW_PM)) { + && ismnum(name_to_mon(gp.pl_fruit, (int *) 0)))) { Strcpy(buf, gp.pl_fruit); Strcpy(gp.pl_fruit, "candied "); nmcpy(gp.pl_fruit + 8, buf, PL_FSIZ - 8); diff --git a/src/polyself.c b/src/polyself.c index dd6b7d398..ff19ad4d2 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -464,7 +464,7 @@ polyself(int psflags) monsterpoly = ((psflags & POLY_MONSTER) != 0), formrevert = ((psflags & POLY_REVERT) != 0), draconian = (uarm && Is_dragon_armor(uarm)), - iswere = (u.ulycn >= LOW_PM), + iswere = (ismnum(u.ulycn)), isvamp = (is_vampire(gy.youmonst.data) || is_vampshifter(&gy.youmonst)), controllable_poly = Polymorph_control && !(Stunned || Unaware); @@ -663,7 +663,7 @@ polyself(int psflags) && !rn2(10)) ? PM_WOLF : !rn2(4) ? PM_FOG_CLOUD : PM_VAMPIRE_BAT; - if (gy.youmonst.cham >= LOW_PM + if (ismnum(gy.youmonst.cham) && !is_vampire(gy.youmonst.data) && !rn2(2)) mntmp = gy.youmonst.cham; } @@ -2230,7 +2230,7 @@ polysense(void) HWarn_of_mon |= FROMRACE; return; } - if (warnidx >= LOW_PM) { + if (ismnum(warnidx)) { gc.context.warntype.speciesidx = warnidx; gc.context.warntype.species = &mons[warnidx]; HWarn_of_mon |= FROMRACE; diff --git a/src/potion.c b/src/potion.c index 7c94177c6..f04da9595 100644 --- a/src/potion.c +++ b/src/potion.c @@ -713,7 +713,7 @@ peffect_water(struct obj *otmp) if (otmp->blessed) { pline("This burns like %s!", hliquid("acid")); exercise(A_CON, FALSE); - if (u.ulycn >= LOW_PM) { + if (ismnum(u.ulycn)) { Your("affinity to %s disappears!", makeplural(mons[u.ulycn].pmnames[NEUTRAL])); if (gy.youmonst.data == &mons[u.ulycn]) @@ -725,7 +725,7 @@ peffect_water(struct obj *otmp) } else if (otmp->cursed) { You_feel("quite proud of yourself."); healup(d(2, 6), 0, 0, 0); - if (u.ulycn >= LOW_PM && !Upolyd) + if (ismnum(u.ulycn) && !Upolyd) you_were(); exercise(A_CON, TRUE); } @@ -735,7 +735,7 @@ peffect_water(struct obj *otmp) make_sick(0L, (char *) 0, TRUE, SICK_ALL); exercise(A_WIS, TRUE); exercise(A_CON, TRUE); - if (u.ulycn >= LOW_PM) + if (ismnum(u.ulycn)) you_unwere(TRUE); /* "Purified" */ /* make_confused(0L, TRUE); */ } else { @@ -745,7 +745,7 @@ peffect_water(struct obj *otmp) KILLED_BY_AN); } else You_feel("full of dread."); - if (u.ulycn >= LOW_PM && !Upolyd) + if (ismnum(u.ulycn) && !Upolyd) you_were(); exercise(A_CON, FALSE); } @@ -2047,7 +2047,7 @@ potionbreathe(struct obj *obj) case POT_WATER: if (u.umonnum == PM_GREMLIN) { (void) split_mon(&gy.youmonst, (struct monst *) 0); - } else if (u.ulycn >= LOW_PM) { + } else if (ismnum(u.ulycn)) { /* vapor from [un]holy water will trigger transformation but won't cure lycanthropy */ if (obj->blessed && gy.youmonst.data == &mons[u.ulycn]) diff --git a/src/pray.c b/src/pray.c index be92a8688..cc1a5d07a 100644 --- a/src/pray.c +++ b/src/pray.c @@ -209,7 +209,7 @@ in_trouble(void) return TROUBLE_REGION; if (critically_low_hp(FALSE)) return TROUBLE_HIT; - if (u.ulycn >= LOW_PM) + if (ismnum(u.ulycn)) return TROUBLE_LYCANTHROPE; if (near_capacity() >= EXT_ENCUMBER && AMAX(A_STR) - ABASE(A_STR) > 3) return TROUBLE_COLLAPSING; diff --git a/src/read.c b/src/read.c index e99c0929d..05a4eef79 100644 --- a/src/read.c +++ b/src/read.c @@ -3086,11 +3086,11 @@ create_particular_parse( } else { /* no explicit gender term was specified */ d->fem = gender_name_var; } - if (d->which >= LOW_PM) + if (ismnum(d->which)) return TRUE; /* got one */ d->monclass = name_to_monclass(bufp, &d->which); - if (d->which >= LOW_PM) { + if (ismnum(d->which)) { d->monclass = MAXMCLASSES; /* matters below */ return TRUE; } else if (d->monclass == S_invisible) { /* not an actual monster class */ diff --git a/src/restore.c b/src/restore.c index b2a487c3c..62914d988 100644 --- a/src/restore.c +++ b/src/restore.c @@ -531,7 +531,7 @@ restgamestate(NHFILE *nhfp) newgamecontext = gc.context; /* copy statically init'd context */ if (nhfp->structlevel) Mread(nhfp->fd, &gc.context, sizeof gc.context); - gc.context.warntype.species = (gc.context.warntype.speciesidx >= LOW_PM) + gc.context.warntype.species = (ismnum(gc.context.warntype.speciesidx)) ? &mons[gc.context.warntype.speciesidx] : (struct permonst *) 0; /* gc.context.victual.piece, .tin.tin, .spellbook.book, and .polearm.hitmon diff --git a/src/shk.c b/src/shk.c index cacc1aa18..a6da8621f 100644 --- a/src/shk.c +++ b/src/shk.c @@ -3706,7 +3706,7 @@ corpsenm_price_adj(struct obj *obj) long val = 0L; if ((obj->otyp == TIN || obj->otyp == EGG || obj->otyp == CORPSE) - && obj->corpsenm >= LOW_PM) { + && ismnum(obj->corpsenm)) { int i; long tmp = 1L; struct permonst *ptr = &mons[obj->corpsenm]; @@ -5279,7 +5279,7 @@ block_entry(register coordxy x, register coordxy y) char * shk_your(char *buf, struct obj *obj) { - boolean chk_pm = obj->otyp == CORPSE && obj->corpsenm >= LOW_PM; + boolean chk_pm = obj->otyp == CORPSE && ismnum(obj->corpsenm); buf[0] = '\0'; if (chk_pm && type_is_pname(&mons[obj->corpsenm])) diff --git a/src/shknam.c b/src/shknam.c index 32e3677f0..a222ebefb 100644 --- a/src/shknam.c +++ b/src/shknam.c @@ -395,8 +395,7 @@ veggy_item(struct obj* obj, int otyp /* used iff obj is null */) if (otyp == TIN && corpsenm == NON_PM) /* implies obj is non-null */ return (boolean) (obj->spe == 1); /* 0 = empty, 1 = spinach */ if (otyp == TIN || otyp == CORPSE) - return (boolean) (corpsenm >= LOW_PM - && vegetarian(&mons[corpsenm])); + return (boolean) (ismnum(corpsenm) && vegetarian(&mons[corpsenm])); } return FALSE; } diff --git a/src/sp_lev.c b/src/sp_lev.c index 17908bc2e..7bbf92a5a 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1977,7 +1977,7 @@ create_monster(monster *m, struct mkroom *croom) if (m->appear_as.str && ((mtmp->data->mlet == S_MIMIC) /* shapechanger (chameleons, et al, and vampires) */ - || (mtmp->cham >= LOW_PM && m->appear == M_AP_MONSTER)) + || (ismnum(mtmp->cham) && m->appear == M_AP_MONSTER)) && !Protection_from_shape_changers) { int i; diff --git a/src/trap.c b/src/trap.c index 1de2f3516..c9f227c19 100644 --- a/src/trap.c +++ b/src/trap.c @@ -741,7 +741,7 @@ animate_statue( mon = makemon(&mons[PM_DOPPELGANGER], x, y, mmflags); /* if hero has protection from shape changers, cham field will be NON_PM; otherwise, set form to match the statue */ - if (mon && mon->cham >= LOW_PM) + if (mon && ismnum(mon->cham)) (void) newcham(mon, mptr, NO_NC_FLAGS); } else { if (cause == ANIMATE_SPELL) diff --git a/src/uhitm.c b/src/uhitm.c index 886e62b44..41896c95f 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1127,7 +1127,7 @@ hmon_hitmon_misc_obj( ; /* maybe turn the corpse into a statue? */ #endif } - hmd->dmg = (obj->corpsenm >= LOW_PM ? mons[obj->corpsenm].msize + hmd->dmg = (ismnum(obj->corpsenm) ? mons[obj->corpsenm].msize : 0) + 1; break; @@ -1149,14 +1149,14 @@ hmon_hitmon_misc_obj( hand-to-hand attack should yield a "bashing" mesg */ if (obj == uwep) gu.unweapon = TRUE; - if (obj->spe && obj->corpsenm >= LOW_PM) { + if (obj->spe && ismnum(obj->corpsenm)) { if (obj->quan < 5L) change_luck((schar) - (obj->quan)); else change_luck(-5); } - if (obj->corpsenm >= LOW_PM + if (ismnum(obj->corpsenm) && touch_petrifies(&mons[obj->corpsenm])) { /*learn_egg_type(obj->corpsenm);*/ pline("Splat! You hit %s with %s %s egg%s!", @@ -1178,7 +1178,7 @@ hmon_hitmon_misc_obj( } else { /* ordinary egg(s) */ enum monnums mnum = obj->corpsenm; const char *eggp = - (mnum >= LOW_PM && mnum < NUMMONS && obj->known) + (ismnum(mnum) && obj->known) ? the(mons[mnum].pmnames[NEUTRAL]) : (cnt > 1L) ? "some" : "an"; diff --git a/src/zap.c b/src/zap.c index 751e47352..09553e182 100644 --- a/src/zap.c +++ b/src/zap.c @@ -283,7 +283,7 @@ bhitm(struct monst *mtmp, struct obj *otmp) /* if shapechange failed because there aren't enough eligible candidates (most likely for vampshifter), try reverting to original form */ - || (mtmp->cham >= LOW_PM + || (ismnum(mtmp->cham) && newcham(mtmp, &mons[mtmp->cham], ncflags) != 0)) { if (give_msg && (canspotmon(mtmp) @@ -5719,7 +5719,7 @@ destroy_item(int osym, int dmgtyp) || objects[obj->otyp].oc_oprop == FLYING)) /* destroyed wands and potions of polymorph don't trigger polymorph so don't need to be deferred */ - || (obj->otyp == POT_WATER && u.ulycn >= LOW_PM + || (obj->otyp == POT_WATER && ismnum(u.ulycn) && (Upolyd ? obj->blessed : obj->cursed)))) { deferrals[deferral_indx++] = obj->o_id; continue;