diff --git a/include/context.h b/include/context.h index 10da8bd8d..c9a36fb19 100644 --- a/include/context.h +++ b/include/context.h @@ -135,8 +135,8 @@ struct context_info { int warnlevel; /* threshold (digit) to warn about unseen mons */ long next_attrib_check; /* next attribute check */ long seer_turn; /* when random clairvoyance will next kick in */ - long stethoscope_move; /* when a stethoscope was last used */ - short stethoscope_movement; /* to track multiple moves on same turn */ + long stethoscope_seq; /* when a stethoscope was last used; first use + * during a move takes no time, second uses move */ boolean travel; /* find way automatically to u.tx,u.ty */ boolean travel1; /* first travel step */ boolean forcefight; diff --git a/include/decl.h b/include/decl.h index 8a810488f..392c64fef 100644 --- a/include/decl.h +++ b/include/decl.h @@ -822,6 +822,8 @@ struct instance_globals { struct mkroom *subrooms; dlevel_t level; /* level map */ long moves; /* turn counter */ + long hero_seq; /* 'moves*8 + n' where n is updated each hero move during + * the current turn */ long wailmsg; struct obj *migrating_objs; /* objects moving to another dungeon level */ struct obj *billobjs; /* objects not yet paid for */ diff --git a/include/mextra.h b/include/mextra.h index 41b519eeb..ed209e346 100644 --- a/include/mextra.h +++ b/include/mextra.h @@ -132,7 +132,9 @@ struct eshk { d_level shoplevel; /* level (& dungeon) of his shop */ int billct; /* no. of entries of bill[] in use */ 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 */ char customer[PL_NSIZ]; /* most recent customer */ char shknam[PL_NSIZ]; diff --git a/include/patchlevel.h b/include/patchlevel.h index 77ffff403..d5b5f0ab1 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 46 +#define EDITLEVEL 47 /* * Development status possibilities. diff --git a/src/allmain.c b/src/allmain.c index 0ef1108ef..1e0053a12 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -212,9 +212,12 @@ moveloop_core(void) */ if (g.moves >= 1000000000L) { display_nhwindow(WIN_MESSAGE, TRUE); - pline_The("dungeon capitulates."); + urgent_pline("The dungeon capitulates."); 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) iflags.time_botl = TRUE; /* 'moves' just changed */ @@ -351,6 +354,7 @@ moveloop_core(void) /* once-per-hero-took-time things go here */ /******************************************/ + g.hero_seq++; /* moves*8 + n for n == 1..7 */ #ifdef STATUS_HILITES if (iflags.hilite_delta) status_eval_next_unhilite(); @@ -648,7 +652,6 @@ newgame(void) g.context.botlx = TRUE; g.context.ident = 1; - g.context.stethoscope_move = -1L; g.context.warnlevel = 1; g.context.next_attrib_check = 600L; /* arbitrary first setting */ g.context.tribute.enabled = TRUE; /* turn on 3.6 tributes */ diff --git a/src/apply.c b/src/apply.c index e4b6b20af..f315e3921 100644 --- a/src/apply.c +++ b/src/apply.c @@ -319,10 +319,8 @@ use_stethoscope(struct obj *obj) if (!getdir((char *) 0)) return 0; - res = (g.moves == g.context.stethoscope_move) - && (g.youmonst.movement == g.context.stethoscope_movement); - g.context.stethoscope_move = g.moves; - g.context.stethoscope_movement = g.youmonst.movement; + res = (g.hero_seq == g.context.stethoscope_seq); + g.context.stethoscope_seq = g.hero_seq; g.bhitpos.x = u.ux, g.bhitpos.y = u.uy; /* tentative, reset below */ g.notonhead = u.uswallow; diff --git a/src/decl.c b/src/decl.c index 36c60defa..ebf96c2cd 100644 --- a/src/decl.c +++ b/src/decl.c @@ -305,8 +305,11 @@ const struct instance_globals g_init = { DUMMY, /* rooms */ NULL, /* subrooms */ UNDEFINED_VALUES, /* level */ - 1, /* moves */ - 0, /* wailmsg */ + 1L, /* moves; misnamed turn counter */ + 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, /* billobjs */ #if defined(MICRO) || defined(WIN32) @@ -709,13 +712,13 @@ decl_globals_init(void) g.valuables[2].size = 0; if (g_init.magic != IVMAGIC) { - printf("decl_globals_init: g_init.magic in unexpected state (%lx)\n", - g_init.magic); + raw_printf( + "decl_globals_init: g_init.magic in unexpected state (%lx).", + g_init.magic); exit(1); } - 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); } @@ -739,8 +742,6 @@ decl_globals_init(void) g.urole = urole_init_data; g.urace = urace_init_data; - - } /*decl.c*/ diff --git a/src/dothrow.c b/src/dothrow.c index 21af79406..67bdd042a 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -2111,10 +2111,11 @@ release_camera_demon(struct obj *obj, xchar x, xchar y) * and break messages have been delivered prior to getting here. */ void -breakobj(struct obj *obj, - xchar x, xchar y, /* object location (ox, oy may not be right) */ - boolean hero_caused, /* is this the hero's fault? */ - boolean from_invent) +breakobj( + struct obj *obj, + xchar x, xchar y, /* object location (ox, oy may not be right) */ + boolean hero_caused, /* is this the hero's fault? */ + boolean from_invent) { boolean fracture = FALSE; @@ -2175,19 +2176,20 @@ breakobj(struct obj *obj, struct monst *shkp = shop_keeper(*o_shop); if (shkp) { /* (implies *o_shop != '\0') */ - static NEARDATA long lastmovetime = 0L; - static NEARDATA boolean peaceful_shk = FALSE; - /* We want to base shk actions on her peacefulness - at start of this turn, so that "simultaneous" - multiple breakage isn't drastically worse than - single breakage. (ought to be done via ESHK) */ - if (g.moves != lastmovetime) - peaceful_shk = shkp->mpeaceful; - if (stolen_value(obj, x, y, peaceful_shk, FALSE) > 0L + struct eshk *eshkp = ESHK(shkp); + + /* base shk actions on her peacefulness at start of + this turn, so that "simultaneous" multiple breakage + isn't drastically worse than single breakage */ + if (g.hero_seq != eshkp->break_seq) + eshkp->seq_peaceful = shkp->mpeaceful; + if ((stolen_value(obj, x, y, eshkp->seq_peaceful, FALSE) > 0L) && (*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); - 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; } } }