]> granicus.if.org Git - nethack/commitdiff
Revert "check."
authornhmall <nhmall@nethack.org>
Sat, 24 Nov 2018 03:17:16 +0000 (22:17 -0500)
committernhmall <nhmall@nethack.org>
Sat, 24 Nov 2018 03:17:16 +0000 (22:17 -0500)
This reverts commit 7814d9097a0d5b5ceddb530121633998a9fc148a.

include/config.h
include/decl.h
include/extern.h
src/apply.c
src/artifact.c
src/botl.c
src/decl.c
src/dog.c
src/restore.c

index 82b45cad965bcbf6595e501df37213aa3ac9c9ec..e57b524fb683682a3ff76f6a8234d89c63875457 100644 (file)
@@ -556,6 +556,15 @@ typedef unsigned char uchar;
 
 #endif
 
+/* PLAYAGAIN support for allowing the game shell to stay open after the player
+ * saves or dies.  This requires that the game engine can be re-entered to
+ * start another game.
+ *
+ * This support does not include supporting playing another game when
+ * a panic has occured due to undetermined state the engine is left in after a
+ * panic */
+/* #define PLAYAGAIN */
+
 /* End of Section 4 */
 
 #ifdef TTY_TILES_ESCCODES
index 4716f158c61e4204e9bd4daafef06cb295d2990d..2cc7f965cc0d121540707f366c96f9543dc08778 100644 (file)
@@ -192,6 +192,7 @@ E NEARDATA char dogname[];
 E NEARDATA char catname[];
 E NEARDATA char horsename[];
 E char preferred_pet;
+E int petname_used;
 
 E const char *occtxt; /* defined when occupation != NULL */
 E const char *nomovemsg;
@@ -443,15 +444,10 @@ struct early_opt {
  * things initialized during the initialization of the game engine.
  * It is initialized with icontext_initial_state found in decl.c */
 
+#define PLAYAGAIN
+
 struct instance_context {
     int oldcap; /* encumberance - pickup.c */
-    int petname_used; /* user preferred pet name has been used - dog.c */
-    int jumping_is_magic; /* current jump result of magic - apply.c */
-    int polearm_range_min; /* apply.c */
-    int polearm_range_max; /* apply.c */
-    int spec_dbon_applies; /* coordinate effects from spec_dbon() with 
-                            * messages in artifact_hit() - artifact.c */
-    int mrank_sz; /* loaded by max_rank_sz - botl.c */
 };
 
 E struct instance_context icontext;
index 89910b0bba91889ff9ffa71c67dbdce7456ff5f3..d3a251b83666e332cb009b4da3c3e2c1b8d8633d 100644 (file)
@@ -251,6 +251,9 @@ E void FDECL(destroy_drawbridge, (int, int));
 /* ### decl.c ### */
 
 E void NDECL(decl_init);
+#ifdef PLAYAGAIN
+E void NDECL(decl_early_init);
+#endif
 
 /* ### detect.c ### */
 
index b4c0270df0f1d19f427c4a86e4e2a7438139e8ee..d202acc7763acfd9c6bac0ee22a3cde5cf94d9d0 100644 (file)
@@ -1600,13 +1600,15 @@ boolean showmsg;
     return TRUE;
 }
 
+static int jumping_is_magic;
+
 STATIC_OVL boolean
 get_valid_jump_position(x,y)
 int x,y;
 {
     return (isok(x, y)
             && (ACCESSIBLE(levl[x][y].typ) || Passes_walls)
-            && is_valid_jump_pos(x, y, icontext.jumping_is_magic, FALSE));
+            && is_valid_jump_pos(x, y, jumping_is_magic, FALSE));
 }
 
 void
@@ -1720,7 +1722,7 @@ int magic; /* 0=Physical, otherwise skill level */
     pline("Where do you want to jump?");
     cc.x = u.ux;
     cc.y = u.uy;
-    icontext.jumping_is_magic = magic;
+    jumping_is_magic = magic;
     getpos_sethilite(display_jump_positions, get_valid_jump_position);
     if (getpos(&cc, TRUE, "the desired position") < 0)
         return 0; /* user pressed ESC */
@@ -2912,13 +2914,16 @@ int min_range, max_range;
     return TRUE;
 }
 
+static int polearm_range_min = -1;
+static int polearm_range_max = -1;
+
 STATIC_OVL boolean
 get_valid_polearm_position(x, y)
 int x, y;
 {
     return (isok(x, y) && ACCESSIBLE(levl[x][y].typ)
-            && distu(x, y) >= icontext.polearm_range_min
-            && distu(x, y) <= icontext.polearm_range_max);
+            && distu(x, y) >= polearm_range_min
+            && distu(x, y) <= polearm_range_max);
 }
 
 void
@@ -2990,8 +2995,8 @@ struct obj *obj;
     else
         max_range = 8; /* (P_SKILL(typ) >= P_EXPERT) */
 
-    icontext.polearm_range_min = min_range;
-    icontext.polearm_range_max = max_range;
+    polearm_range_min = min_range;
+    polearm_range_max = max_range;
 
     /* Prompt for a location */
     pline(where_to_hit);
index a5d0902009ddb73b2c4f37287d69a17eb7ff2ddd..87cbf3b61dc6ae30a67629386aa5a6dee9975df0 100644 (file)
@@ -40,6 +40,9 @@ STATIC_DCL int FDECL(count_surround_traps, (int, int));
    of hit points that will fit in a 15 bit integer. */
 #define FATAL_DAMAGE_MODIFIER 200
 
+/* coordinate effects from spec_dbon() with messages in artifact_hit() */
+STATIC_OVL int spec_dbon_applies = 0;
+
 /* flags including which artifacts have already been created */
 static boolean artiexist[1 + NROFARTIFACTS + 1];
 /* and a discovery list for them (no dummy first entry here) */
@@ -844,15 +847,15 @@ int tmp;
 
     if (!weap || (weap->attk.adtyp == AD_PHYS /* check for `NO_ATTK' */
                   && weap->attk.damn == 0 && weap->attk.damd == 0))
-        icontext.spec_dbon_applies = FALSE;
+        spec_dbon_applies = FALSE;
     else if (otmp->oartifact == ART_GRIMTOOTH)
         /* Grimtooth has SPFX settings to warn against elves but we want its
            damage bonus to apply to all targets, so bypass spec_applies() */
-        icontext.spec_dbon_applies = TRUE;
+        spec_dbon_applies = TRUE;
     else
-        icontext.spec_dbon_applies = spec_applies(weap, mon);
+        spec_dbon_applies = spec_applies(weap, mon);
 
-    if (icontext.spec_dbon_applies)
+    if (spec_dbon_applies)
         return weap->attk.damd ? rnd((int) weap->attk.damd) : max(tmp, 1);
     return 0;
 }
@@ -976,14 +979,14 @@ char *hittee;              /* target's name: "you" or mon_nam(mdef) */
         scare_dieroll /= (1 << (mb->spe / 3));
     /* if target successfully resisted the artifact damage bonus,
        reduce overall likelihood of the assorted special effects */
-    if (!icontext.spec_dbon_applies)
+    if (!spec_dbon_applies)
         dieroll += 1;
 
     /* might stun even when attempting a more severe effect, but
        in that case it will only happen if the other effect fails;
        extra damage will apply regardless; 3.4.1: sometimes might
        just probe even when it hasn't been enchanted */
-    do_stun = (max(mb->spe, 0) < rn2(icontext.spec_dbon_applies ? 11 : 7));
+    do_stun = (max(mb->spe, 0) < rn2(spec_dbon_applies ? 11 : 7));
 
     /* the special effects also boost physical damage; increments are
        generally cumulative, but since the stun effect is based on a
@@ -1182,12 +1185,12 @@ int dieroll; /* needed for Magicbane and vorpal blades */
     if (attacks(AD_FIRE, otmp)) {
         if (realizes_damage)
             pline_The("fiery blade %s %s%c",
-                      !icontext.spec_dbon_applies
+                      !spec_dbon_applies
                           ? "hits"
                           : (mdef->data == &mons[PM_WATER_ELEMENTAL])
                                 ? "vaporizes part of"
                                 : "burns",
-                      hittee, !icontext.spec_dbon_applies ? '.' : '!');
+                      hittee, !spec_dbon_applies ? '.' : '!');
         if (!rn2(4))
             (void) destroy_mitem(mdef, POTION_CLASS, AD_FIRE);
         if (!rn2(4))
@@ -1201,8 +1204,8 @@ int dieroll; /* needed for Magicbane and vorpal blades */
     if (attacks(AD_COLD, otmp)) {
         if (realizes_damage)
             pline_The("ice-cold blade %s %s%c",
-                      !icontext.spec_dbon_applies ? "hits" : "freezes", hittee,
-                      !icontext.spec_dbon_applies ? '.' : '!');
+                      !spec_dbon_applies ? "hits" : "freezes", hittee,
+                      !spec_dbon_applies ? '.' : '!');
         if (!rn2(4))
             (void) destroy_mitem(mdef, POTION_CLASS, AD_COLD);
         return realizes_damage;
@@ -1210,9 +1213,9 @@ int dieroll; /* needed for Magicbane and vorpal blades */
     if (attacks(AD_ELEC, otmp)) {
         if (realizes_damage)
             pline_The("massive hammer hits%s %s%c",
-                      !icontext.spec_dbon_applies ? "" : "!  Lightning strikes",
-                      hittee, !icontext.spec_dbon_applies ? '.' : '!');
-        if (icontext.spec_dbon_applies)
+                      !spec_dbon_applies ? "" : "!  Lightning strikes",
+                      hittee, !spec_dbon_applies ? '.' : '!');
+        if (spec_dbon_applies)
             wake_nearto(mdef->mx, mdef->my, 4 * 4);
         if (!rn2(5))
             (void) destroy_mitem(mdef, RING_CLASS, AD_ELEC);
@@ -1223,10 +1226,10 @@ int dieroll; /* needed for Magicbane and vorpal blades */
     if (attacks(AD_MAGM, otmp)) {
         if (realizes_damage)
             pline_The("imaginary widget hits%s %s%c",
-                      !icontext.spec_dbon_applies
+                      !spec_dbon_applies
                           ? ""
                           : "!  A hail of magic missiles strikes",
-                      hittee, !icontext.spec_dbon_applies ? '.' : '!');
+                      hittee, !spec_dbon_applies ? '.' : '!');
         return realizes_damage;
     }
 
@@ -1235,7 +1238,7 @@ int dieroll; /* needed for Magicbane and vorpal blades */
         return Mb_hit(magr, mdef, otmp, dmgptr, dieroll, vis, hittee);
     }
 
-    if (!icontext.spec_dbon_applies) {
+    if (!spec_dbon_applies) {
         /* since damage bonus didn't apply, nothing more to do;
            no further attacks have side-effects on inventory */
         return FALSE;
index 9256051b3e797b7d31a10340e12fcfda1ca2b61e..4af7491057a46286423d795adbf65879643894ac 100644 (file)
@@ -11,6 +11,7 @@ extern const char *hu_stat[]; /* defined in eat.c */
 const char *const enc_stat[] = { "",         "Burdened",  "Stressed",
                                  "Strained", "Overtaxed", "Overloaded" };
 
+STATIC_OVL NEARDATA int mrank_sz = 0; /* loaded by max_rank_sz (from u_init) */
 STATIC_DCL const char *NDECL(rank);
 #ifdef STATUS_HILITES
 STATIC_DCL void NDECL(bot_via_windowport);
@@ -64,7 +65,7 @@ do_statusline1()
         Strcpy(nb = eos(nb), rank());
 
     Sprintf(nb = eos(nb), "  ");
-    i = icontext.mrank_sz + 15;
+    i = mrank_sz + 15;
     j = (int) ((nb + 2) - newbot1); /* strlen(newbot1) but less computation */
     if ((i - j) > 0)
         Sprintf(nb = eos(nb), "%*s", i - j, " "); /* pad with spaces */
@@ -345,7 +346,7 @@ max_rank_sz()
         if (urole.rank[i].f && (r = strlen(urole.rank[i].f)) > maxr)
             maxr = r;
     }
-    icontext.mrank_sz = maxr;
+    mrank_sz = maxr;
     return;
 }
 
index 2a259efaa867517ffe490d76e0ff5a64db6db168..edfeb3a60441c2d5aa449b029926005306487b99 100644 (file)
@@ -207,6 +207,7 @@ NEARDATA char dogname[PL_PSIZ] = DUMMY;
 NEARDATA char catname[PL_PSIZ] = DUMMY;
 NEARDATA char horsename[PL_PSIZ] = DUMMY;
 char preferred_pet; /* '\0', 'c', 'd', 'n' (none) */
+int petname_used = 0;
 /* monsters that went down/up together with @ */
 NEARDATA struct monst *mydogs = (struct monst *) 0;
 /* monsters that are moving to another dungeon level */
@@ -284,6 +285,7 @@ char *fqn_prefix_names[PREFIX_COUNT] = {
 };
 #endif
 
+#ifdef PLAYAGAIN
 const struct savefile_info default_sfinfo = {
 #ifdef NHSTDC
     0x00000000UL
@@ -306,8 +308,53 @@ const struct savefile_info default_sfinfo = {
     0x00000000L, 0x00000000L
 #endif
 };
+#endif
 
-NEARDATA struct savefile_info sfcap, sfrestinfo, sfsaveinfo;
+NEARDATA struct savefile_info sfcap = {
+#ifdef NHSTDC
+    0x00000000UL
+#else
+    0x00000000L
+#endif
+#if defined(COMPRESS) || defined(ZLIB_COMP)
+        | SFI1_EXTERNALCOMP
+#endif
+#if defined(ZEROCOMP)
+        | SFI1_ZEROCOMP
+#endif
+#if defined(RLECOMP)
+        | SFI1_RLECOMP
+#endif
+    ,
+#ifdef NHSTDC
+    0x00000000UL, 0x00000000UL
+#else
+    0x00000000L, 0x00000000L
+#endif
+};
+
+NEARDATA struct savefile_info sfrestinfo, sfsaveinfo = {
+#ifdef NHSTDC
+    0x00000000UL
+#else
+    0x00000000L
+#endif
+#if defined(COMPRESS) || defined(ZLIB_COMP)
+        | SFI1_EXTERNALCOMP
+#endif
+#if defined(ZEROCOMP)
+        | SFI1_ZEROCOMP
+#endif
+#if defined(RLECOMP)
+        | SFI1_RLECOMP
+#endif
+    ,
+#ifdef NHSTDC
+    0x00000000UL, 0x00000000UL
+#else
+    0x00000000L, 0x00000000L
+#endif
+};
 
 struct plinemsg_type *plinemsg_types = (struct plinemsg_type *) 0;
 
@@ -325,14 +372,243 @@ decl_init()
     return;
 }
 
+#ifdef PLAYAGAIN
+
+static boolean s_firstStart = TRUE;
+
+static boolean
+decl_is_block_zero(p, n)
+unsigned char * p;
+int n;
+{
+    static unsigned char zeroblock[512] = { 0 };
+    unsigned char * sentinel = p + n;
+    while (p < sentinel) {
+        int c = (n < sizeof(zeroblock) ? n : sizeof(zeroblock));
+        if (memcmp(p, zeroblock, c) != 0) return FALSE;
+        p += c;
+    }
+    return TRUE;
+}
+
+static void
+decl_zero_block(p, n)
+unsigned char * p;
+int n;
+{
+    nhassert(!s_firstStart || decl_is_block_zero(p, n));
+    memset(p, 0, n);
+}
+
+#define ZEROARRAY(x) decl_zero_block((void *) &x[0], 0, sizeof(x))
+#define ZEROARRAYN(x,n) decl_zero_block((void *) &x[0], 0, sizeof(x[0])*(n))
+#define ZERO(x) decl_zero_block((void *) &x, 0, sizeof(x))
+#define ZEROPTR(x) { nhassert(x == NULL); x = NULL; }
+#define ZEROPTRNOCHECK(x) { x = NULL; }
+
+/* decl_early_init() is called when we are starting a game.  On first
+ * start, it validates that global state is in the expected state.
+ * When called on subsequent starts, it initializes global state to
+ * expected state.
+ *
+ * In the case that of global pointers, on subsequent starts it will
+ * panic if it finds a non-NULL pointer with the assumption that a
+ * pointer has leaked.  */
+
+void
+decl_early_init()
+{
+    hackpid = 0;
+#if defined(UNIX) || defined(VMS)
+    locknum = 0;
+#endif
+#ifdef DEF_PAGER
+    catmore = 0;
+#endif
+
+    ZEROARRAY(bases);
+
+    multi = 0;
+    multi_reason = NULL;
+    nroom = 0;
+    nsubroom = 0;
+    occtime = 0;
+
+    x_maze_max = (COLNO - 1) & ~1;
+    y_maze_max = (ROWNO - 1) & ~1;
+
+    otg_temp = 0;
+
+    ZERO(dungeon_topology);
+    ZERO(quest_status);
+
+    warn_obj_cnt = 0;
+    ZEROARRAYN(smeq, MAXNROFROOMS + 1);
+    doorindex = 0;
+    save_cm = NULL;
+
+    ZERO(killer);
+    done_money = 0;
+    nomovemsg = NULL;
+    ZEROARRAY(plname);
+    ZEROARRAY(pl_character);
+    pl_race = '\0';
+
+    ZEROARRAY(pl_fruit);
+    ffruit = NULL;
+
+    ZEROARRAY(tune);
+
+    occtxt = NULL;
+
+    yn_number = 0;
+
+#if defined(MICRO) || defined(WIN32)
+    ZEROARRAYN(hackdir, PATHLEN);
+#ifdef MICRO
+    ZEROARRAYN(levels, PATHLEN);
+#endif /* MICRO */
+#endif /* MICRO || WIN32 */
+
+#ifdef MFLOPPY
+    ZEROARRAYN(permbones, PATHLEN);
+    ramdisk = FALSE;
+    saveprompt = TRUE;
+#endif
+
+    ZEROARRAY(level_info);
+
+    ZERO(program_state);
+
+    tbx = 0;
+    tby = 0;
+
+    ZERO(m_shot);
+
+    ZEROARRAYN(dungeons, MAXDUNGEON);
+    ZEROPTR(sp_levchn);
+    ZERO(upstair);
+    ZERO(dnstair);
+    ZERO(upladder);
+    ZERO(dnladder);
+    ZERO(sstairs);
+    ZERO(updest);
+    ZERO(dndest);
+    ZERO(inv_pos);
+
+    defer_see_monsters = FALSE;
+    in_mklev = FALSE;
+    stoned = FALSE;
+    unweapon = FALSE;
+    mrg_to_wielded = FALSE;
+
+    in_steed_dismounting = FALSE;
+
+    ZERO(bhitpos);
+    ZEROARRAY(doors);
+
+    ZEROARRAY(rooms);
+    subrooms = &rooms[MAXNROFROOMS + 1];
+    upstairs_room = NULL;
+    dnstairs_room = NULL;
+    sstairs_room = NULL;
+
+    ZERO(level);
+    ZEROPTR(ftrap);
+    ZERO(youmonst);
+    ZERO(context);
+    ZERO(flags);
+#ifdef SYSFLAGS
+    ZERO(sysflags);
+#endif
+    ZERO(iflags);
+    ZERO(u);
+    ZERO(ubirthday);
+    ZERO(urealtime);
+
+    ZEROARRAY(lastseentyp);
+
+    ZEROPTR(invent);
+    ZEROPTRNOCHECK(uwep);
+    ZEROPTRNOCHECK(uarm);
+    ZEROPTRNOCHECK(uswapwep);
+    ZEROPTRNOCHECK(uquiver);
+    ZEROPTRNOCHECK(uarmu);
+    ZEROPTRNOCHECK(uskin);
+    ZEROPTRNOCHECK(uarmc);
+    ZEROPTRNOCHECK(uarmh);
+    ZEROPTRNOCHECK(uarms);
+    ZEROPTRNOCHECK(uarmg);
+    ZEROPTRNOCHECK(uarmf);
+    ZEROPTRNOCHECK(uamul);
+    ZEROPTRNOCHECK(uright);
+    ZEROPTRNOCHECK(uleft);
+    ZEROPTRNOCHECK(ublindf);
+    ZEROPTRNOCHECK(uchain);
+    ZEROPTRNOCHECK(uball);
+
+    ZEROPTR(current_wand);
+    ZEROPTR(thrownobj);
+    ZEROPTR(kickedobj);
+
+    ZEROARRAYN(spl_book, MAXSPELL + 1);
+
+    moves = 1;
+    monstermoves = 1;
+
+    wailmsg = 0L;
+
+    ZEROPTR(migrating_objs);
+    ZEROPTR(billobjs);
+
+    ZERO(zeroobj);
+    ZERO(zeromonst);
+    ZERO(zeroany);
+
+    ZEROARRAYN(dogname, PL_PSIZ);
+    ZEROARRAYN(catname, PL_PSIZ);
+    ZEROARRAYN(horsename, PL_PSIZ);
+    ZERO(preferred_pet);
+    ZERO(petname_used);
+    ZEROPTR(mydogs);
+    ZEROPTR(migrating_mons);
+
+    ZEROARRAY(mvitals);
+
+    ZEROPTR(menu_colorings);
+
+    vision_full_recalc = 0;
+    viz_array = NULL;
+
+    WIN_MESSAGE = WIN_ERR;
+#ifndef STATUS_VIA_WINDOWPORT
+    WIN_STATUS = WIN_ERR;
+#endif
+    WIN_MAP = WIN_ERR;
+    WIN_INVEN = WIN_ERR;
+
+    ZEROARRAYN(toplines, TBUFSZ);
+    ZERO(tc_gbl_data);
+    ZEROARRAYN(fqn_prefix, PREFIX_COUNT);
+
+    sfcap = default_sfinfo;
+    sfrestinfo = default_sfinfo;
+    sfsaveinfo = default_sfinfo;
+
+    ZEROPTR(plinemsg_types);
+
+#ifdef PANICTRACE
+    ARGV0 = NULL;
+#endif
+
+    nhUse_dummy = 0;
+
+    s_firstStart = FALSE;
+}
+#endif
+
 const struct instance_context icontext_initial_state = {
-    0,  /* oldcap - last encumberance in pickup.c */
-    0,  /* petname_used - dog.c */
-    0,  /* jumping_is_magic - apply.c */
-    -1, /* polearm_range_min - apply.c */
-    -1, /* polearm_range_max - apply.c */
-    0,  /* spec_dbon_applies - artifact.c */
-    0,  /* mrank_sz - botl.c */
+    0, /* oldcap - last encumberance in pickup.c */
 };
 
 struct instance_context icontext;
@@ -342,9 +618,7 @@ icontext_init()
 {
     icontext = icontext_initial_state;
 
-    sfcap = default_sfinfo;
-    sfrestinfo = default_sfinfo;
-    sfsaveinfo = default_sfinfo;
+    decl_early_init();
 };
 
 /*decl.c*/
index 79e6b781f4ea36f9b3c6a6e4e1009dfba967d7bd..7c1b62e8b205c94afe079a8fcfe157312e35f11c 100644 (file)
--- a/src/dog.c
+++ b/src/dog.c
@@ -197,7 +197,7 @@ makedog()
         put_saddle_on_mon(otmp, mtmp);
     }
 
-    if (!icontext.petname_used++ && *petname)
+    if (!petname_used++ && *petname)
         mtmp = christen_monst(mtmp, petname);
 
     initedog(mtmp);
index 557cb3219310c84e40c5b35cc8334aebc020d38c..f26379967f1383e686a0b90b5d25f97bc892a9fa 100644 (file)
@@ -899,7 +899,7 @@ register int fd;
 #ifdef MFLOPPY
     gameDiskPrompt();
 #endif
-    max_rank_sz(); /* to recompute icontext.mrank_sz (botl.c) */
+    max_rank_sz(); /* to recompute mrank_sz (botl.c) */
     /* take care of iron ball & chain */
     for (otmp = fobj; otmp; otmp = otmp->nobj)
         if (otmp->owornmask)