From: PatR Date: Fri, 24 Apr 2020 16:29:52 +0000 (-0700) Subject: obj->oextra->{omid,olong} X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e63fed627cce352f2529cdb7c88e55ab875b5a54;p=nethack obj->oextra->{omid,olong} 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. --- diff --git a/doc/fixes37.0 b/doc/fixes37.0 index cf311f4ad..5354bd565 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -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 diff --git a/include/obj.h b/include/obj.h index 1cf298dba..d736ef424 100644 --- a/include/obj.h +++ b/include/obj.h @@ -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 */ diff --git a/include/patchlevel.h b/include/patchlevel.h index 614c73bd5..77039bc79 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -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 \ diff --git a/src/cmd.c b/src/cmd.c index 085b30ad3..cc53f0915 100644 --- 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; } diff --git a/src/invent.c b/src/invent.c index a3d4ed209..079af9f23 100644 --- a/src/invent.c +++ b/src/invent.c @@ -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; diff --git a/src/mkobj.c b/src/mkobj.c index dd7e92b09..7d6480035 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -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; } diff --git a/src/restore.c b/src/restore.c index deabf002f..2f9191255 100644 --- a/src/restore.c +++ b/src/restore.c @@ -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); } diff --git a/src/save.c b/src/save.c index cf95c198b..c2d710f4c 100644 --- a/src/save.c +++ b/src/save.c @@ -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); } diff --git a/src/zap.c b/src/zap.c index 0db7fff2b..64e642e16 100644 --- 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))