'moves' is actually turns and there hasn't been any straightforward
way to track actual hero moves.  Add hero_seq for that.  It isn't a
counter but is distinct each time the hero makes a move.  I wanted
it for curses ^P support but so far use it for checking stethoscope
usage and for shopkeeper behavior when items in a shop are broken by
the hero.

Increment EDITLEVEL due to change in save file contents.
This commit is contained in:
PatR
2021-12-26 00:16:55 -08:00
parent c4724fd271
commit 5fbe1de2a7
8 changed files with 41 additions and 33 deletions
+2 -2
View File
@@ -135,8 +135,8 @@ struct context_info {
int warnlevel; /* threshold (digit) to warn about unseen mons */ int warnlevel; /* threshold (digit) to warn about unseen mons */
long next_attrib_check; /* next attribute check */ long next_attrib_check; /* next attribute check */
long seer_turn; /* when random clairvoyance will next kick in */ long seer_turn; /* when random clairvoyance will next kick in */
long stethoscope_move; /* when a stethoscope was last used */ long stethoscope_seq; /* when a stethoscope was last used; first use
short stethoscope_movement; /* to track multiple moves on same turn */ * during a move takes no time, second uses move */
boolean travel; /* find way automatically to u.tx,u.ty */ boolean travel; /* find way automatically to u.tx,u.ty */
boolean travel1; /* first travel step */ boolean travel1; /* first travel step */
boolean forcefight; boolean forcefight;
+2
View File
@@ -822,6 +822,8 @@ struct instance_globals {
struct mkroom *subrooms; struct mkroom *subrooms;
dlevel_t level; /* level map */ dlevel_t level; /* level map */
long moves; /* turn counter */ long moves; /* turn counter */
long hero_seq; /* 'moves*8 + n' where n is updated each hero move during
* the current turn */
long wailmsg; long wailmsg;
struct obj *migrating_objs; /* objects moving to another dungeon level */ struct obj *migrating_objs; /* objects moving to another dungeon level */
struct obj *billobjs; /* objects not yet paid for */ struct obj *billobjs; /* objects not yet paid for */
+3 -1
View File
@@ -132,7 +132,9 @@ struct eshk {
d_level shoplevel; /* level (& dungeon) of his shop */ d_level shoplevel; /* level (& dungeon) of his shop */
int billct; /* no. of entries of bill[] in use */ int billct; /* no. of entries of bill[] in use */
struct bill_x bill[BILLSZ]; struct bill_x bill[BILLSZ];
struct bill_x *bill_p; struct bill_x *bill_p; /* &(ESHK(shkp)->bill[0]) */
long break_seq; /* hero_seq value at time of object breakage */
boolean seq_peaceful; /* shkp->mpeaceful at start of break_seq */
int visitct; /* nr of visits by most recent customer */ int visitct; /* nr of visits by most recent customer */
char customer[PL_NSIZ]; /* most recent customer */ char customer[PL_NSIZ]; /* most recent customer */
char shknam[PL_NSIZ]; char shknam[PL_NSIZ];
+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 46 #define EDITLEVEL 47
/* /*
* Development status possibilities. * Development status possibilities.
+5 -2
View File
@@ -212,9 +212,12 @@ moveloop_core(void)
*/ */
if (g.moves >= 1000000000L) { if (g.moves >= 1000000000L) {
display_nhwindow(WIN_MESSAGE, TRUE); display_nhwindow(WIN_MESSAGE, TRUE);
pline_The("dungeon capitulates."); urgent_pline("The dungeon capitulates.");
done(ESCAPED); done(ESCAPED);
} }
/* 'moves' is misnamed; it represents turns; hero_seq is
a value that is distinct every time the hero moves */
g.hero_seq = g.moves << 3;
if (flags.time && !g.context.run) if (flags.time && !g.context.run)
iflags.time_botl = TRUE; /* 'moves' just changed */ iflags.time_botl = TRUE; /* 'moves' just changed */
@@ -351,6 +354,7 @@ moveloop_core(void)
/* once-per-hero-took-time things go here */ /* once-per-hero-took-time things go here */
/******************************************/ /******************************************/
g.hero_seq++; /* moves*8 + n for n == 1..7 */
#ifdef STATUS_HILITES #ifdef STATUS_HILITES
if (iflags.hilite_delta) if (iflags.hilite_delta)
status_eval_next_unhilite(); status_eval_next_unhilite();
@@ -648,7 +652,6 @@ newgame(void)
g.context.botlx = TRUE; g.context.botlx = TRUE;
g.context.ident = 1; g.context.ident = 1;
g.context.stethoscope_move = -1L;
g.context.warnlevel = 1; g.context.warnlevel = 1;
g.context.next_attrib_check = 600L; /* arbitrary first setting */ g.context.next_attrib_check = 600L; /* arbitrary first setting */
g.context.tribute.enabled = TRUE; /* turn on 3.6 tributes */ g.context.tribute.enabled = TRUE; /* turn on 3.6 tributes */
+2 -4
View File
@@ -319,10 +319,8 @@ use_stethoscope(struct obj *obj)
if (!getdir((char *) 0)) if (!getdir((char *) 0))
return 0; return 0;
res = (g.moves == g.context.stethoscope_move) res = (g.hero_seq == g.context.stethoscope_seq);
&& (g.youmonst.movement == g.context.stethoscope_movement); g.context.stethoscope_seq = g.hero_seq;
g.context.stethoscope_move = g.moves;
g.context.stethoscope_movement = g.youmonst.movement;
g.bhitpos.x = u.ux, g.bhitpos.y = u.uy; /* tentative, reset below */ g.bhitpos.x = u.ux, g.bhitpos.y = u.uy; /* tentative, reset below */
g.notonhead = u.uswallow; g.notonhead = u.uswallow;
+9 -8
View File
@@ -305,8 +305,11 @@ const struct instance_globals g_init = {
DUMMY, /* rooms */ DUMMY, /* rooms */
NULL, /* subrooms */ NULL, /* subrooms */
UNDEFINED_VALUES, /* level */ UNDEFINED_VALUES, /* level */
1, /* moves */ 1L, /* moves; misnamed turn counter */
0, /* wailmsg */ 1L << 3, /* hero_seq: sequence number for hero movement, 'moves*8 + n'
* where n is usually 1, sometimes 2 when Fast/Very_fast, maybe
* higher if polymorphed into something that's even faster */
0L, /* wailmsg */
NULL, /* migrating_objs */ NULL, /* migrating_objs */
NULL, /* billobjs */ NULL, /* billobjs */
#if defined(MICRO) || defined(WIN32) #if defined(MICRO) || defined(WIN32)
@@ -709,13 +712,13 @@ decl_globals_init(void)
g.valuables[2].size = 0; g.valuables[2].size = 0;
if (g_init.magic != IVMAGIC) { if (g_init.magic != IVMAGIC) {
printf("decl_globals_init: g_init.magic in unexpected state (%lx)\n", raw_printf(
g_init.magic); "decl_globals_init: g_init.magic in unexpected state (%lx).",
g_init.magic);
exit(1); exit(1);
} }
if (g_init.havestate != TRUE) { if (g_init.havestate != TRUE) {
printf("decl_globals_init: g_init..havestate not TRUE\n"); raw_print("decl_globals_init: g_init.havestate not True.");
exit(1); exit(1);
} }
@@ -739,8 +742,6 @@ decl_globals_init(void)
g.urole = urole_init_data; g.urole = urole_init_data;
g.urace = urace_init_data; g.urace = urace_init_data;
} }
/*decl.c*/ /*decl.c*/
+17 -15
View File
@@ -2111,10 +2111,11 @@ release_camera_demon(struct obj *obj, xchar x, xchar y)
* and break messages have been delivered prior to getting here. * and break messages have been delivered prior to getting here.
*/ */
void void
breakobj(struct obj *obj, breakobj(
xchar x, xchar y, /* object location (ox, oy may not be right) */ struct obj *obj,
boolean hero_caused, /* is this the hero's fault? */ xchar x, xchar y, /* object location (ox, oy may not be right) */
boolean from_invent) boolean hero_caused, /* is this the hero's fault? */
boolean from_invent)
{ {
boolean fracture = FALSE; boolean fracture = FALSE;
@@ -2175,19 +2176,20 @@ breakobj(struct obj *obj,
struct monst *shkp = shop_keeper(*o_shop); struct monst *shkp = shop_keeper(*o_shop);
if (shkp) { /* (implies *o_shop != '\0') */ if (shkp) { /* (implies *o_shop != '\0') */
static NEARDATA long lastmovetime = 0L; struct eshk *eshkp = ESHK(shkp);
static NEARDATA boolean peaceful_shk = FALSE;
/* We want to base shk actions on her peacefulness /* base shk actions on her peacefulness at start of
at start of this turn, so that "simultaneous" this turn, so that "simultaneous" multiple breakage
multiple breakage isn't drastically worse than isn't drastically worse than single breakage */
single breakage. (ought to be done via ESHK) */ if (g.hero_seq != eshkp->break_seq)
if (g.moves != lastmovetime) eshkp->seq_peaceful = shkp->mpeaceful;
peaceful_shk = shkp->mpeaceful; if ((stolen_value(obj, x, y, eshkp->seq_peaceful, FALSE) > 0L)
if (stolen_value(obj, x, y, peaceful_shk, FALSE) > 0L
&& (*o_shop != u.ushops[0] || !inside_shop(u.ux, u.uy)) && (*o_shop != u.ushops[0] || !inside_shop(u.ux, u.uy))
&& g.moves != lastmovetime) && g.hero_seq != eshkp->break_seq)
make_angry_shk(shkp, x, y); make_angry_shk(shkp, x, y);
lastmovetime = g.moves; /* make_angry_shk() is only called on the first instance
of breakage during any particular hero move */
eshkp->break_seq = g.hero_seq;
} }
} }
} }