cham changes (trunk only)
This is a foundation patch for patches to follow. - use a full short index for mon->cham field. - The current system of providing CHAM_XXX values was limited to the 3 bits allocated in the bitfield and invalidated save/bones if the field was expanded. - The current system didn't provide an easy backwards change if multiple monster types wanted to use the bit, there was a one to one mapping: For instance, if you wanted a CHAM_VAMPIRE, and you wanted vampires, vampire lords, and Vlad to use it, you would have to have CHAM_VAMPIRE, CHAM_VAMPIRE_LORD, and CHAM_VLAD defined to achieve that with the one-to-one backward mapping. - This new way just uses the mon[] index in the mon->cham field and eliminates the need for CHAM_XXX (CHAM_ORDINARY is still used). - no longer requires the cham_to_pm mappings
This commit is contained in:
@@ -251,7 +251,7 @@ moveloop()
|
||||
stop_occupation();
|
||||
else
|
||||
nomul(0);
|
||||
if (change == 1) polyself(FALSE);
|
||||
if (change == 1) polyself(0);
|
||||
else you_were();
|
||||
change = 0;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)apply.c 3.4 2003/11/18 */
|
||||
/* SCCS Id: @(#)apply.c 3.4 2004/06/12 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
|
||||
@@ -636,7 +636,7 @@ wiz_panic()
|
||||
STATIC_PTR int
|
||||
wiz_polyself()
|
||||
{
|
||||
polyself(TRUE);
|
||||
polyself(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -920,7 +920,7 @@ finish_meating(mtmp)
|
||||
struct monst *mtmp;
|
||||
{
|
||||
mtmp->meating = 0;
|
||||
if (mtmp->m_ap_type && mtmp->mappearance && !mtmp->cham) {
|
||||
if (mtmp->m_ap_type && mtmp->mappearance && mtmp->cham == CHAM_ORDINARY) {
|
||||
/* was eating a mimic and now appearance needs resetting */
|
||||
mtmp->m_ap_type = 0;
|
||||
mtmp->mappearance = 0;
|
||||
|
||||
@@ -875,7 +875,7 @@ register int pm;
|
||||
/* case PM_SANDESTIN: */
|
||||
if (!Unchanging) {
|
||||
You_feel("a change coming over you.");
|
||||
polyself(FALSE);
|
||||
polyself(0);
|
||||
}
|
||||
break;
|
||||
case PM_MIND_FLAYER:
|
||||
|
||||
@@ -581,7 +581,7 @@ drinksink()
|
||||
case 10: pline("This water contains toxic wastes!");
|
||||
if (!Unchanging) {
|
||||
You("undergo a freakish metamorphosis!");
|
||||
polyself(FALSE);
|
||||
polyself(0);
|
||||
}
|
||||
break;
|
||||
/* more odd messages --JJB */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)mhitu.c 3.4 2003/11/26 */
|
||||
/* SCCS Id: @(#)mhitu.c 3.4 2004/06/12 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -467,14 +467,14 @@ mattacku(mtmp)
|
||||
}
|
||||
|
||||
/* Special demon handling code */
|
||||
if(!mtmp->cham && is_demon(mdat) && !range2
|
||||
if((mtmp->cham == CHAM_ORDINARY) && is_demon(mdat) && !range2
|
||||
&& mtmp->data != &mons[PM_BALROG]
|
||||
&& mtmp->data != &mons[PM_SUCCUBUS]
|
||||
&& mtmp->data != &mons[PM_INCUBUS])
|
||||
if(!mtmp->mcan && !rn2(13)) msummon(mtmp);
|
||||
|
||||
/* Special lycanthrope handling code */
|
||||
if(!mtmp->cham && is_were(mdat) && !range2) {
|
||||
if((mtmp->cham == CHAM_ORDINARY) && is_were(mdat) && !range2) {
|
||||
|
||||
if(is_human(mdat)) {
|
||||
if(!rn2(5 - (night() * 2)) && !mtmp->mcan) new_were(mtmp);
|
||||
|
||||
@@ -136,7 +136,7 @@ boolean talk;
|
||||
}
|
||||
}
|
||||
|
||||
#define Athome (Inhell && !mtmp->cham)
|
||||
#define Athome (Inhell && (mtmp->cham == CHAM_ORDINARY))
|
||||
|
||||
int
|
||||
demon_talk(mtmp) /* returns 1 if it won't attack. */
|
||||
|
||||
74
src/mon.c
74
src/mon.c
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)mon.c 3.4 2004/05/21 */
|
||||
/* SCCS Id: @(#)mon.c 3.4 2004/06/12 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -120,30 +120,21 @@ int mndx, mode;
|
||||
return mndx;
|
||||
}
|
||||
|
||||
/* convert monster index to chameleon index */
|
||||
/* return monster index if chameleon, or CHAM_ORDINARY if not */
|
||||
int
|
||||
pm_to_cham(mndx)
|
||||
int mndx;
|
||||
{
|
||||
int mcham;
|
||||
int mcham = CHAM_ORDINARY;
|
||||
|
||||
switch (mndx) {
|
||||
case PM_CHAMELEON: mcham = CHAM_CHAMELEON; break;
|
||||
case PM_DOPPELGANGER: mcham = CHAM_DOPPELGANGER; break;
|
||||
case PM_SANDESTIN: mcham = CHAM_SANDESTIN; break;
|
||||
default: mcham = CHAM_ORDINARY; break;
|
||||
}
|
||||
/*
|
||||
* 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;
|
||||
return mcham;
|
||||
}
|
||||
|
||||
/* convert chameleon index to monster index */
|
||||
STATIC_VAR short cham_to_pm[] = {
|
||||
NON_PM, /* placeholder for CHAM_ORDINARY */
|
||||
PM_CHAMELEON,
|
||||
PM_DOPPELGANGER,
|
||||
PM_SANDESTIN,
|
||||
};
|
||||
|
||||
/* for deciding whether corpse will carry along full monster data */
|
||||
#define KEEPTRAITS(mon) ((mon)->isshk || (mon)->mtame || \
|
||||
unique_corpstat(mon->data) || \
|
||||
@@ -1458,8 +1449,10 @@ register struct monst *mtmp;
|
||||
|
||||
mptr = mtmp->data; /* save this for m_detach() */
|
||||
/* restore chameleon, lycanthropes to true form at death */
|
||||
if (mtmp->cham)
|
||||
set_mon_data(mtmp, &mons[cham_to_pm[mtmp->cham]], -1);
|
||||
if (mtmp->cham != CHAM_ORDINARY) {
|
||||
set_mon_data(mtmp, &mons[mtmp->cham], -1);
|
||||
mtmp->cham = CHAM_ORDINARY;
|
||||
}
|
||||
else if (mtmp->data == &mons[PM_WEREJACKAL])
|
||||
set_mon_data(mtmp, &mons[PM_HUMAN_WEREJACKAL], -1);
|
||||
else if (mtmp->data == &mons[PM_WEREWOLF])
|
||||
@@ -2174,10 +2167,10 @@ rescham()
|
||||
for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||
if (DEADMONSTER(mtmp)) continue;
|
||||
mcham = (int) mtmp->cham;
|
||||
if (mcham) {
|
||||
mtmp->cham = CHAM_ORDINARY;
|
||||
(void) newcham(mtmp, &mons[cham_to_pm[mcham]],
|
||||
if (mcham != CHAM_ORDINARY) {
|
||||
(void) newcham(mtmp, &mons[mcham],
|
||||
FALSE, FALSE);
|
||||
mtmp->cham = CHAM_ORDINARY;
|
||||
}
|
||||
if(is_were(mtmp->data) && mtmp->data->mlet != S_HUMAN)
|
||||
new_were(mtmp);
|
||||
@@ -2218,9 +2211,9 @@ struct monst *mon;
|
||||
|
||||
if (Protection_from_shape_changers) {
|
||||
mcham = (int) mon->cham;
|
||||
if (mcham) {
|
||||
if (mcham != CHAM_ORDINARY) {
|
||||
mon->cham = CHAM_ORDINARY;
|
||||
(void) newcham(mon, &mons[cham_to_pm[mcham]], FALSE, FALSE);
|
||||
(void) newcham(mon, &mons[mcham], FALSE, FALSE);
|
||||
} else if (is_were(mon->data) && !is_human(mon->data)) {
|
||||
new_were(mon);
|
||||
}
|
||||
@@ -2234,7 +2227,7 @@ STATIC_OVL boolean
|
||||
restrap(mtmp)
|
||||
register struct monst *mtmp;
|
||||
{
|
||||
if(mtmp->cham || mtmp->mcan || mtmp->m_ap_type ||
|
||||
if((mtmp->cham != CHAM_ORDINARY) || 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);
|
||||
@@ -2313,24 +2306,39 @@ pick_animal()
|
||||
return animal_list[rn2(animal_list_count)];
|
||||
}
|
||||
|
||||
STATIC_OVL int
|
||||
int
|
||||
select_newcham_form(mon)
|
||||
struct monst *mon;
|
||||
{
|
||||
int mndx = NON_PM;
|
||||
|
||||
switch (mon->cham) {
|
||||
case CHAM_SANDESTIN:
|
||||
case PM_SANDESTIN:
|
||||
if (rn2(7)) mndx = pick_nasty();
|
||||
break;
|
||||
case CHAM_DOPPELGANGER:
|
||||
case PM_DOPPELGANGER:
|
||||
if (!rn2(7)) mndx = pick_nasty();
|
||||
else if (rn2(3)) mndx = rn1(PM_WIZARD - PM_ARCHEOLOGIST + 1,
|
||||
PM_ARCHEOLOGIST);
|
||||
break;
|
||||
case CHAM_CHAMELEON:
|
||||
case PM_CHAMELEON:
|
||||
if (!rn2(3)) mndx = pick_animal();
|
||||
break;
|
||||
case PM_VLAD_THE_IMPALER:
|
||||
case PM_VAMPIRE_LORD:
|
||||
case PM_VAMPIRE:
|
||||
if (mon_has_special(mon) && /* ensure Vlad can carry it still */
|
||||
mon->cham == PM_VLAD_THE_IMPALER) {
|
||||
mndx = PM_VLAD_THE_IMPALER;
|
||||
break;
|
||||
}
|
||||
if (!rn2(10) && mon->cham != PM_VAMPIRE) {
|
||||
/* VAMPIRE_LORD || VLAD */
|
||||
mndx = PM_WOLF;
|
||||
break;
|
||||
}
|
||||
mndx = !rn2(4) ? PM_FOG_CLOUD : PM_VAMPIRE_BAT;
|
||||
break;
|
||||
case CHAM_ORDINARY:
|
||||
{
|
||||
struct obj *m_armr = which_armor(mon, W_ARM);
|
||||
@@ -2649,12 +2657,12 @@ void
|
||||
kill_genocided_monsters()
|
||||
{
|
||||
struct monst *mtmp, *mtmp2;
|
||||
boolean kill_cham[CHAM_MAX_INDX+1];
|
||||
boolean kill_cham[NUMMONS];
|
||||
int mndx;
|
||||
|
||||
kill_cham[CHAM_ORDINARY] = FALSE; /* (this is mndx==0) */
|
||||
for (mndx = 1; mndx <= CHAM_MAX_INDX; mndx++)
|
||||
kill_cham[mndx] = (mvitals[cham_to_pm[mndx]].mvflags & G_GENOD) != 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
|
||||
@@ -2671,7 +2679,7 @@ kill_genocided_monsters()
|
||||
if (DEADMONSTER(mtmp)) continue;
|
||||
mndx = monsndx(mtmp->data);
|
||||
if ((mvitals[mndx].mvflags & G_GENOD) || kill_cham[mtmp->cham]) {
|
||||
if (mtmp->cham && !kill_cham[mtmp->cham])
|
||||
if ((mtmp->cham != CHAM_ORDINARY) && !kill_cham[mtmp->cham])
|
||||
(void) newcham(mtmp, (struct permonst *)0, FALSE, FALSE);
|
||||
else
|
||||
mondead(mtmp);
|
||||
|
||||
@@ -94,6 +94,7 @@ 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),
|
||||
@@ -2357,7 +2358,7 @@ struct permonst _mons2[] = {
|
||||
NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(WT_HUMAN, 400, 0, MS_IMITATE, MZ_HUMAN), MR_SLEEP, 0,
|
||||
M1_HUMANOID|M1_OMNIVORE,
|
||||
M2_NOPOLY|M2_HUMAN|M2_HOSTILE|M2_STRONG|M2_COLLECT,
|
||||
M2_NOPOLY|M2_HUMAN|M2_HOSTILE|M2_STRONG|M2_COLLECT|M2_SHAPESHIFTER,
|
||||
M3_INFRAVISIBLE, HI_DOMESTIC),
|
||||
MON("nurse", S_HUMAN,
|
||||
LVL(11, 6, 0, 0, 0), (G_GENO|3),
|
||||
@@ -2791,7 +2792,7 @@ struct permonst _mons2[] = {
|
||||
A(ATTK(AT_WEAP, AD_PHYS, 2, 6), ATTK(AT_WEAP, AD_PHYS, 2, 6),
|
||||
NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(1500, 400, 0, MS_CUSS, MZ_HUMAN), MR_STONE, 0,
|
||||
M1_HUMANOID, M2_NOPOLY|M2_STALK|M2_STRONG|M2_COLLECT,
|
||||
M1_HUMANOID, M2_NOPOLY|M2_STALK|M2_STRONG|M2_COLLECT|M2_SHAPESHIFTER,
|
||||
M3_INFRAVISIBLE|M3_INFRAVISION, CLR_GRAY),
|
||||
/*
|
||||
* sea monsters
|
||||
@@ -2883,7 +2884,8 @@ struct permonst _mons2[] = {
|
||||
A(ATTK(AT_BITE, AD_PHYS, 4, 2),
|
||||
NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
|
||||
SIZ(100, 100, 0, MS_SILENT, MZ_TINY), 0, 0,
|
||||
M1_ANIMAL|M1_NOHANDS|M1_CARNIVORE, M2_NOPOLY|M2_HOSTILE, 0, CLR_BROWN),
|
||||
M1_ANIMAL|M1_NOHANDS|M1_CARNIVORE, M2_NOPOLY|M2_HOSTILE|M2_SHAPESHIFTER,
|
||||
0, CLR_BROWN),
|
||||
MON("crocodile", S_LIZARD,
|
||||
LVL(6, 9, 5, 0, 0), (G_GENO|1),
|
||||
A(ATTK(AT_BITE, AD_PHYS, 4, 2), ATTK(AT_CLAW, AD_PHYS, 1,12),
|
||||
|
||||
11
src/muse.c
11
src/muse.c
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)muse.c 3.4 2002/12/23 */
|
||||
/* SCCS Id: @(#)muse.c 3.4 2004/06/12 */
|
||||
/* Copyright (C) 1990 by Ken Arromdee */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -1588,7 +1588,8 @@ struct monst *mtmp;
|
||||
if(dist2(x, y, mtmp->mux, mtmp->muy) > 36)
|
||||
return FALSE;
|
||||
|
||||
if (!stuck && !immobile && !mtmp->cham && monstr[monsndx(mdat)] < 6) {
|
||||
if (!stuck && !immobile &&
|
||||
(mtmp->cham == CHAM_ORDINARY) && monstr[monsndx(mdat)] < 6) {
|
||||
boolean ignore_boulders = (verysmall(mdat) ||
|
||||
throws_rocks(mdat) ||
|
||||
passes_walls(mdat));
|
||||
@@ -1658,13 +1659,15 @@ struct monst *mtmp;
|
||||
m.has_misc = MUSE_POT_SPEED;
|
||||
}
|
||||
nomore(MUSE_WAN_POLYMORPH);
|
||||
if(obj->otyp == WAN_POLYMORPH && obj->spe > 0 && !mtmp->cham
|
||||
if(obj->otyp == WAN_POLYMORPH && obj->spe > 0
|
||||
&& (mtmp->cham == CHAM_ORDINARY)
|
||||
&& monstr[monsndx(mdat)] < 6) {
|
||||
m.misc = obj;
|
||||
m.has_misc = MUSE_WAN_POLYMORPH;
|
||||
}
|
||||
nomore(MUSE_POT_POLYMORPH);
|
||||
if(obj->otyp == POT_POLYMORPH && !mtmp->cham
|
||||
if(obj->otyp == POT_POLYMORPH
|
||||
&& (mtmp->cham == CHAM_ORDINARY)
|
||||
&& monstr[monsndx(mdat)] < 6) {
|
||||
m.misc = obj;
|
||||
m.has_misc = MUSE_POT_POLYMORPH;
|
||||
|
||||
@@ -309,7 +309,7 @@ register struct monst *mtmp;
|
||||
}
|
||||
else if (mtmp->mpeaceful) Strcat(info, ", peaceful");
|
||||
if (mtmp->meating) Strcat(info, ", eating");
|
||||
if (mtmp->meating && !mtmp->cham &&
|
||||
if (mtmp->meating && (mtmp->cham == CHAM_ORDINARY) &&
|
||||
mtmp->mappearance && mtmp->m_ap_type) {
|
||||
Sprintf(eos(info), ", mimicing %s",
|
||||
(mtmp->m_ap_type == M_AP_FURNITURE) ?
|
||||
|
||||
@@ -225,13 +225,14 @@ dead: /* we come directly here if their experience level went to 0 or less */
|
||||
}
|
||||
|
||||
void
|
||||
polyself(forcecontrol)
|
||||
boolean forcecontrol;
|
||||
polyself(psflags)
|
||||
int psflags;
|
||||
{
|
||||
char buf[BUFSZ];
|
||||
int old_light, new_light;
|
||||
int mntmp = NON_PM;
|
||||
int tries=0;
|
||||
boolean forcecontrol = (psflags == 1);
|
||||
boolean draconian = (uarm &&
|
||||
uarm->otyp >= GRAY_DRAGON_SCALE_MAIL &&
|
||||
uarm->otyp <= YELLOW_DRAGON_SCALES);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)potion.c 3.4 2003/11/26 */
|
||||
/* SCCS Id: @(#)potion.c 3.4 2004/06/12 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -918,7 +918,7 @@ peffects(otmp)
|
||||
break;
|
||||
case POT_POLYMORPH:
|
||||
You_feel("a little %s.", Hallucination ? "normal" : "strange");
|
||||
if (!Unchanging) polyself(FALSE);
|
||||
if (!Unchanging) polyself(0);
|
||||
break;
|
||||
default:
|
||||
impossible("What a funny potion! (%u)", otmp->otyp);
|
||||
@@ -1055,7 +1055,7 @@ boolean your_fault;
|
||||
break;
|
||||
case POT_POLYMORPH:
|
||||
You_feel("a little %s.", Hallucination ? "normal" : "strange");
|
||||
if (!Unchanging && !Antimagic) polyself(FALSE);
|
||||
if (!Unchanging && !Antimagic) polyself(0);
|
||||
break;
|
||||
case POT_ACID:
|
||||
if (!Acid_resistance) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)trap.c 3.4 2003/12/26 */
|
||||
/* SCCS Id: @(#)trap.c 3.4 2004/06/12 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -1100,7 +1100,7 @@ glovecheck: (void) rust_dmg(uarmg, "gauntlets", 1, TRUE, &youmonst);
|
||||
deltrap(trap); /* delete trap before polymorph */
|
||||
newsym(u.ux,u.uy); /* get rid of trap symbol */
|
||||
You_feel("a change coming over you.");
|
||||
polyself(FALSE);
|
||||
polyself(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)zap.c 3.4 2003/11/26 */
|
||||
/* SCCS Id: @(#)zap.c 3.4 2004/06/12 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -634,7 +634,7 @@ register struct obj *obj;
|
||||
mtmp = makemon(&mons[montype], x, y,
|
||||
NO_MINVENT | MM_NOWAIT);
|
||||
if (mtmp) {
|
||||
if (mtmp->cham == CHAM_DOPPELGANGER) {
|
||||
if (mtmp->cham == PM_DOPPELGANGER) {
|
||||
/* change shape to match the corpse */
|
||||
(void) newcham(mtmp, mptr, FALSE, FALSE);
|
||||
} else if (mtmp->data->mlet == S_ZOMBIE) {
|
||||
@@ -1983,7 +1983,7 @@ boolean ordinary;
|
||||
makeknown(WAN_POLYMORPH);
|
||||
case SPE_POLYMORPH:
|
||||
if (!Unchanging)
|
||||
polyself(FALSE);
|
||||
polyself(0);
|
||||
break;
|
||||
|
||||
case WAN_CANCELLATION:
|
||||
|
||||
Reference in New Issue
Block a user