]> granicus.if.org Git - nethack/commitdiff
obj->oextra->{omid,olong}
authorPatR <rankin@nethack.org>
Fri, 24 Apr 2020 16:29:52 +0000 (09:29 -0700)
committerPatR <rankin@nethack.org>
Fri, 24 Apr 2020 16:29:52 +0000 (09:29 -0700)
Change obj->oextra->omid from a usually-Null pointer field in
oextra to a simple 'unsigned' that doesn't need any allocation
beyond obj->oextra itself.  Value 0 means that it is not in use;
it is used to hold a monst.m_id and those are always non-zero.

Delete unused obj->oextra->olong.  'olong' used to be the last
field in struct obj, put there to force alignment of anything
which followed it back when obj structures were over-allocated to
append extra information.  It had a comment about being used for
temporary gold but whatever that was, temporary gold was gone long
before obj->oextra got introduced.

Bump EDITLEVEL since this invalidates existing 3.7 save files.

Remove a bunch of tabs from obj.h and save.c.

doc/fixes37.0
include/obj.h
include/patchlevel.h
src/cmd.c
src/invent.c
src/mkobj.c
src/restore.c
src/save.c
src/zap.c

index cf311f4adbb5aee62fc70bab5d7619dd2da17500..5354bd565e68960c81bea0f0d91cfc4376253004 100644 (file)
@@ -371,4 +371,6 @@ options overhaul: moved the option definitions into include/optlist.h;
 function reglyph_darkroom() relocated from options.c to display.c
 resurrect 'makedefs -m' to be able to derive default mons[].diffculty values
        suitable for assigning to new or changed monsters
+convert obj->oextra->omid from pointer to scalar
+get rid of unused obj->oextra->olong
 
index 1cf298dba62ad78e5429063ab81a539f4074fcd0..d736ef424a2fd532695948286efa0201740a4f63 100644 (file)
@@ -16,15 +16,14 @@ union vptrs {
 };
 
 /****
- ***   oextra -- collection of all object extensions
- **    (see the note at the bottom of this file before adding oextra fields)
+ ***    oextra -- collection of all object extensions
+ **     (see the note at the bottom of this file before adding oextra fields)
  */
 struct oextra {
     char *oname;          /* ptr to name of object */
     struct monst *omonst; /* ptr to attached monst struct */
-    unsigned *omid;       /* ptr to m_id */
-    long *olong;          /* ptr to misc long (temporary gold object) */
-    char *omailcmd;       /* response_cmd for mail deliver */
+    char *omailcmd;       /* response_cmd for mail delivery */
+    unsigned omid;        /* for corpse; m_id of corpse's ghost */
 };
 
 struct obj {
@@ -126,32 +125,30 @@ struct obj {
 #define newobj() (struct obj *) alloc(sizeof(struct obj))
 
 /***
- **    oextra referencing and testing macros
+ **     oextra referencing and testing macros
  */
 
 #define ONAME(o) ((o)->oextra->oname)
-#define OMID(o) ((o)->oextra->omid)
 #define OMONST(o) ((o)->oextra->omonst)
-#define OLONG(o) ((o)->oextra->olong)
 #define OMAILCMD(o) ((o)->oextra->omailcmd)
+#define OMID(o) ((o)->oextra->omid) /* non-zero => set, zero => not set */
 
 #define has_oname(o) ((o)->oextra && ONAME(o))
-#define has_omid(o) ((o)->oextra && OMID(o))
 #define has_omonst(o) ((o)->oextra && OMONST(o))
-#define has_olong(o) ((o)->oextra && OLONG(o))
 #define has_omailcmd(o) ((o)->oextra && OMAILCMD(o))
+#define has_omid(o) ((o)->oextra && OMID(o))
 
 /* Weapons and weapon-tools */
 /* KMH -- now based on skill categories.  Formerly:
- *     #define is_sword(otmp)  (otmp->oclass == WEAPON_CLASS && \
- *                      objects[otmp->otyp].oc_wepcat == WEP_SWORD)
- *     #define is_blade(otmp)  (otmp->oclass == WEAPON_CLASS && \
- *                      (objects[otmp->otyp].oc_wepcat == WEP_BLADE || \
- *                       objects[otmp->otyp].oc_wepcat == WEP_SWORD))
- *     #define is_weptool(o)   ((o)->oclass == TOOL_CLASS && \
- *                      objects[(o)->otyp].oc_weptool)
- *     #define is_multigen(otyp) (otyp <= SHURIKEN)
- *     #define is_poisonable(otyp) (otyp <= BEC_DE_CORBIN)
+ *      #define is_sword(otmp)  (otmp->oclass == WEAPON_CLASS && \
+ *                       objects[otmp->otyp].oc_wepcat == WEP_SWORD)
+ *      #define is_blade(otmp)  (otmp->oclass == WEAPON_CLASS && \
+ *                       (objects[otmp->otyp].oc_wepcat == WEP_BLADE || \
+ *                        objects[otmp->otyp].oc_wepcat == WEP_SWORD))
+ *      #define is_weptool(o)   ((o)->oclass == TOOL_CLASS && \
+ *                       objects[(o)->otyp].oc_weptool)
+ *      #define is_multigen(otyp) (otyp <= SHURIKEN)
+ *      #define is_poisonable(otyp) (otyp <= BEC_DE_CORBIN)
  */
 #define is_blade(otmp)                           \
     (otmp->oclass == WEAPON_CLASS                \
@@ -381,43 +378,44 @@ struct obj {
 /*
  *  Notes for adding new oextra structures:
  *
- *      1. Add the structure definition and any required macros in an
+ *       1. Add the structure definition and any required macros in an
  *          appropriate header file that precedes this one.
- *      2. Add a pointer to your new struct to oextra struct in this file.
- *      3. Add a referencing macro to this file after the newobj macro above
- *         (see ONAME, OMONST, OMIN, OLONG, or OMAILCMD for examples).
- *      4. Add a testing macro after the set of referencing macros
- *         (see has_oname(), has_omonst(), has_omin(), has_olong(),
- *         has_omailcmd() for examples).
- *      5. Create newXX(otmp) function and possibly free_XX(otmp) function
- *         in an appropriate new or existing source file and add a prototype
- *         for it to include/extern.h.  The majority of these are currently
- *         located in mkobj.c for convenience.
+ *       2. Add a pointer to your new struct to oextra struct in this file.
+ *       3. Add a referencing macro to this file after the newobj macro above
+ *          (see ONAME, OMONST, OMAILCMD, or OMIN for examples).
+ *       4. Add a testing macro after the set of referencing macros
+ *          (see has_oname(), has_omonst(), has_omailcmd(), and has_omin(),
+ *          for examples).
+ *       5. Create newXX(otmp) function and possibly free_XX(otmp) function
+ *          in an appropriate new or existing source file and add a prototype
+ *          for it to include/extern.h.  The majority of these are currently
+ *          located in mkobj.c for convenience.
  *
- *             void FDECL(newXX, (struct obj *));
- *             void FDECL(free_XX, (struct obj *));
+ *          void FDECL(newXX, (struct obj *));
+ *          void FDECL(free_XX, (struct obj *));
  *
- *               void
- *               newxx(otmp)
- *               struct obj *otmp;
- *               {
- *                   if (!otmp->oextra) otmp->oextra = newoextra();
- *                   if (!XX(otmp)) {
- *                       XX(otmp) = (struct XX *)alloc(sizeof(struct xx));
- *                       (void) memset((genericptr_t) XX(otmp),
- *                                  0, sizeof(struct xx));
- *                   }
- *               }
+ *          void
+ *          newxx(otmp)
+ *          struct obj *otmp;
+ *          {
+ *              if (!otmp->oextra)
+ *                  otmp->oextra = newoextra();
+ *              if (!XX(otmp)) {
+ *                  XX(otmp) = (struct XX *) alloc(sizeof (struct xx));
+ *                  (void) memset((genericptr_t) XX(otmp),
+ *                                0, sizeof (struct xx));
+ *              }
+ *         }
  *
- *      6. Adjust size_obj() in src/cmd.c appropriately.
- *      7. Adjust dealloc_oextra() in src/mkobj.c to clean up
- *         properly during obj deallocation.
- *      8. Adjust copy_oextra() in src/mkobj.c to make duplicate
- *         copies of your struct or data onto another obj struct.
- *      9. Adjust restobj() in src/restore.c to deal with your
- *         struct or data during a restore.
- *     10. Adjust saveobj() in src/save.c to deal with your
- *         struct or data during a save.
+ *       6. Adjust size_obj() in src/cmd.c appropriately.
+ *       7. Adjust dealloc_oextra() in src/mkobj.c to clean up
+ *          properly during obj deallocation.
+ *       8. Adjust copy_oextra() in src/mkobj.c to make duplicate
+ *          copies of your struct or data onto another obj struct.
+ *       9. Adjust restobj() in src/restore.c to deal with your
+ *          struct or data during a restore.
+ *      10. Adjust saveobj() in src/save.c to deal with your
+ *          struct or data during a save.
  */
 
 #endif /* OBJ_H */
index 614c73bd51017dba6b0ebdb221d80d589f246f8d..77039bc794463a7a77fa926f2dd8bffba6be2aab 100644 (file)
@@ -14,7 +14,7 @@
  * Incrementing EDITLEVEL can be used to force invalidation of old bones
  * and save files.
  */
-#define EDITLEVEL 17
+#define EDITLEVEL 18
 
 #define COPYRIGHT_BANNER_A "NetHack, Copyright 1985-2020"
 #define COPYRIGHT_BANNER_B \
index 085b30ad35a98db061d5b68f8561a0e147bea4a5..cc53f0915ccefbc166147df536e36051a84b2533 100644 (file)
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -2295,12 +2295,9 @@ struct obj *otmp;
             sz += (int) strlen(ONAME(otmp)) + 1;
         if (OMONST(otmp))
             sz += size_monst(OMONST(otmp), FALSE);
-        if (OMID(otmp))
-            sz += (int) sizeof (unsigned);
-        if (OLONG(otmp))
-            sz += (int) sizeof (long);
         if (OMAILCMD(otmp))
             sz += (int) strlen(OMAILCMD(otmp)) + 1;
+        /* sz += (int) sizeof (unsigned); -- now part of oextra itself */
     }
     return sz;
 }
index a3d4ed209615c11857a5fa4807bb046583a8b8c3..079af9f23d30d1c561ebf2144f3e87fea2d9d6d4 100644 (file)
@@ -3718,6 +3718,11 @@ register struct obj *otmp, *obj;
     if (obj->unpaid && !same_price(obj, otmp))
         return FALSE;
 
+    /* some additional information is always incompatible */
+    if (has_omonst(obj) || has_omid(obj)
+        || has_omonst(otmp) || has_omid(otmp))
+        return FALSE;
+
     /* if they have names, make sure they're the same */
     objnamelth = strlen(safe_oname(obj));
     otmpnamelth = strlen(safe_oname(otmp));
@@ -3727,11 +3732,12 @@ register struct obj *otmp, *obj;
             && strncmp(ONAME(obj), ONAME(otmp), objnamelth)))
         return FALSE;
 
-    /* for the moment, any additional information is incompatible */
-    if (has_omonst(obj) || has_omid(obj) || has_olong(obj) || has_omonst(otmp)
-        || has_omid(otmp) || has_olong(otmp))
+    /* if one has an attached mail command, other must have same command */
+    if (!has_omailcmd(obj) ? has_omailcmd(otmp)
+        : (!has_omailcmd(otmp) || strcmp(OMAILCMD(obj), OMAILCMD(otmp)) != 0))
         return FALSE;
 
+    /* should be moot since matching artifacts wouldn't be unique */
     if (obj->oartifact != otmp->oartifact)
         return FALSE;
 
index dd7e92b09072bb3f3736148a5cdf88e23d0879d5..7d6480035a22177d4fa9e8e5c90035a1cbf216b7 100644 (file)
@@ -75,9 +75,8 @@ newoextra()
     oextra = (struct oextra *) alloc(sizeof (struct oextra));
     oextra->oname = 0;
     oextra->omonst = 0;
-    oextra->omid = 0;
-    oextra->olong = 0;
     oextra->omailcmd = 0;
+    oextra->omid = 0;
     return oextra;
 }
 
@@ -92,10 +91,6 @@ struct obj *o;
             free((genericptr_t) x->oname);
         if (x->omonst)
             free_omonst(o);     /* 'o' rather than 'x' */
-        if (x->omid)
-            free((genericptr_t) x->omid);
-        if (x->olong)
-            free((genericptr_t) x->olong);
         if (x->omailcmd)
             free((genericptr_t) x->omailcmd);
 
@@ -141,42 +136,14 @@ struct obj *otmp;
 {
     if (!otmp->oextra)
         otmp->oextra = newoextra();
-    if (!OMID(otmp)) {
-        OMID(otmp) = (unsigned *) alloc(sizeof (unsigned));
-        (void) memset((genericptr_t) OMID(otmp), 0, sizeof (unsigned));
-    }
+    OMID(otmp) = 0;
 }
 
 void
 free_omid(otmp)
 struct obj *otmp;
 {
-    if (otmp->oextra && OMID(otmp)) {
-        free((genericptr_t) OMID(otmp));
-        OMID(otmp) = (unsigned *) 0;
-    }
-}
-
-void
-newolong(otmp)
-struct obj *otmp;
-{
-    if (!otmp->oextra)
-        otmp->oextra = newoextra();
-    if (!OLONG(otmp)) {
-        OLONG(otmp) = (long *) alloc(sizeof (long));
-        (void) memset((genericptr_t) OLONG(otmp), 0, sizeof (long));
-    }
-}
-
-void
-free_olong(otmp)
-struct obj *otmp;
-{
-    if (otmp->oextra && OLONG(otmp)) {
-        free((genericptr_t) OLONG(otmp));
-        OLONG(otmp) = (long *) 0;
-    }
+    OMID(otmp) = 0;
 }
 
 void
@@ -406,20 +373,13 @@ struct obj *obj2, *obj1;
         if (OMONST(obj1)->mextra)
             copy_mextra(OMONST(obj2), OMONST(obj1));
     }
+    if (has_omailcmd(obj1)) {
+        new_omailcmd(obj2, OMAILCMD(obj1));
+    }
     if (has_omid(obj1)) {
         if (!OMID(obj2))
             newomid(obj2);
-        (void) memcpy((genericptr_t) OMID(obj2), (genericptr_t) OMID(obj1),
-                      sizeof (unsigned));
-    }
-    if (has_olong(obj1)) {
-        if (!OLONG(obj2))
-            newolong(obj2);
-        (void) memcpy((genericptr_t) OLONG(obj2), (genericptr_t) OLONG(obj1),
-                      sizeof (long));
-    }
-    if (has_omailcmd(obj1)) {
-        new_omailcmd(obj2, OMAILCMD(obj1));
+        OMID(obj2) = OMID(obj1);
     }
 }
 
@@ -1605,7 +1565,7 @@ unsigned mid;
     if (!mid || !obj)
         return (struct obj *) 0;
     newomid(obj);
-    *OMID(obj) = mid;
+    OMID(obj) = mid;
     return obj;
 }
 
index deabf002f5bac959566fdc9f65eead958ed8bcff..2f9191255a07131dd3a7a197feffc4847dfd3d70 100644 (file)
@@ -229,25 +229,6 @@ struct obj *otmp;
             restmon(nhfp, OMONST(otmp));
         }
 
-        /* omid - monster id number, connecting corpse to ghost */
-        if (nhfp->structlevel)
-            mread(nhfp->fd, (genericptr_t) &buflen, sizeof(buflen));
-
-        if (buflen > 0) {
-            newomid(otmp);
-            if (nhfp->structlevel)
-                mread(nhfp->fd, (genericptr_t) OMID(otmp), buflen);
-        }
-
-        /* olong - temporary gold */
-        if (nhfp->structlevel)
-            mread(nhfp->fd, (genericptr_t) &buflen, sizeof(buflen));
-        if (buflen > 0) {
-            newolong(otmp);
-            if (nhfp->structlevel)
-                mread(nhfp->fd, (genericptr_t) OLONG(otmp), buflen);
-        }
-
         /* omailcmd - feedback mechanism for scroll of mail */
         if (nhfp->structlevel)
             mread(nhfp->fd, (genericptr_t) &buflen, sizeof(buflen));
@@ -259,6 +240,11 @@ struct obj *otmp;
             new_omailcmd(otmp, omailcmd);
             free((genericptr_t) omailcmd);
         }
+
+        /* omid - monster id number, connecting corpse to ghost */
+        newomid(otmp); /* superfluous; we're already allocated otmp->oextra */
+        if (nhfp->structlevel)
+            mread(nhfp->fd, (genericptr_t) &OMID(otmp), sizeof OMID(otmp));
     }
 }
 
@@ -1393,6 +1379,7 @@ boolean ghostly;
 {
     struct obj *otmp;
     unsigned oldid, nid;
+
     for (otmp = fobj; otmp; otmp = otmp->nobj) {
         if (ghostly && has_omonst(otmp)) {
             struct monst *mtmp = OMONST(otmp);
@@ -1401,11 +1388,9 @@ boolean ghostly;
             mtmp->mpeaceful = mtmp->mtame = 0; /* pet's owner died! */
         }
         if (ghostly && has_omid(otmp)) {
-            (void) memcpy((genericptr_t) &oldid, (genericptr_t) OMID(otmp),
-                          sizeof(oldid));
+            oldid = OMID(otmp);
             if (lookup_id_mapping(oldid, &nid))
-                (void) memcpy((genericptr_t) OMID(otmp), (genericptr_t) &nid,
-                              sizeof(nid));
+                OMID(otmp) = nid;
             else
                 free_omid(otmp);
         }
index cf95c198b65905b4c1de4ae125b68e2ac67fdfcd..c2d710f4c87cb9f4fd897a788603ea1d51bfca85 100644 (file)
@@ -633,9 +633,9 @@ boolean rlecomp;
                     /* run has been broken, write out run-length encoding */
  writeout:
                     if (nhfp->structlevel) {
-                        bwrite(nhfp->fd, (genericptr_t) &match, sizeof (uchar));
-                        bwrite(nhfp->fd, (genericptr_t) rgrm, sizeof (struct rm));
-                   }
+                        bwrite(nhfp->fd, (genericptr_t) &match, sizeof match);
+                        bwrite(nhfp->fd, (genericptr_t) rgrm, sizeof *rgrm);
+                    }
                     /* start encoding again. we have at least 1 rm
                        in the next run, viz. this one. */
                     match = 1;
@@ -679,7 +679,7 @@ struct cemetery **cemeteryaddr;
         if (perform_bwrite(nhfp)) {
             if (nhfp->structlevel)
                 bwrite(nhfp->fd, (genericptr_t) thisbones, sizeof *thisbones);
-       }
+        }
         if (release_data(nhfp))
             free((genericptr_t) thisbones);
     }
@@ -705,7 +705,7 @@ NHFILE *nhfp;
         if (perform_bwrite(nhfp)) {
             if (nhfp->structlevel)
                 bwrite(nhfp->fd, (genericptr_t) damageptr, sizeof *damageptr);
-       }
+        }
         tmp_dam = damageptr;
         damageptr = damageptr->next;
         if (release_data(nhfp))
@@ -742,23 +742,8 @@ struct obj *otmp;
         } else {
             if (nhfp->structlevel)
                 bwrite(nhfp->fd, (genericptr_t) &zerobuf, sizeof zerobuf);
-       }
-        buflen = OMID(otmp) ? (int) sizeof (unsigned) : 0;
-        if (nhfp->structlevel)
-            bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen);
-        if (buflen > 0) {
-            if (nhfp->structlevel)
-                bwrite(nhfp->fd, (genericptr_t) OMID(otmp), buflen);
-       }
-        /* TODO: post 3.6.x, get rid of this */
-        buflen = OLONG(otmp) ? (int) sizeof (long) : 0;
-        if (nhfp->structlevel)
-            bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen);
-        if (buflen > 0) {
-            if (nhfp->structlevel)
-                bwrite(nhfp->fd, (genericptr_t) OLONG(otmp), buflen);
-       }
-
+        }
+        /* extra info about scroll of mail */
         buflen = OMAILCMD(otmp) ? (int) strlen(OMAILCMD(otmp)) + 1 : 0;
         if (nhfp->structlevel)
             bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen);
@@ -766,6 +751,11 @@ struct obj *otmp;
             if (nhfp->structlevel)
                   bwrite(nhfp->fd, (genericptr_t) OMAILCMD(otmp), buflen);
         }
+        /* omid used to be indirect via a pointer in oextra but has
+           become part of oextra itself; 0 means not applicable and
+           gets saved/restored whenever any other oxtra components do */
+        if (nhfp->structlevel)
+            bwrite(nhfp->fd, (genericptr_t) &OMID(otmp), sizeof OMID(otmp));
     }
 }
 
@@ -874,11 +864,12 @@ struct monst *mtmp;
         if (buflen > 0) {
             if (nhfp->structlevel)
                 bwrite(nhfp->fd, (genericptr_t) EDOG(mtmp), buflen);
-       }
+        }
         /* mcorpsenm is inline int rather than pointer to something,
            so doesn't need to be preceded by a length field */
         if (nhfp->structlevel)
-            bwrite(nhfp->fd, (genericptr_t) &MCORPSENM(mtmp), sizeof MCORPSENM(mtmp));
+            bwrite(nhfp->fd, (genericptr_t) &MCORPSENM(mtmp),
+                   sizeof MCORPSENM(mtmp));
     }
 }
 
@@ -930,7 +921,7 @@ register struct trap *trap;
         if (perform_bwrite(nhfp)) {
             if (nhfp->structlevel)  
                 bwrite(nhfp->fd, (genericptr_t) trap, sizeof *trap);
-       }
+        }
         if (release_data(nhfp))
             dealloc_trap(trap);
         trap = trap2;
@@ -959,7 +950,7 @@ NHFILE *nhfp;
         if (f1->fid >= 0 && perform_bwrite(nhfp)) {
             if (nhfp->structlevel)
                 bwrite(nhfp->fd, (genericptr_t) f1, sizeof *f1);
-       }
+        }
         if (release_data(nhfp))
             dealloc_fruit(f1);
         f1 = f2;
@@ -992,7 +983,7 @@ NHFILE *nhfp;
         if (perform_bwrite(nhfp)) {
             if (nhfp->structlevel)
                 bwrite(nhfp->fd, (genericptr_t) tmplev, sizeof *tmplev);
-       }
+        }
         if (release_data(nhfp))
             free((genericptr_t) tmplev);
     }
index 0db7fff2b7dd3e2e5e26428a6016f90567004b0f..64e642e16fca5c0f17399b5a2f78aa86b9dc58d4 100644 (file)
--- a/src/zap.c
+++ b/src/zap.c
@@ -873,8 +873,7 @@ boolean by_hero;
         struct monst *ghost;
         struct obj *otmp;
 
-        (void) memcpy((genericptr_t) &m_id, (genericptr_t) OMID(corpse),
-                      sizeof m_id);
+        m_id = OMID(corpse);
         ghost = find_mid(m_id, FM_FMON);
         if (ghost && ghost->data == &mons[PM_GHOST]) {
             if (canseemon(ghost))