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.
This commit is contained in:
nethack.allison
2006-03-12 04:43:28 +00:00
parent e1ef0f1042
commit 0b88609133
15 changed files with 48 additions and 51 deletions
+27 -27
View File
@@ -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);
}