]> granicus.if.org Git - nethack/commitdiff
hero_seq
authorPatR <rankin@nethack.org>
Sun, 26 Dec 2021 08:16:55 +0000 (00:16 -0800)
committerPatR <rankin@nethack.org>
Sun, 26 Dec 2021 08:16:55 +0000 (00:16 -0800)
'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.

include/context.h
include/decl.h
include/mextra.h
include/patchlevel.h
src/allmain.c
src/apply.c
src/decl.c
src/dothrow.c

index 10da8bd8dd542ade909ece78d712c21d31a32176..c9a36fb190a48fbb345f21dfec2c206acb51e00f 100644 (file)
@@ -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;
index 8a810488f5d02947503c7d646284a2208b28678a..392c64fef63ea6873de3cdcbbcc059035df88618 100644 (file)
@@ -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 */
index 41b519eeb9d14643b10de7ab9a0229f118182231..ed209e346004852190521b2304193d8f561c724e 100644 (file)
@@ -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];
index 77ffff40324ef41fd1584b6c27e5be56880f5270..d5b5f0ab18251ece8feaee34080e1523d01d527a 100644 (file)
@@ -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.
index 0ef1108ef18b6416d5e9a7ce804fb9ea97706cc4..1e0053a122fe58547138222c6327edecfe4bdcc5 100644 (file)
@@ -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    */
index e4b6b20afe49bbacb76b1d1785521539442580fb..f315e392164db35440c5ee1605cbcdf8d36b020c 100644 (file)
@@ -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;
index 36c60defa91258987744d434cf85e47c4462d7be..ebf96c2cddac4587c498f8accb7786e44eb923f1 100644 (file)
@@ -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*/
index 21af79406b463473278c569f17372f5a7c011975..67bdd042a994875c6eb0558455f1127a91a1cc70 100644 (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.
  */
 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;
             }
         }
     }