add two unused fields for hardfought save compatability

There are two hardfought code additions that render save and bones files incompatible
with the upstream NetHack-3.7, and that makes testing with hardfought
save and bones files more challenging than it needs to be, when
investigating and troubleshooting bug reports.

Add some unused fields to advance towards achieving save file parity with
hardfought, which is a significant source of play-testing for NetHack-3.7.

1) the elbereth field addition to u_conduct

This adds an unused placeholder field named 'hf_reserved1', at the appropriate
place in u_conduct to achieve struct field parity with the one in use on
hardfought.

2) hardfought adds a field to struct monst:
    char former_rank[25]; /* for bones' ghost rank in their former life */

Instead of adding that to every monst, this adds a new mextra struct
named 'former', which currently contains the equivalent 25-character
field called 'rank' which can hold the content that was in the
former_rank[25] field. That way, the field will only be added when it
is needed.

A pull request https://github.com/k21971/NetHack37/pull/2 has been
done on hardfought to do it the same way (untested there as of yet).

Even though NetHack-3.7 does not utilize that information presently,
this will be a further step toward allowing hardfought-generated save
and bones files to be used for troubleshooting, without modification,
on a similar architecture running stock NetHack-3.7 code.

That savefile parity won't be achieved until the after the
hardfought pull-request mentioned above (or equivalent) is merged.

As this change will not be compatible with existing save and bones
files, it will be accompanied with an EDITLEVEL increment.
This commit is contained in:
nhmall
2025-02-02 09:00:05 -05:00
parent d74624abbd
commit d785f7a649
11 changed files with 91 additions and 4 deletions

View File

@@ -257,6 +257,7 @@ extern char *do_statusline2(void);
extern void bot(void);
extern void timebot(void);
extern int xlev_to_rank(int);
extern const char *rank(void);
extern int rank_to_xlev(int);
extern const char *rank_of(int, short, boolean);
extern int title_to_mon(const char *, int *, int *);
@@ -1442,6 +1443,8 @@ 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 ### */

View File

@@ -182,6 +182,10 @@ struct edog {
Bitfield(killed_by_u, 1); /* you attempted to kill him */
};
struct former_incarnation {
char rank[25]; /* for bones' ghost rank in their former life */
};
/***
** mextra.h -- collection of all monster extensions
*/
@@ -192,6 +196,7 @@ struct mextra {
struct eshk *eshk;
struct emin *emin;
struct edog *edog;
struct former_incarnation *former;
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 */
@@ -203,6 +208,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 MCORPSENM(mon) ((mon)->mextra->mcorpsenm)
#define has_mgivenname(mon) ((mon)->mextra && MGIVENNAME(mon))
@@ -211,6 +217,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_mcorpsenm(mon) ((mon)->mextra && MCORPSENM(mon) != NON_PM)
#endif /* MEXTRA_H */

View File

@@ -260,6 +260,14 @@
|| objects[(obj)->otyp].oc_material == VEGGY \
|| ((obj)->otyp == CORPSE && (obj)->corpsenm == PM_LICHEN))))
/* is_bones_monster() is currently only used by hardfought livelog,
* but is included as part of savefile field compatibility adjustments.
*/
#define is_bones_monster(ptr) \
((ptr) == &mons[PM_GHOST] || (ptr) == &mons[PM_GHOUL] \
|| (ptr) == &mons[PM_VAMPIRE] || (ptr) == &mons[PM_WRAITH] \
|| (ptr) == &mons[PM_GREEN_SLIME] || (ptr)->mlet == S_MUMMY)
#ifdef PMNAME_MACROS
#define pmname(ptr,g) ((((g) == MALE || (g) == FEMALE) && (ptr)->pmnames[g]) \
? (ptr)->pmnames[g] : (ptr)->pmnames[NEUTRAL])

View File

@@ -153,6 +153,7 @@ struct u_conduct { /* number of times... */
long polyselfs; /* transformed yourself */
long wishes; /* used a wish */
long wisharti; /* wished for an artifact */
long hf_reserved1; /* hf uses for elbereth;for hf savefile compatiblity */
long sokocheat; /* violated special 'rules' in Sokoban */
long pets; /* obtained a pet */
/* genocides already listed at end of game */