From 0b88609133844ba215b0e383b76bd195562e14be Mon Sep 17 00:00:00 2001 From: "nethack.allison" Date: Sun, 12 Mar 2006 04:43:28 +0000 Subject: [PATCH] chameleon behaviour - restore intended behaviour of kill_genocided_monsters(). It has been incorrect since the chameleon overhaul in June 2004. - eliminate CHAM_ORDINARY and use NON_PM instead. --- include/monst.h | 1 - include/obj.h | 3 +-- src/dogmove.c | 2 +- src/makemon.c | 8 ++++---- src/mhitm.c | 2 +- src/mhitu.c | 4 ++-- src/minion.c | 2 +- src/mon.c | 54 ++++++++++++++++++++++++------------------------- src/monmove.c | 6 +++--- src/monst.c | 1 - src/muse.c | 6 +++--- src/pline.c | 2 +- src/read.c | 2 +- src/trap.c | 4 ++-- src/zap.c | 2 +- 15 files changed, 48 insertions(+), 51 deletions(-) diff --git a/include/monst.h b/include/monst.h index c25344dfb..b46598dd0 100644 --- a/include/monst.h +++ b/include/monst.h @@ -43,7 +43,6 @@ struct monst { unsigned m_id; short mnum; /* permanent monster index number */ short cham; /* if shapeshifter, orig mons[] idx goes here */ -#define CHAM_ORDINARY 0 /* not a shapechanger */ short movement; /* movement points (derived from permonst definition and added effects */ uchar m_lev; /* adjusted difficulty level of monster */ aligntyp malign; /* alignment of this monster, relative to the diff --git a/include/obj.h b/include/obj.h index 355b16556..32b3e0aae 100644 --- a/include/obj.h +++ b/include/obj.h @@ -210,8 +210,7 @@ struct obj { #define MAX_EGG_HATCH_TIME 200 /* longest an egg can remain unhatched */ #define stale_egg(egg) ((monstermoves - (egg)->age) > (2*MAX_EGG_HATCH_TIME)) #define ofood(o) ((o)->otyp == CORPSE || (o)->otyp == EGG || (o)->otyp == TIN) -#define polyfodder(obj) (ofood(obj) && \ - pm_to_cham((obj)->corpsenm) != CHAM_ORDINARY) +#define polyfodder(obj) (ofood(obj) && pm_to_cham((obj)->corpsenm) != NON_PM) #define mlevelgain(obj) (ofood(obj) && (obj)->corpsenm == PM_WRAITH) #define mhealup(obj) (ofood(obj) && (obj)->corpsenm == PM_NURSE) diff --git a/src/dogmove.c b/src/dogmove.c index 3675736a0..88224d431 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -979,7 +979,7 @@ finish_meating(mtmp) struct monst *mtmp; { mtmp->meating = 0; - if (mtmp->m_ap_type && mtmp->mappearance && mtmp->cham == CHAM_ORDINARY) { + if (mtmp->m_ap_type && mtmp->mappearance && mtmp->cham == NON_PM) { /* was eating a mimic and now appearance needs resetting */ mtmp->m_ap_type = 0; mtmp->mappearance = 0; diff --git a/src/makemon.c b/src/makemon.c index 8efc35bfd..6984d593e 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)makemon.c 3.5 2005/11/02 */ +/* SCCS Id: @(#)makemon.c 3.5 2006/03/11 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1030,11 +1030,11 @@ register int mmflags; if (mndx == PM_VLAD_THE_IMPALER) mitem = CANDELABRUM_OF_INVOCATION; - mtmp->cham = CHAM_ORDINARY; /* default is "not a shapechanger" */ - if ((mcham = pm_to_cham(mndx)) != CHAM_ORDINARY) { + mtmp->cham = NON_PM; /* default is "not a shapechanger" */ + if ((mcham = pm_to_cham(mndx)) != NON_PM) { /* this is a shapechanger after all */ if (Protection_from_shape_changers) { - ; /* stuck in its natural form (CHAM_ORDINARY) */ + ; /* stuck in its natural form (NON_PM) */ } else { /* General shapechangers start out with random form (this explicitly picks something from the normal diff --git a/src/mhitm.c b/src/mhitm.c index dc8a050c1..eaf960866 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1237,7 +1237,7 @@ mdamagem(magr, mdef, mattk) if (mattk->adtyp == AD_DGST) { /* various checks similar to dog_eat and meatobj. * after monkilled() to provide better message ordering */ - if (mdef->cham != CHAM_ORDINARY) { + if (mdef->cham >= LOW_PM) { (void) newcham(magr, (struct permonst *)0, FALSE, TRUE); } else if (mdef->data == &mons[PM_GREEN_SLIME]) { (void) newcham(magr, &mons[PM_GREEN_SLIME], FALSE, TRUE); diff --git a/src/mhitu.c b/src/mhitu.c index 2e4d96df1..32d4e9d3a 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -469,14 +469,14 @@ mattacku(mtmp) } /* Special demon handling code */ - if((mtmp->cham == CHAM_ORDINARY) && is_demon(mdat) && !range2 + if((mtmp->cham == NON_PM) && is_demon(mdat) && !range2 && mtmp->data != &mons[PM_BALROG] && mtmp->data != &mons[PM_SUCCUBUS] && mtmp->data != &mons[PM_INCUBUS]) if (!mtmp->mcan && !rn2(13)) (void)msummon(mtmp); /* Special lycanthrope handling code */ - if((mtmp->cham == CHAM_ORDINARY) && is_were(mdat) && !range2) { + if((mtmp->cham == NON_PM) && is_were(mdat) && !range2) { if(is_human(mdat)) { if(!rn2(5 - (night() * 2)) && !mtmp->mcan) new_were(mtmp); diff --git a/src/minion.c b/src/minion.c index 07b125b37..6fd9d26b6 100644 --- a/src/minion.c +++ b/src/minion.c @@ -169,7 +169,7 @@ boolean talk; } } -#define Athome (Inhell && (mtmp->cham == CHAM_ORDINARY)) +#define Athome (Inhell && (mtmp->cham == NON_PM)) int demon_talk(mtmp) /* returns 1 if it won't attack. */ diff --git a/src/mon.c b/src/mon.c index 91bb3e81c..dafaee257 100644 --- a/src/mon.c +++ b/src/mon.c @@ -119,18 +119,18 @@ int mndx, mode; return mndx; } -/* return monster index if chameleon, or CHAM_ORDINARY if not */ +/* return monster index if chameleon, or NON_PM if not */ int pm_to_cham(mndx) int mndx; { - int mcham = CHAM_ORDINARY; + int mcham = NON_PM; /* * As of 3.5.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])) mcham = mndx; + if (mndx >= LOW_PM && is_shapeshifter(&mons[mndx])) mcham = mndx; return mcham; } @@ -529,7 +529,7 @@ mcalcdistress() mon_regen(mtmp, FALSE); /* possibly polymorph shapechangers and lycanthropes */ - if (mtmp->cham != CHAM_ORDINARY) { + if (mtmp->cham >= LOW_PM) { if (is_vampshifter(mtmp) || mtmp->data->mlet == S_VAMPIRE) decide_to_shapeshift(mtmp,0); else if (!rn2(6)) @@ -1470,7 +1470,7 @@ register struct monst *mtmp; int mndx = mtmp->cham; int x = mtmp->mx, y = mtmp->my; /* this only happens if shapeshifted */ - if (mndx != CHAM_ORDINARY && mndx != monsndx(mtmp->data)) { + if (mndx >= LOW_PM && mndx != monsndx(mtmp->data)) { char buf[BUFSZ]; boolean in_door = amorphous(mtmp->data) && closed_door(mtmp->mx,mtmp->my); @@ -1502,7 +1502,7 @@ register struct monst *mtmp; } newcham(mtmp, &mons[mndx], FALSE, FALSE); if (mtmp->data == &mons[mndx]) - mtmp->cham = CHAM_ORDINARY; + mtmp->cham = NON_PM; else mtmp->cham = mndx; if ((!Blind && canseemon(mtmp)) || sensemon(mtmp)) @@ -1520,9 +1520,9 @@ register struct monst *mtmp; mptr = mtmp->data; /* save this for m_detach() */ /* restore chameleon, lycanthropes to true form at death */ - if (mtmp->cham != CHAM_ORDINARY) { + if (mtmp->cham >= LOW_PM) { set_mon_data(mtmp, &mons[mtmp->cham], -1); - mtmp->cham = CHAM_ORDINARY; + mtmp->cham = NON_PM; } else if (mtmp->data == &mons[PM_WEREJACKAL]) set_mon_data(mtmp, &mons[PM_HUMAN_WEREJACKAL], -1); @@ -2231,10 +2231,10 @@ rescham() for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { if (DEADMONSTER(mtmp)) continue; mcham = (int) mtmp->cham; - if (mcham != CHAM_ORDINARY) { + if (mcham >= LOW_PM) { (void) newcham(mtmp, &mons[mcham], FALSE, FALSE); - mtmp->cham = CHAM_ORDINARY; + mtmp->cham = NON_PM; } if(is_were(mtmp->data) && mtmp->data->mlet != S_HUMAN) new_were(mtmp); @@ -2275,13 +2275,13 @@ struct monst *mon; if (Protection_from_shape_changers) { mcham = (int) mon->cham; - if (mcham != CHAM_ORDINARY) { - mon->cham = CHAM_ORDINARY; + if (mcham >= LOW_PM) { + mon->cham = NON_PM; (void) newcham(mon, &mons[mcham], FALSE, FALSE); } else if (is_were(mon->data) && !is_human(mon->data)) { new_were(mon); } - } else if (mon->cham == CHAM_ORDINARY) { + } else if (mon->cham == NON_PM) { mon->cham = pm_to_cham(monsndx(mon->data)); } } @@ -2291,7 +2291,7 @@ STATIC_OVL boolean restrap(mtmp) register struct monst *mtmp; { - if((mtmp->cham != CHAM_ORDINARY) || mtmp->mcan || mtmp->m_ap_type || + if((mtmp->cham >= LOW_PM) || mtmp->mcan || mtmp->m_ap_type || cansee(mtmp->mx, mtmp->my) || rn2(3) || (mtmp == u.ustuck) || (sensemon(mtmp) && distu(mtmp->mx, mtmp->my) <= 2)) return(FALSE); @@ -2387,10 +2387,11 @@ int shiftflags; * If we're shifted and getting low on hp, maybe shift back. * If we're not already shifted and in good health, maybe shift. */ - if ((mon->mhp <= mon->mhpmax / 6) && rn2(4)) + if ((mon->mhp <= mon->mhpmax / 6) && + rn2(4) && (mon->cham >= LOW_PM)) (void) newcham(mon, &mons[mon->cham], FALSE, msg); - } else if (mon->data->mlet == S_VAMPIRE && mon->cham == CHAM_ORDINARY - && !rn2(6) && (mon->mhp > mon->mhpmax - ((mon->mhpmax / 10) + 1))) { + } else if (mon->data->mlet == S_VAMPIRE && mon->cham == NON_PM && + !rn2(6) && (mon->mhp > mon->mhpmax - ((mon->mhpmax / 10) + 1))) { (void) newcham(mon, (struct permonst *)0, FALSE, msg); } } @@ -2428,7 +2429,7 @@ struct monst *mon; } mndx = !rn2(4) ? PM_FOG_CLOUD : PM_VAMPIRE_BAT; break; - case CHAM_ORDINARY: + case NON_PM: /* ordinary */ { struct obj *m_armr = which_armor(mon, W_ARM); @@ -2749,12 +2750,9 @@ void kill_genocided_monsters() { struct monst *mtmp, *mtmp2; - boolean kill_cham[NUMMONS]; + boolean kill_cham; int mndx; - kill_cham[CHAM_ORDINARY] = FALSE; /* (this is mndx==0) */ - for (mndx = LOW_PM; mndx < NUMMONS; mndx++) - kill_cham[mndx] = (mvitals[mndx].mvflags & G_GENOD) != 0; /* * Called during genocide, and again upon level change. The latter * catches up with any migrating monsters as they finally arrive at @@ -2766,15 +2764,17 @@ kill_genocided_monsters() * 2) otherwise, force every chameleon which is imitating * any genocided species to take on a new form. */ - for (mtmp = fmon; mtmp; mtmp = mtmp2) { + for (mtmp = fmon; mtmp; mtmp = mtmp2, kill_cham = FALSE) { mtmp2 = mtmp->nmon; if (DEADMONSTER(mtmp)) continue; mndx = monsndx(mtmp->data); - if ((mvitals[mndx].mvflags & G_GENOD) || kill_cham[mtmp->cham]) { - if ((mtmp->cham != CHAM_ORDINARY) && !kill_cham[mtmp->cham]) - (void) newcham(mtmp, (struct permonst *)0, FALSE, FALSE); + if (mtmp->cham >= LOW_PM && (mvitals[mtmp->cham].mvflags & G_GENOD)) + kill_cham = TRUE; + if ((mvitals[mndx].mvflags & G_GENOD) || kill_cham) { + if (mtmp->cham >= LOW_PM && !kill_cham) + (void) newcham(mtmp, (struct permonst *)0, FALSE, FALSE); else - mondead(mtmp); + mondead(mtmp); } if (mtmp->minvent) kill_eggs(mtmp->minvent); } diff --git a/src/monmove.c b/src/monmove.c index a247d1f3d..ab15b90dc 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1506,11 +1506,11 @@ struct monst *mon; struct permonst *ptr; { int reslt = 0; - if (mon->cham != CHAM_ORDINARY) { + if (mon->cham >= LOW_PM) { if (ptr == &mons[mon->cham]) - mon->cham = CHAM_ORDINARY; + mon->cham = NON_PM; reslt = newcham(mon, ptr, FALSE, FALSE); - } else if (mon->cham == CHAM_ORDINARY && ptr != mon->data) { + } else if (mon->cham == NON_PM && ptr != mon->data) { mon->cham = monsndx(mon->data); reslt = newcham(mon, ptr, FALSE, FALSE); } diff --git a/src/monst.c b/src/monst.c index 87a10cf07..95953e99a 100644 --- a/src/monst.c +++ b/src/monst.c @@ -90,7 +90,6 @@ NEARDATA struct permonst mons[] = { /* * ants */ - /* Never use M2_SHAPESHIFTER for mons[0] as long as CHAM_ORDINARY==0 */ MON("giant ant", S_ANT, LVL(2, 18, 3, 0, 0), (G_GENO|G_SGROUP|3), A(ATTK(AT_BITE, AD_PHYS, 1, 4), diff --git a/src/muse.c b/src/muse.c index 27e111add..9eff95241 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1586,7 +1586,7 @@ struct monst *mtmp; return FALSE; if (!stuck && !immobile && - (mtmp->cham == CHAM_ORDINARY) && monstr[monsndx(mdat)] < 6) { + (mtmp->cham == NON_PM) && monstr[monsndx(mdat)] < 6) { boolean ignore_boulders = (verysmall(mdat) || throws_rocks(mdat) || passes_walls(mdat)); @@ -1657,14 +1657,14 @@ struct monst *mtmp; } nomore(MUSE_WAN_POLYMORPH); if(obj->otyp == WAN_POLYMORPH && obj->spe > 0 - && (mtmp->cham == CHAM_ORDINARY) + && (mtmp->cham == NON_PM) && monstr[monsndx(mdat)] < 6) { m.misc = obj; m.has_misc = MUSE_WAN_POLYMORPH; } nomore(MUSE_POT_POLYMORPH); if(obj->otyp == POT_POLYMORPH - && (mtmp->cham == CHAM_ORDINARY) + && (mtmp->cham == NON_PM) && monstr[monsndx(mdat)] < 6) { m.misc = obj; m.has_misc = MUSE_POT_POLYMORPH; diff --git a/src/pline.c b/src/pline.c index 1eac6094a..a992836f4 100644 --- a/src/pline.c +++ b/src/pline.c @@ -317,7 +317,7 @@ register struct monst *mtmp; } else if (mtmp->mpeaceful) Strcat(info, ", peaceful"); if (mtmp->meating) Strcat(info, ", eating"); - if (mtmp->meating && (mtmp->cham == CHAM_ORDINARY) && + if (mtmp->meating && (mtmp->cham == NON_PM) && mtmp->mappearance && mtmp->m_ap_type) { Sprintf(eos(info), ", mimicing %s", (mtmp->m_ap_type == M_AP_FURNITURE) ? diff --git a/src/read.c b/src/read.c index 173cdab05..1ce663fb6 100644 --- a/src/read.c +++ b/src/read.c @@ -2068,7 +2068,7 @@ create_particular() } if (mtmp) { madeany = TRUE; - if (mtmp->cham != CHAM_ORDINARY && firstchoice != NON_PM) + if (mtmp->cham >= LOW_PM && firstchoice != NON_PM) (void)newcham(mtmp, &mons[firstchoice], FALSE, FALSE); } } diff --git a/src/trap.c b/src/trap.c index d8d8eb9cf..9b757ea8d 100644 --- a/src/trap.c +++ b/src/trap.c @@ -449,8 +449,8 @@ int *fail_reason; mon = makemon(&mons[PM_DOPPELGANGER], x, y, NO_MINVENT | MM_NOCOUNTBIRTH | MM_ADJACENTOK); /* if hero has protection from shape changers, cham field will - be CHAM_ORDINARY; otherwise, set form to match the statue */ - if (mon && mon->cham != CHAM_ORDINARY) + be NON_PM; otherwise, set form to match the statue */ + if (mon && mon->cham >= LOW_PM) (void) newcham(mon, mptr, FALSE, FALSE); } else mon = makemon(mptr, x, y, (cause == ANIMATE_SPELL) ? diff --git a/src/zap.c b/src/zap.c index ce803bed6..63ff37de2 100644 --- a/src/zap.c +++ b/src/zap.c @@ -229,7 +229,7 @@ struct obj *otmp; /* natural shapechangers aren't affected by system shock (unless protection from shapechangers is interfering with their metabolism...) */ - if (mtmp->cham == CHAM_ORDINARY && !rn2(25)) { + if (mtmp->cham == NON_PM && !rn2(25)) { if (canseemon(mtmp)) { pline("%s shudders!", Monnam(mtmp)); learn_it = TRUE; -- 2.40.0