'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.
This commit is contained in:
nhmall
2025-02-04 15:16:42 -05:00
parent b44a547153
commit c24786430f
13 changed files with 108 additions and 71 deletions
+2 -2
View File
@@ -248,6 +248,8 @@ extern void savebones(int, time_t, struct obj *);
extern int getbones(void); extern int getbones(void);
extern boolean bones_include_name(const char *) NONNULLARG1; extern boolean bones_include_name(const char *) NONNULLARG1;
extern void fix_ghostly_obj(struct obj *) NONNULLARG1; extern void fix_ghostly_obj(struct obj *) NONNULLARG1;
extern void newebones(struct monst *) NONNULLARG1;
extern void free_ebones(struct monst *) NONNULLARG1;
/* ### botl.c ### */ /* ### botl.c ### */
@@ -1443,8 +1445,6 @@ extern void mkmonmoney(struct monst *, long) NONNULLARG1;
extern int bagotricks(struct obj *, boolean, int *); extern int bagotricks(struct obj *, boolean, int *);
extern boolean propagate(int, boolean, boolean); extern boolean propagate(int, boolean, boolean);
extern void summon_furies(int); extern void summon_furies(int);
extern void newformer(struct monst *) NONNULLARG1;
extern void free_former(struct monst *) NONNULLARG1;
/* ### mcastu.c ### */ /* ### mcastu.c ### */
+1
View File
@@ -767,6 +767,7 @@ struct role_filter {
boolean roles[NUM_ROLES + 1]; boolean roles[NUM_ROLES + 1];
short mask; short mask;
}; };
#define NUM_RACES (5)
enum saveformats { enum saveformats {
invalid = 0, invalid = 0,
+17 -13
View File
@@ -182,16 +182,20 @@ struct edog {
Bitfield(killed_by_u, 1); /* you attempted to kill him */ Bitfield(killed_by_u, 1); /* you attempted to kill him */
}; };
/* for saving the hero's rank in bones monster */ /***
struct mon_former_rank { ** extension tracking a player's remnant monster (ghost, mummy etc.)
int lev; */
short mnum; struct ebones {
boolean female; unsigned parentmid; /* make clobber-detection possible */
}; uchar role; /* index into roles[] */
uchar race; /* index into races[] */
struct former_incarnation { align oldalign; /* character alignment */
unsigned parentmid; /* make clobber-detection possible */ uchar deathlevel; /* level when dying (m_lev may differ) */
struct mon_former_rank rank; /* for bones' ghost rank in former life */ 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 eshk *eshk;
struct emin *emin; struct emin *emin;
struct edog *edog; struct edog *edog;
struct former_incarnation *former; struct ebones *ebones;
int mcorpsenm; /* obj->corpsenm for mimic posing as statue or corpse, int mcorpsenm; /* obj->corpsenm for mimic posing as statue or corpse,
* obj->spe (fruit index) for one posing as a slime mold, * obj->spe (fruit index) for one posing as a slime mold,
* or an alignment mask for one posing as an altar */ * or an alignment mask for one posing as an altar */
@@ -216,7 +220,7 @@ struct mextra {
#define ESHK(mon) ((mon)->mextra->eshk) #define ESHK(mon) ((mon)->mextra->eshk)
#define EMIN(mon) ((mon)->mextra->emin) #define EMIN(mon) ((mon)->mextra->emin)
#define EDOG(mon) ((mon)->mextra->edog) #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 MCORPSENM(mon) ((mon)->mextra->mcorpsenm)
#define has_mgivenname(mon) ((mon)->mextra && MGIVENNAME(mon)) #define has_mgivenname(mon) ((mon)->mextra && MGIVENNAME(mon))
@@ -225,7 +229,7 @@ struct mextra {
#define has_eshk(mon) ((mon)->mextra && ESHK(mon)) #define has_eshk(mon) ((mon)->mextra && ESHK(mon))
#define has_emin(mon) ((mon)->mextra && EMIN(mon)) #define has_emin(mon) ((mon)->mextra && EMIN(mon))
#define has_edog(mon) ((mon)->mextra && EDOG(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) #define has_mcorpsenm(mon) ((mon)->mextra && MCORPSENM(mon) != NON_PM)
#endif /* MEXTRA_H */ #endif /* MEXTRA_H */
+1 -1
View File
@@ -17,7 +17,7 @@
* Incrementing EDITLEVEL can be used to force invalidation of old bones * Incrementing EDITLEVEL can be used to force invalidation of old bones
* and save files. * and save files.
*/ */
#define EDITLEVEL 118 #define EDITLEVEL 119
/* /*
* Development status possibilities. * Development status possibilities.
+53 -6
View File
@@ -502,16 +502,39 @@ savebones(int how, time_t when, struct obj *corpse)
(void) obj_attach_mid(corpse, mtmp->m_id); (void) obj_attach_mid(corpse, mtmp->m_id);
} }
if (mtmp) { if (mtmp) {
int i;
mtmp->m_lev = (u.ulevel ? u.ulevel : 1); mtmp->m_lev = (u.ulevel ? u.ulevel : 1);
mtmp->mhp = mtmp->mhpmax = u.uhpmax; mtmp->mhp = mtmp->mhpmax = u.uhpmax;
mtmp->female = flags.female; mtmp->female = flags.female;
mtmp->msleeping = 1; mtmp->msleeping = 1;
if (!has_former(mtmp))
newformer(mtmp); if (!has_ebones(mtmp))
if (has_former(mtmp)) { newebones(mtmp);
FORMER(mtmp)->rank.lev = mtmp->m_lev; if (has_ebones(mtmp)) {
FORMER(mtmp)->rank.mnum = Role_switch; for (i = 0; i <= NUM_ROLES; ++i) {
FORMER(mtmp)->rank.female = flags.female; 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) { for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
@@ -783,4 +806,28 @@ fix_ghostly_obj(struct obj *obj)
obj->ghostly = 0; 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*/ /*bones.c*/
+2 -2
View File
@@ -273,7 +273,7 @@ do_mgivenname(void)
verbalize("I'm %s, not %s.", shkname(mtmp), buf); verbalize("I'm %s, not %s.", shkname(mtmp), buf);
} }
} else if (mtmp->ispriest || mtmp->isminion || mtmp->isshk } 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)) if (!alreadynamed(mtmp, monnambuf, buf))
pline("%s will not accept the name %s.", upstart(monnambuf), buf); pline("%s will not accept the name %s.", upstart(monnambuf), buf);
} else { } else {
@@ -956,7 +956,7 @@ x_monnam(
#if 0 #if 0
/* hardfought */ /* hardfought */
if (has_former(mtmp) && FORMER(mtmp)->rank.mnum != NON_PM) { if (has_ebones(mtmp)) {
#endif #endif
if (mdat == &mons[PM_GHOST]) { if (mdat == &mons[PM_GHOST]) {
Sprintf(eos(buf), "%s ghost", s_suffix(name)); Sprintf(eos(buf), "%s ghost", s_suffix(name));
+7 -4
View File
@@ -206,7 +206,7 @@ done_in_by(struct monst *mtmp, int how)
/* _the_ <invisible> <distorted> ghost of Dudley */ /* _the_ <invisible> <distorted> ghost of Dudley */
#if 0 #if 0
/* hardfought */ /* hardfought */
if (has_former(mtmp) && FORMER(mtmp)->rank.mnum != NON_PM) { if (has_ebones(mtmp) && EBONES(mtmp)->rank.mnum != NON_PM) {
#else #else
if (mptr == &mons[PM_GHOST] && has_mgivenname(mtmp)) { if (mptr == &mons[PM_GHOST] && has_mgivenname(mtmp)) {
#endif #endif
@@ -253,7 +253,7 @@ done_in_by(struct monst *mtmp, int how)
realnm, shape); realnm, shape);
mptr = mtmp->data; /* reset for mimicker case */ mptr = mtmp->data; /* reset for mimicker case */
#if 0 /* hardfought */ #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)); Strcpy(buf, m_monnam(mtmp));
#endif #endif
} else if (mptr == &mons[PM_GHOST]) { } else if (mptr == &mons[PM_GHOST]) {
@@ -273,8 +273,11 @@ done_in_by(struct monst *mtmp, int how)
Strcat(buf, m_monnam(mtmp)); Strcat(buf, m_monnam(mtmp));
} else { } else {
Strcat(buf, pmname(mptr, Mgender(mtmp))); Strcat(buf, pmname(mptr, Mgender(mtmp)));
if (has_mgivenname(mtmp)) if (has_mgivenname(mtmp)) {
Sprintf(eos(buf), " called %s", MGIVENNAME(mtmp)); Sprintf(eos(buf), " %s %s",
has_ebones(mtmp) ? "of" : "called",
MGIVENNAME(mtmp));
}
} }
Strcpy(svk.killer.name, buf); Strcpy(svk.killer.name, buf);
-23
View File
@@ -1070,29 +1070,6 @@ newmextra(void)
return mextra; 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 staticfn boolean
makemon_rnd_goodpos( makemon_rnd_goodpos(
struct monst *mon, struct monst *mon,
+11 -11
View File
@@ -2567,11 +2567,11 @@ copy_mextra(struct monst *mtmp2, struct monst *mtmp1)
assert(has_edog(mtmp2)); assert(has_edog(mtmp2));
*EDOG(mtmp2) = *EDOG(mtmp1); *EDOG(mtmp2) = *EDOG(mtmp1);
} }
if (FORMER(mtmp1)) { if (EBONES(mtmp1)) {
if (!FORMER(mtmp2)) if (!EBONES(mtmp2))
newformer(mtmp2); newebones(mtmp2);
assert(has_former(mtmp2)); assert(has_ebones(mtmp2));
*FORMER(mtmp2) = *FORMER(mtmp1); *EBONES(mtmp2) = *EBONES(mtmp1);
} }
if (has_mcorpsenm(mtmp1)) if (has_mcorpsenm(mtmp1))
MCORPSENM(mtmp2) = MCORPSENM(mtmp1); MCORPSENM(mtmp2) = MCORPSENM(mtmp1);
@@ -2595,8 +2595,8 @@ dealloc_mextra(struct monst *m)
free((genericptr_t) x->emin), x->emin = 0; free((genericptr_t) x->emin), x->emin = 0;
if (x->edog) if (x->edog)
free((genericptr_t) x->edog), x->edog = 0; free((genericptr_t) x->edog), x->edog = 0;
if (x->former) if (x->ebones)
free((genericptr_t) x->former), x->former = 0; free((genericptr_t) x->ebones), x->ebones = 0;
x->mcorpsenm = NON_PM; /* no allocation to release */ x->mcorpsenm = NON_PM; /* no allocation to release */
free((genericptr_t) x); free((genericptr_t) x);
@@ -3644,13 +3644,13 @@ xkilled(
#if 0 /* HARDFOUGHT-only at present */ #if 0 /* HARDFOUGHT-only at present */
#ifdef LIVELOG #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_printf(LL_UMONST, "destroyed %s, %s former %s",
livelog_mon_nam(mtmp), livelog_mon_nam(mtmp),
(mtmp->data == &mons[PM_GHOST]) ? "the" : "and", (mtmp->data == &mons[PM_GHOST]) ? "the" : "and",
rank_of(FORMER(mtmp)->rank.lev, rank_of(EBONES(mtmp)->deathlevel,
FORMER(mtmp)->rank.mnum, EBONES(mtmp)->mnum,
FORMER(mtmp)->rank.female)); EBONES(mtmp)->female));
} }
#endif /* LIVELOG */ #endif /* LIVELOG */
#endif #endif
+4 -4
View File
@@ -370,14 +370,14 @@ restmon(NHFILE *nhfp, struct monst *mtmp)
EDOG(mtmp)->apport = 1; EDOG(mtmp)->apport = 1;
} }
} }
/* former - info about former self, primarily for bones files */ /* ebones */
if (nhfp->structlevel) if (nhfp->structlevel)
Mread(nhfp->fd, &buflen, sizeof buflen); Mread(nhfp->fd, &buflen, sizeof buflen);
if (buflen > 0) { if (buflen > 0) {
newformer(mtmp); newebones(mtmp);
if (nhfp->structlevel) if (nhfp->structlevel)
Mread(nhfp->fd, FORMER(mtmp), Mread(nhfp->fd, EBONES(mtmp),
sizeof (struct former_incarnation)); sizeof (struct ebones));
} }
/* mcorpsenm - obj->corpsenm for mimic posing as corpse or /* mcorpsenm - obj->corpsenm for mimic posing as corpse or
statue (inline int rather than pointer to something) */ statue (inline int rather than pointer to something) */
+6 -1
View File
@@ -24,6 +24,9 @@
* *
* God names use a leading underscore to flag goddesses. * God names use a leading underscore to flag goddesses.
*/ */
/* NUM_ROLES is defined in hack.h */
const struct Role roles[NUM_ROLES+1] = { const struct Role roles[NUM_ROLES+1] = {
{ { "Archeologist", 0 }, { { "Archeologist", 0 },
{ { "Digger", 0 }, { { "Digger", 0 },
@@ -573,7 +576,9 @@ const struct Role roles[NUM_ROLES+1] = {
}; };
/* Table of all races */ /* Table of all races */
const struct Race races[] = {
/* NUM_RACES is defined in hack.h */
const struct Race races[NUM_RACES + 1] = {
{ {
"human", "human",
"human", "human",
+2 -2
View File
@@ -943,12 +943,12 @@ savemon(NHFILE *nhfp, struct monst *mtmp)
if (nhfp->structlevel) if (nhfp->structlevel)
bwrite(nhfp->fd, (genericptr_t) EDOG(mtmp), buflen); 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) if (nhfp->structlevel)
bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof (int)); bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof (int));
if (buflen > 0) { if (buflen > 0) {
if (nhfp->structlevel) 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, /* mcorpsenm is inline int rather than pointer to something,
so doesn't need to be preceded by a length field */ so doesn't need to be preceded by a length field */
+2 -2
View File
@@ -1246,8 +1246,8 @@ size_monst(struct monst *mtmp, boolean incl_wsegs)
sz += (int) sizeof (struct emin); sz += (int) sizeof (struct emin);
if (EDOG(mtmp)) if (EDOG(mtmp))
sz += (int) sizeof (struct edog); sz += (int) sizeof (struct edog);
if (FORMER(mtmp)) if (EBONES(mtmp))
sz += (int) sizeof (struct former_incarnation); sz += (int) sizeof (struct ebones);
/* mextra->mcorpsenm doesn't point to more memory */ /* mextra->mcorpsenm doesn't point to more memory */
} }
return sz; return sz;