simplify achievement tracking for special objects

This turned out to be a lot more work than I anticipated, but it is
definitely simpler (other than having #wizmakemap take achievements
away if you replace the level that contains the 'prize', which wasn't
handled before).

I cheated and made Mine's End into a no-bones level because the new
flagging scheme for luckstone, bag, and amulet can't carry over from
one game to another.  It probably should have been no-bones all along.
Sokoban didn't have this issue because it's already no-bones.

Existing save files are invalidated.
This commit is contained in:
PatR
2020-01-24 13:54:23 -08:00
parent dba6c20e2d
commit 0166239a22
12 changed files with 85 additions and 71 deletions

View File

@@ -105,6 +105,11 @@ struct novel_tracking { /* for choosing random passage when reading novel */
passage from the Death Quotes section of dat/tribute */
};
struct achievement_tracking {
unsigned mines_prize_oid, soko_prize_oid; /* obj->o_id */
short mines_prize_type, soko_prize_typ1, soko_prize_typ2; /* obj->otyp */
};
struct context_info {
unsigned ident; /* social security number for each monster */
unsigned no_of_wizards; /* 0, 1 or 2 (wizard and his shadow) */
@@ -143,6 +148,7 @@ struct context_info {
struct obj_split objsplit; /* track most recently split object stack */
struct tribute_info tribute;
struct novel_tracking novel;
struct achievement_tracking achieveo;
};
#endif /* CONTEXT_H */

View File

@@ -215,7 +215,7 @@ typedef struct {
boolean fieldlevel; /* fieldlevel saves saves each field individually */
boolean addinfo; /* if set, some additional context info from core */
boolean eof; /* place to mark eof reached */
boolean bendian; /* set to true if executing on a big-endian machine */
boolean bendian; /* set to true if executing on big-endian machine */
FILE *fpdef; /* file pointer for fieldlevel default style */
FILE *fpdefmap; /* file pointer mapfile for def format */
FILE *fplog; /* file pointer logfile */
@@ -1184,15 +1184,13 @@ struct instance_globals {
char *lev_message;
lev_region *lregions;
int num_lregions;
/* positions touched by level elements explicitly defined in the des-file */
/* positions touched by level elements explicitly defined in des-file */
char SpLev_Map[COLNO][ROWNO];
struct sp_coder *coder;
xchar xstart, ystart;
char xsize, ysize;
boolean splev_init_present;
boolean icedpools;
int mines_prize_count;
int soko_prize_count; /* achievements */
struct obj *container_obj[MAX_CONTAINMENT];
int container_idx;
struct monst *invent_carrying_monster;

View File

@@ -346,19 +346,9 @@ struct obj {
&& !undiscovered_artifact(ART_EYES_OF_THE_OVERWORLD)))
#define pair_of(o) ((o)->otyp == LENSES || is_gloves(o) || is_boots(o))
/* 'PRIZE' values override obj->corpsenm so prizes mustn't be object types
which use that field for monster type (or other overloaded purpose) */
#define MINES_PRIZE 1
#define SOKO_PRIZE1 2
#define SOKO_PRIZE2 3
#define is_mines_prize(o) \
((o)->otyp == iflags.mines_prize_type \
&& (o)->record_achieve_special == MINES_PRIZE)
#define is_soko_prize(o) \
(((o)->otyp == iflags.soko_prize_type1 \
&& (o)->record_achieve_special == SOKO_PRIZE1) \
|| ((o)->otyp == iflags.soko_prize_type2 \
&& (o)->record_achieve_special == SOKO_PRIZE2))
/* achievement tracking; 3.6.x did this differently */
#define is_mines_prize(o) ((o)->o_id == g.context.achieveo.mines_prize_oid)
#define is_soko_prize(o) ((o)->o_id == g.context.achieveo.soko_prize_oid)
/* Flags for get_obj_location(). */
#define CONTAINED_TOO 0x1

View File

@@ -14,7 +14,7 @@
* Incrementing EDITLEVEL can be used to force invalidation of old bones
* and save files.
*/
#define EDITLEVEL 10
#define EDITLEVEL 11
#define COPYRIGHT_BANNER_A "NetHack, Copyright 1985-2020"
#define COPYRIGHT_BANNER_B \