mimic statues & 2009 startup banner (trunk only)

A mimic posing as a statue was displayed as a tengu statue (and
recognizeable as such now that statues are displayed as the corresponding
monster rather than rock-class back tick), but the lookat code described
it as a giant ant statue (since there was no obj->corpsenm available to
indicate the monster type, it defaulted to 0).  This adds monst->mextra
field `mcorpsenm' so that mimics have a place to remember what sort of
statue or corpse they are mimicking.  And it picks a random monster type
when they take such forms so that the old tengu hack becomes irrelevant.

     newmextra() and newoextra() initialized pointers via memset(...,0)
which is not portable; switch to explicit assignments.  The wizard mode
code to display memory used for monsters and objects added in amounts
for the miscellaneous things pointed to by monst->mextra and obj->oextra
structs but didn't include memory for those structs themselves; add it.
Simplify monster save/restore slightly; there's no need for extra zeroes
to represent monst->mextra->X sizes when monst->mextra is null.

     Update the startup banner for 2009.  I should have done this with a
separate patch but I'm taking a shortcut.  :-]
This commit is contained in:
nethack.rankin
2009-01-31 08:03:41 +00:00
parent 0def692d5f
commit 71219bf093
12 changed files with 124 additions and 71 deletions

View File

@@ -2374,6 +2374,7 @@ struct obj *otmp;
int sz = (int)sizeof (struct obj);
if (otmp->oextra) {
sz += (int)sizeof (struct oextra);
if (ONAME(otmp)) sz += (int)strlen(ONAME(otmp)) + 1;
if (OMONST(otmp)) sz += (int)sizeof (struct monst);
if (OMID(otmp)) sz += (int)sizeof (unsigned);
@@ -2479,12 +2480,14 @@ struct monst *mtmp;
int sz = (int)sizeof (struct monst);
if (mtmp->mextra) {
sz += (int)sizeof (struct mextra);
if (MNAME(mtmp)) sz += (int)strlen(MNAME(mtmp)) + 1;
if (EGD(mtmp)) sz += (int)sizeof (struct egd);
if (EPRI(mtmp)) sz += (int)sizeof (struct epri);
if (ESHK(mtmp)) sz += (int)sizeof (struct eshk);
if (EMIN(mtmp)) sz += (int)sizeof (struct emin);
if (EDOG(mtmp)) sz += (int)sizeof (struct edog);
/* mextra->mcorpsenm doesn't point to more memory */
}
return sz;
}

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)display.c 3.5 2007/06/25 */
/* SCCS Id: @(#)display.c 3.5 2009/01/30 */
/* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */
/* and Dave Cohrs, 1990. */
/* NetHack may be freely redistributed. See license for details. */
@@ -420,11 +420,12 @@ display_monster(x, y, mon, sightflags, worm_tail)
case M_AP_OBJECT: {
struct obj obj; /* Make a fake object to send */
/* to map_object(). */
obj.oextra = (struct oextra *)0;
obj = zeroobj;
obj.ox = x;
obj.oy = y;
obj.otyp = mon->mappearance;
obj.corpsenm = PM_TENGU; /* if mimicing a corpse */
/* might be mimicing a corpse or statue */
obj.corpsenm = has_mcorpsenm(mon) ? MCORPSENM(mon) : PM_TENGU;
map_object(&obj,!sensed);
break;
}

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)makemon.c 3.5 2007/03/23 */
/* SCCS Id: @(#)makemon.c 3.5 2009/01/30 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -859,9 +859,15 @@ struct mextra *
newmextra()
{
struct mextra *mextra;
mextra = (struct mextra *)alloc(sizeof(struct mextra));
if (mextra)
(void) memset((genericptr_t)mextra, 0, sizeof(struct mextra));
mextra->mname = 0;
mextra->egd = 0;
mextra->epri = 0;
mextra->eshk = 0;
mextra->emin = 0;
mextra->edog = 0;
mextra->mcorpsenm = NON_PM;
return mextra;
}
@@ -1732,6 +1738,23 @@ struct monst *mtmp;
mtmp->malign = abs(mal);
}
/* allocate a new mcorpsenm field for a monster; only need mextra itself */
void
newmcorpsenm(mtmp)
struct monst *mtmp;
{
if (!mtmp->mextra) mtmp->mextra = newmextra();
MCORPSENM(mtmp) = NON_PM; /* not initialized yet */
}
/* release monster's mcorpsenm field; basically a no-op */
void
freemcorpsenm(mtmp)
struct monst *mtmp;
{
if (has_mcorpsenm(mtmp)) MCORPSENM(mtmp) = NON_PM;
}
static NEARDATA char syms[] = {
MAXOCLASSES, MAXOCLASSES+1, RING_CLASS, WAND_CLASS, WEAPON_CLASS,
FOOD_CLASS, COIN_CLASS, SCROLL_CLASS, POTION_CLASS, ARMOR_CLASS,
@@ -1836,15 +1859,14 @@ assign_sym:
if (s_sym >= MAXOCLASSES) {
ap_type = M_AP_FURNITURE;
appear = s_sym == MAXOCLASSES ? S_upstair : S_dnstair;
} else if (s_sym == COIN_CLASS) {
ap_type = M_AP_OBJECT;
appear = GOLD_PIECE;
} else {
ap_type = M_AP_OBJECT;
if (s_sym == S_MIMIC_DEF) {
appear = STRANGE_OBJECT;
} else if (s_sym == COIN_CLASS) {
appear = GOLD_PIECE;
} else {
otmp = mkobj( (char) s_sym, FALSE );
otmp = mkobj((char) s_sym, FALSE);
appear = otmp->otyp;
/* make sure container contents are free'ed */
obfree(otmp, (struct obj *) 0);
@@ -1853,6 +1875,14 @@ assign_sym:
}
mtmp->m_ap_type = ap_type;
mtmp->mappearance = appear;
if (ap_type == M_AP_OBJECT &&
(appear == STATUE || appear == CORPSE ||
appear == FIGURINE || appear == EGG)) {
newmcorpsenm(mtmp);
MCORPSENM(mtmp) = rndmonnum();
if (appear == EGG && !can_be_hatched(MCORPSENM(mtmp)))
MCORPSENM(mtmp) = NON_PM; /* revert to generic egg */
}
}
/* release a monster from a bag of tricks; return number of monsters created */

View File

@@ -83,9 +83,13 @@ struct oextra *
newoextra()
{
struct oextra *oextra;
oextra = (struct oextra *)alloc(sizeof(struct oextra));
if (oextra)
(void) memset((genericptr_t)oextra, 0, sizeof(struct oextra));
oextra->oname = 0;
oextra->omonst = 0;
oextra->omid = 0;
oextra->olong = 0;
oextra->omailcmd = 0;
return oextra;
}

View File

@@ -1418,6 +1418,7 @@ struct monst *mtmp2, *mtmp1;
(genericptr_t)EDOG(mtmp1),
sizeof(struct edog));
}
if (has_mcorpsenm(mtmp1)) MCORPSENM(mtmp2) = MCORPSENM(mtmp1);
}
STATIC_OVL void
@@ -1431,6 +1432,7 @@ struct mextra *x;
if (x->eshk) free((genericptr_t)x->eshk);
if (x->emin) free((genericptr_t)x->emin);
if (x->edog) free((genericptr_t)x->edog);
/* [no action needed for x->mcorpsenm] */
free((genericptr_t)x);
}
}
@@ -2331,6 +2333,8 @@ register struct monst *mtmp;
unsigned old_app = mtmp->mappearance;
uchar old_ap_type = mtmp->m_ap_type;
if (has_mcorpsenm(mtmp)) freemcorpsenm(mtmp);
mtmp->m_ap_type = M_AP_NOTHING;
mtmp->mappearance = 0;

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)pager.c 3.5 2008/07/20 */
/* SCCS Id: @(#)pager.c 3.5 2009/01/30 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -213,15 +213,24 @@ lookat(x, y, buf, monbuf)
} /* mtmp */
} else if (glyph_is_object(glyph)) {
int glyphotyp = glyph_to_obj(glyph);
struct obj *otmp = vobj_at(x,y);
if (!otmp || otmp->otyp != glyph_to_obj(glyph)) {
if (glyph_to_obj(glyph) != STRANGE_OBJECT) {
otmp = mksobj(glyph_to_obj(glyph), FALSE, FALSE);
/* there might be a mimic here posing as an object */
mtmp = m_at(x, y);
if (mtmp && mtmp->m_ap_type == M_AP_OBJECT &&
mtmp->mappearance == glyphotyp) otmp = 0;
else mtmp = 0;
if (!otmp || otmp->otyp != glyphotyp) {
if (glyphotyp != STRANGE_OBJECT) {
otmp = mksobj(glyphotyp, FALSE, FALSE);
if (otmp->oclass == COIN_CLASS)
otmp->quan = 2L; /* to force pluralization */
else if (otmp->otyp == SLIME_MOLD)
otmp->spe = context.current_fruit; /* give it a type */
if (mtmp && has_mcorpsenm(mtmp)) /* mimic as corpse/statue */
otmp->corpsenm = MCORPSENM(mtmp);
Strcpy(buf, distant_name(otmp, xname));
dealloc_obj(otmp);
}

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)restore.c 3.5 2008/07/20 */
/* SCCS Id: @(#)restore.c 3.5 2009/01/30 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -350,56 +350,53 @@ struct monst *mtmp;
mread(fd, (genericptr_t) mtmp, sizeof(struct monst));
/* any saved pointers are mostly invalid */
/* next monster pointer is invalid */
mtmp->nmon = (struct monst *)0;
mtmp->mextra = (struct mextra *)0;
/* non-null mextra needs to be reconstructed */
if (mtmp->mextra) {
mtmp->mextra = newmextra();
/* read the length of the name and the name */
mread(fd, (genericptr_t) &buflen, sizeof(buflen));
if (buflen > 0) {
/* mname - monster's name */
mread(fd, (genericptr_t) &buflen, sizeof(buflen));
if (buflen > 0) { /* includes terminating '\0' */
new_mname(mtmp, buflen);
mread(fd, (genericptr_t) MNAME(mtmp), buflen);
}
/* egd */
mread(fd, (genericptr_t) &buflen, sizeof(buflen));
if (buflen > 0) {
}
/* egd - vault guard */
mread(fd, (genericptr_t) &buflen, sizeof (buflen));
if (buflen > 0) {
newegd(mtmp);
mread(fd, (genericptr_t) EGD(mtmp),
sizeof(struct egd));
}
/* epri */
mread(fd, (genericptr_t) &buflen, sizeof(buflen));
if (buflen > 0) {
mread(fd, (genericptr_t) EGD(mtmp), sizeof (struct egd));
}
/* epri - temple priest */
mread(fd, (genericptr_t) &buflen, sizeof (buflen));
if (buflen > 0) {
newepri(mtmp);
mread(fd, (genericptr_t) EPRI(mtmp),
sizeof(struct epri));
}
/* eshk */
mread(fd, (genericptr_t) &buflen, sizeof(buflen));
if (buflen > 0) {
mread(fd, (genericptr_t) EPRI(mtmp), sizeof (struct epri));
}
/* eshk - shopkeeper */
mread(fd, (genericptr_t) &buflen, sizeof (buflen));
if (buflen > 0) {
neweshk(mtmp);
mread(fd, (genericptr_t) ESHK(mtmp),
sizeof(struct eshk));
}
/* emin */
mread(fd, (genericptr_t) &buflen, sizeof(buflen));
if (buflen > 0) {
mread(fd, (genericptr_t) ESHK(mtmp), sizeof (struct eshk));
}
/* emin - minion */
mread(fd, (genericptr_t) &buflen, sizeof (buflen));
if (buflen > 0) {
newemin(mtmp);
mread(fd, (genericptr_t) EMIN(mtmp),
sizeof(struct emin));
}
/* edog */
mread(fd, (genericptr_t) &buflen, sizeof(buflen));
if (buflen > 0) {
mread(fd, (genericptr_t) EMIN(mtmp), sizeof (struct emin));
}
/* edog - pet */
mread(fd, (genericptr_t) &buflen, sizeof (buflen));
if (buflen > 0) {
newedog(mtmp);
mread(fd, (genericptr_t) EDOG(mtmp),
sizeof(struct edog));
}
mread(fd, (genericptr_t) EDOG(mtmp), sizeof (struct edog));
}
/* mcorpsenm - obj->corpsenm for mimic posing as corpse or
statue (inline int rather than pointer to something) */
mread(fd, (genericptr_t) &MCORPSENM(mtmp),
sizeof MCORPSENM(mtmp));
} /* mextra */
}
STATIC_OVL struct monst *

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)save.c 3.5 2008/07/20 */
/* SCCS Id: @(#)save.c 3.5 2009/01/30 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1046,14 +1046,7 @@ struct monst *mtmp;
buflen = sizeof(struct monst);
bwrite(fd, (genericptr_t) &buflen, sizeof(int));
bwrite(fd, (genericptr_t) mtmp, buflen);
if (!mtmp->mextra) {
bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
} else {
if (mtmp->mextra) {
if (MNAME(mtmp)) buflen = strlen(MNAME(mtmp)) + 1;
else buflen = 0;
bwrite(fd, (genericptr_t) &buflen, sizeof buflen);
@@ -1089,6 +1082,11 @@ struct monst *mtmp;
bwrite(fd, (genericptr_t) &buflen, sizeof(int));
if (buflen > 0)
bwrite(fd, (genericptr_t) EDOG(mtmp), buflen);
/* mcorpsenm is inline int rather than pointer to something,
so doesn't need to be preceded by a length field */
bwrite(fd, (genericptr_t) &MCORPSENM(mtmp),
sizeof MCORPSENM(mtmp));
}
}