From c24786430f6dd6fc1341431dafbaa17df00c46d9 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 4 Feb 2025 15:16:42 -0500 Subject: [PATCH] 'struct former' -> 'struct ebones' Some variants were already using a similar approach using a struct called 'ebones', so adopt the same naming so NetHack-3.7, hardfought, and some variants are using the same name. As before there are fields in the struct that are not currently used by NetHack-3.7, but the intent is that hardfought save and bones files can be loaded by NetHack-3.7 without code modification, for debugging bug reports. This invalidates existing save and bones files. --- include/extern.h | 4 +-- include/hack.h | 1 + include/mextra.h | 30 ++++++++++++---------- include/patchlevel.h | 2 +- src/bones.c | 59 +++++++++++++++++++++++++++++++++++++++----- src/do_name.c | 4 +-- src/end.c | 11 ++++++--- src/makemon.c | 23 ----------------- src/mon.c | 22 ++++++++--------- src/restore.c | 8 +++--- src/role.c | 7 +++++- src/save.c | 4 +-- src/wizcmds.c | 4 +-- 13 files changed, 108 insertions(+), 71 deletions(-) diff --git a/include/extern.h b/include/extern.h index e9988c798..7ab07ada2 100644 --- a/include/extern.h +++ b/include/extern.h @@ -248,6 +248,8 @@ extern void savebones(int, time_t, struct obj *); extern int getbones(void); extern boolean bones_include_name(const char *) NONNULLARG1; extern void fix_ghostly_obj(struct obj *) NONNULLARG1; +extern void newebones(struct monst *) NONNULLARG1; +extern void free_ebones(struct monst *) NONNULLARG1; /* ### botl.c ### */ @@ -1443,8 +1445,6 @@ extern void mkmonmoney(struct monst *, long) NONNULLARG1; extern int bagotricks(struct obj *, boolean, int *); extern boolean propagate(int, boolean, boolean); extern void summon_furies(int); -extern void newformer(struct monst *) NONNULLARG1; -extern void free_former(struct monst *) NONNULLARG1; /* ### mcastu.c ### */ diff --git a/include/hack.h b/include/hack.h index 643075129..3fb02f687 100644 --- a/include/hack.h +++ b/include/hack.h @@ -767,6 +767,7 @@ struct role_filter { boolean roles[NUM_ROLES + 1]; short mask; }; +#define NUM_RACES (5) enum saveformats { invalid = 0, diff --git a/include/mextra.h b/include/mextra.h index a665b953b..6cafb4890 100644 --- a/include/mextra.h +++ b/include/mextra.h @@ -182,16 +182,20 @@ struct edog { Bitfield(killed_by_u, 1); /* you attempted to kill him */ }; -/* for saving the hero's rank in bones monster */ -struct mon_former_rank { - int lev; - short mnum; - boolean female; -}; - -struct former_incarnation { - unsigned parentmid; /* make clobber-detection possible */ - struct mon_former_rank rank; /* for bones' ghost rank in former life */ +/*** + ** extension tracking a player's remnant monster (ghost, mummy etc.) + */ +struct ebones { + unsigned parentmid; /* make clobber-detection possible */ + uchar role; /* index into roles[] */ + uchar race; /* index into races[] */ + align oldalign; /* character alignment */ + uchar deathlevel; /* level when dying (m_lev may differ) */ + schar luck; /* luck when dying */ + short mnum; /* monster type */ + Bitfield(female, 1); /* was female */ + Bitfield(demigod, 1); /* had killed wiz or invoked */ + Bitfield(crowned, 1); /* had been crowned */ }; /*** @@ -204,7 +208,7 @@ struct mextra { struct eshk *eshk; struct emin *emin; struct edog *edog; - struct former_incarnation *former; + struct ebones *ebones; int mcorpsenm; /* obj->corpsenm for mimic posing as statue or corpse, * obj->spe (fruit index) for one posing as a slime mold, * or an alignment mask for one posing as an altar */ @@ -216,7 +220,7 @@ struct mextra { #define ESHK(mon) ((mon)->mextra->eshk) #define EMIN(mon) ((mon)->mextra->emin) #define EDOG(mon) ((mon)->mextra->edog) -#define FORMER(mon) ((mon)->mextra->former) +#define EBONES(mon) ((mon)->mextra->ebones) #define MCORPSENM(mon) ((mon)->mextra->mcorpsenm) #define has_mgivenname(mon) ((mon)->mextra && MGIVENNAME(mon)) @@ -225,7 +229,7 @@ struct mextra { #define has_eshk(mon) ((mon)->mextra && ESHK(mon)) #define has_emin(mon) ((mon)->mextra && EMIN(mon)) #define has_edog(mon) ((mon)->mextra && EDOG(mon)) -#define has_former(mon) ((mon)->mextra && FORMER(mon)) +#define has_ebones(mon) ((mon)->mextra && EBONES(mon)) #define has_mcorpsenm(mon) ((mon)->mextra && MCORPSENM(mon) != NON_PM) #endif /* MEXTRA_H */ diff --git a/include/patchlevel.h b/include/patchlevel.h index 1c688630e..0cc49ff95 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -17,7 +17,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 118 +#define EDITLEVEL 119 /* * Development status possibilities. diff --git a/src/bones.c b/src/bones.c index 7b43db3e2..8675d0f9c 100644 --- a/src/bones.c +++ b/src/bones.c @@ -502,16 +502,39 @@ savebones(int how, time_t when, struct obj *corpse) (void) obj_attach_mid(corpse, mtmp->m_id); } if (mtmp) { + int i; + mtmp->m_lev = (u.ulevel ? u.ulevel : 1); mtmp->mhp = mtmp->mhpmax = u.uhpmax; mtmp->female = flags.female; mtmp->msleeping = 1; - if (!has_former(mtmp)) - newformer(mtmp); - if (has_former(mtmp)) { - FORMER(mtmp)->rank.lev = mtmp->m_lev; - FORMER(mtmp)->rank.mnum = Role_switch; - FORMER(mtmp)->rank.female = flags.female; + + if (!has_ebones(mtmp)) + newebones(mtmp); + if (has_ebones(mtmp)) { + for (i = 0; i <= NUM_ROLES; ++i) { + if (!strcmp(gu.urole.name.m, roles[i].name.m)) { + EBONES(mtmp)->role = i; + break; + } + /* impossible("savebones: bad gu.urole.name.m \"%s\"", + gu.urole.name.m); */ + } + for (i = 0; i <= NUM_RACES; ++i) { + if (!strcmp(gu.urace.noun, races[i].noun)) { + EBONES(mtmp)->race = i; + break; + } + /* impossible("savebones: bad gu.urace.noun \"%s\"", + gu.urace.noun); */ + } + EBONES(mtmp)->oldalign = u.ualign; + EBONES(mtmp)->deathlevel = u.ulevel; + EBONES(mtmp)->luck = u.uluck; /* moreluck not included */ + EBONES(mtmp)->mnum = Role_switch; + EBONES(mtmp)->female = flags.female; + EBONES(mtmp)->demigod = u.uevent.udemigod; + EBONES(mtmp)->crowned = u.uevent.uhand_of_elbereth; } } for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { @@ -783,4 +806,28 @@ fix_ghostly_obj(struct obj *obj) obj->ghostly = 0; } +void +newebones(struct monst *mtmp) +{ + if (!mtmp->mextra) + mtmp->mextra = newmextra(); + if (!EBONES(mtmp)) { + EBONES(mtmp) = (struct ebones *) alloc( + sizeof(struct ebones *)); + (void) memset((genericptr_t) EBONES(mtmp), 0, + sizeof(struct ebones *)); + EBONES(mtmp)->parentmid = mtmp->m_id; + } +} + +/* this is not currently used */ +void +free_ebones(struct monst *mtmp) +{ + if (mtmp->mextra && EBONES(mtmp)) { + free((genericptr_t) EBONES(mtmp)); + EBONES(mtmp) = (struct ebones *) 0; + } +} + /*bones.c*/ diff --git a/src/do_name.c b/src/do_name.c index f690a2984..37876700e 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -273,7 +273,7 @@ do_mgivenname(void) verbalize("I'm %s, not %s.", shkname(mtmp), buf); } } else if (mtmp->ispriest || mtmp->isminion || mtmp->isshk - || mtmp->data == &mons[PM_GHOST]) { + || mtmp->data == &mons[PM_GHOST] || has_ebones(mtmp)) { if (!alreadynamed(mtmp, monnambuf, buf)) pline("%s will not accept the name %s.", upstart(monnambuf), buf); } else { @@ -956,7 +956,7 @@ x_monnam( #if 0 /* hardfought */ - if (has_former(mtmp) && FORMER(mtmp)->rank.mnum != NON_PM) { + if (has_ebones(mtmp)) { #endif if (mdat == &mons[PM_GHOST]) { Sprintf(eos(buf), "%s ghost", s_suffix(name)); diff --git a/src/end.c b/src/end.c index 4c916024a..8909b4a8a 100644 --- a/src/end.c +++ b/src/end.c @@ -206,7 +206,7 @@ done_in_by(struct monst *mtmp, int how) /* _the_ ghost of Dudley */ #if 0 /* hardfought */ - if (has_former(mtmp) && FORMER(mtmp)->rank.mnum != NON_PM) { + if (has_ebones(mtmp) && EBONES(mtmp)->rank.mnum != NON_PM) { #else if (mptr == &mons[PM_GHOST] && has_mgivenname(mtmp)) { #endif @@ -253,7 +253,7 @@ done_in_by(struct monst *mtmp, int how) realnm, shape); mptr = mtmp->data; /* reset for mimicker case */ #if 0 /* hardfought */ - } else if (has_former(mtmp) && FORMER(mtmp)->rank.mnum != NON_PM) + } else if (has_ebones(mtmp) && EBONES(mtmp)->rank.mnum != NON_PM) Strcpy(buf, m_monnam(mtmp)); #endif } else if (mptr == &mons[PM_GHOST]) { @@ -273,8 +273,11 @@ done_in_by(struct monst *mtmp, int how) Strcat(buf, m_monnam(mtmp)); } else { Strcat(buf, pmname(mptr, Mgender(mtmp))); - if (has_mgivenname(mtmp)) - Sprintf(eos(buf), " called %s", MGIVENNAME(mtmp)); + if (has_mgivenname(mtmp)) { + Sprintf(eos(buf), " %s %s", + has_ebones(mtmp) ? "of" : "called", + MGIVENNAME(mtmp)); + } } Strcpy(svk.killer.name, buf); diff --git a/src/makemon.c b/src/makemon.c index 9e62c168b..a7e52bf47 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1070,29 +1070,6 @@ newmextra(void) return mextra; } -void -newformer(struct monst *mtmp) -{ - if (!mtmp->mextra) - mtmp->mextra = newmextra(); - if (!FORMER(mtmp)) { - FORMER(mtmp) = (struct former_incarnation *) alloc( - sizeof(struct former_incarnation *)); - (void) memset((genericptr_t) FORMER(mtmp), 0, - sizeof(struct former_incarnation *)); - FORMER(mtmp)->parentmid = mtmp->m_id; - } -} - -void -free_former(struct monst *mtmp) -{ - if (mtmp->mextra && FORMER(mtmp)) { - free((genericptr_t) FORMER(mtmp)); - FORMER(mtmp) = (struct former_incarnation *) 0; - } -} - staticfn boolean makemon_rnd_goodpos( struct monst *mon, diff --git a/src/mon.c b/src/mon.c index 9a11354f5..33f2bedfa 100644 --- a/src/mon.c +++ b/src/mon.c @@ -2567,11 +2567,11 @@ copy_mextra(struct monst *mtmp2, struct monst *mtmp1) assert(has_edog(mtmp2)); *EDOG(mtmp2) = *EDOG(mtmp1); } - if (FORMER(mtmp1)) { - if (!FORMER(mtmp2)) - newformer(mtmp2); - assert(has_former(mtmp2)); - *FORMER(mtmp2) = *FORMER(mtmp1); + if (EBONES(mtmp1)) { + if (!EBONES(mtmp2)) + newebones(mtmp2); + assert(has_ebones(mtmp2)); + *EBONES(mtmp2) = *EBONES(mtmp1); } if (has_mcorpsenm(mtmp1)) MCORPSENM(mtmp2) = MCORPSENM(mtmp1); @@ -2595,8 +2595,8 @@ dealloc_mextra(struct monst *m) free((genericptr_t) x->emin), x->emin = 0; if (x->edog) free((genericptr_t) x->edog), x->edog = 0; - if (x->former) - free((genericptr_t) x->former), x->former = 0; + if (x->ebones) + free((genericptr_t) x->ebones), x->ebones = 0; x->mcorpsenm = NON_PM; /* no allocation to release */ free((genericptr_t) x); @@ -3644,13 +3644,13 @@ xkilled( #if 0 /* HARDFOUGHT-only at present */ #ifdef LIVELOG - if (has_former(mtmp) && FORMER(mtmp)->rank.mnum != NON_PM) { + if (has_ebones(mtmp)) { livelog_printf(LL_UMONST, "destroyed %s, %s former %s", livelog_mon_nam(mtmp), (mtmp->data == &mons[PM_GHOST]) ? "the" : "and", - rank_of(FORMER(mtmp)->rank.lev, - FORMER(mtmp)->rank.mnum, - FORMER(mtmp)->rank.female)); + rank_of(EBONES(mtmp)->deathlevel, + EBONES(mtmp)->mnum, + EBONES(mtmp)->female)); } #endif /* LIVELOG */ #endif diff --git a/src/restore.c b/src/restore.c index 5ab92311e..c15cce775 100644 --- a/src/restore.c +++ b/src/restore.c @@ -370,14 +370,14 @@ restmon(NHFILE *nhfp, struct monst *mtmp) EDOG(mtmp)->apport = 1; } } - /* former - info about former self, primarily for bones files */ + /* ebones */ if (nhfp->structlevel) Mread(nhfp->fd, &buflen, sizeof buflen); if (buflen > 0) { - newformer(mtmp); + newebones(mtmp); if (nhfp->structlevel) - Mread(nhfp->fd, FORMER(mtmp), - sizeof (struct former_incarnation)); + Mread(nhfp->fd, EBONES(mtmp), + sizeof (struct ebones)); } /* mcorpsenm - obj->corpsenm for mimic posing as corpse or statue (inline int rather than pointer to something) */ diff --git a/src/role.c b/src/role.c index 6d4ce709a..e95d3f121 100644 --- a/src/role.c +++ b/src/role.c @@ -24,6 +24,9 @@ * * God names use a leading underscore to flag goddesses. */ + +/* NUM_ROLES is defined in hack.h */ + const struct Role roles[NUM_ROLES+1] = { { { "Archeologist", 0 }, { { "Digger", 0 }, @@ -573,7 +576,9 @@ const struct Role roles[NUM_ROLES+1] = { }; /* Table of all races */ -const struct Race races[] = { + +/* NUM_RACES is defined in hack.h */ +const struct Race races[NUM_RACES + 1] = { { "human", "human", diff --git a/src/save.c b/src/save.c index e383b52b8..ad5f52773 100644 --- a/src/save.c +++ b/src/save.c @@ -943,12 +943,12 @@ savemon(NHFILE *nhfp, struct monst *mtmp) if (nhfp->structlevel) bwrite(nhfp->fd, (genericptr_t) EDOG(mtmp), buflen); } - buflen = FORMER(mtmp) ? (int) sizeof (struct former_incarnation) : 0; + buflen = EBONES(mtmp) ? (int) sizeof (struct ebones) : 0; if (nhfp->structlevel) bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof (int)); if (buflen > 0) { if (nhfp->structlevel) - bwrite(nhfp->fd, (genericptr_t) FORMER(mtmp), buflen); + bwrite(nhfp->fd, (genericptr_t) EBONES(mtmp), buflen); } /* mcorpsenm is inline int rather than pointer to something, so doesn't need to be preceded by a length field */ diff --git a/src/wizcmds.c b/src/wizcmds.c index a37c469aa..6dd756880 100644 --- a/src/wizcmds.c +++ b/src/wizcmds.c @@ -1246,8 +1246,8 @@ size_monst(struct monst *mtmp, boolean incl_wsegs) sz += (int) sizeof (struct emin); if (EDOG(mtmp)) sz += (int) sizeof (struct edog); - if (FORMER(mtmp)) - sz += (int) sizeof (struct former_incarnation); + if (EBONES(mtmp)) + sz += (int) sizeof (struct ebones); /* mextra->mcorpsenm doesn't point to more memory */ } return sz;