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
};
/****
- *** 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 {
#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 \
/*
* 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 */
* 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 \
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;
}
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));
&& 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;
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;
}
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);
{
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
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);
}
}
if (!mid || !obj)
return (struct obj *) 0;
newomid(obj);
- *OMID(obj) = mid;
+ OMID(obj) = mid;
return obj;
}
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));
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));
}
}
{
struct obj *otmp;
unsigned oldid, nid;
+
for (otmp = fobj; otmp; otmp = otmp->nobj) {
if (ghostly && has_omonst(otmp)) {
struct monst *mtmp = OMONST(otmp);
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);
}
/* 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;
if (perform_bwrite(nhfp)) {
if (nhfp->structlevel)
bwrite(nhfp->fd, (genericptr_t) thisbones, sizeof *thisbones);
- }
+ }
if (release_data(nhfp))
free((genericptr_t) thisbones);
}
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))
} 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);
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));
}
}
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));
}
}
if (perform_bwrite(nhfp)) {
if (nhfp->structlevel)
bwrite(nhfp->fd, (genericptr_t) trap, sizeof *trap);
- }
+ }
if (release_data(nhfp))
dealloc_trap(trap);
trap = trap2;
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;
if (perform_bwrite(nhfp)) {
if (nhfp->structlevel)
bwrite(nhfp->fd, (genericptr_t) tmplev, sizeof *tmplev);
- }
+ }
if (release_data(nhfp))
free((genericptr_t) tmplev);
}
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))