]> granicus.if.org Git - nethack/commitdiff
code change - oextra
authornethack.allison <nethack.allison>
Fri, 14 Apr 2006 16:23:56 +0000 (16:23 +0000)
committernethack.allison <nethack.allison>
Fri, 14 Apr 2006 16:23:56 +0000 (16:23 +0000)
move oattached and oname and other things that vary
the size of the obj structure into a separate
non-adjacent oextra structure, similar to what has
already been done for mextra. The obj structure
itself becomes a fixed size.

New 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 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))

changed macros:
has_name(mon) becomes has_mname(mon)  to correspond.

The CVS repository was tagged with
NETHACK_PRE_OEXTRA
before commiting these, and
tagged with
NETHACK_POST_OEXTRA
immediately after. The diff
between those two tags is this oextra patch.

The associated mail daemon changes to use an oextra
structure instead of a hidden command located in the
name after the terminating NUL, have not been tried
or tested.

31 files changed:
doc/fixes35.0
include/extern.h
include/mextra.h
include/obj.h
include/patchlevel.h
src/artifact.c
src/bones.c
src/cmd.c
src/do_name.c
src/dog.c
src/dothrow.c
src/eat.c
src/end.c
src/invent.c
src/mail.c
src/makemon.c
src/mkobj.c
src/mon.c
src/mplayer.c
src/music.c
src/objnam.c
src/pray.c
src/read.c
src/restore.c
src/save.c
src/shk.c
src/steed.c
src/timeout.c
src/trap.c
src/wield.c
src/zap.c

index 1c694c3e084160958f15478fd6cc1861f5b33418..287cbaef36b4e27d74635bb4a0cd9376db906bf8 100644 (file)
@@ -233,3 +233,6 @@ change region player_flags to more appropriate unsigned int instead of boolean
 remove remains of sync_hunger, which has been ifdef'd out for years
 new mextra structure housing pointers to mname, egd, epri, eshk, emin, edog
 consolidate vault.h, epri.h, eshk.h, emin.h and edog.h into new mextra.h
+new oextra structure housing pointers to oname, omonst, omid, olong, and omailcmd
+
+
index 4c7292b971ab1377f760168c3249dadae4533c59..6e0ddc35eb4c55b8bb92b642319ecfd8679558eb 100644 (file)
@@ -351,6 +351,8 @@ E void NDECL(heal_legs);
 E int FDECL(getpos, (coord *,BOOLEAN_P,const char *));
 E void FDECL(new_mname, (struct monst *,int));
 E void FDECL(free_mname, (struct monst *));
+E void FDECL(new_oname, (struct obj *,int));
+E void FDECL(free_oname, (struct obj *));
 E struct monst *FDECL(christen_monst, (struct monst *,const char *));
 E int NDECL(do_mname);
 E struct obj *FDECL(oname, (struct obj *,const char *));
@@ -974,6 +976,7 @@ E struct monst *FDECL(clone_mon, (struct monst *,XCHAR_P,XCHAR_P));
 E int FDECL(monhp_per_lvl, (struct monst *));
 E void FDECL(newmonhp, (struct monst *,int));
 E struct mextra *NDECL(newmextra);
+E void FDECL(copy_mextra, (struct monst *,struct monst *));
 E struct monst *FDECL(makemon, (struct permonst *,int,int,int));
 E boolean FDECL(create_critters, (int,struct permonst *,BOOLEAN_P));
 E struct permonst *NDECL(rndmonst);
@@ -1100,6 +1103,17 @@ E const char *FDECL(waterbody_name, (XCHAR_P,XCHAR_P));
 
 /* ### mkobj.c ### */
 
+E struct oextra *NDECL(newoextra);
+E void FDECL(copy_oextra, (struct obj *,struct obj *));
+E void FDECL(dealloc_oextra, (struct oextra *));
+E void FDECL(newomonst, (struct obj *));
+E void FDECL(free_omonst, (struct obj *));
+E void FDECL(newomid, (struct obj *));
+E void FDECL(free_omid, (struct obj *));
+E void FDECL(newolong, (struct obj *));
+E void FDECL(free_olong, (struct obj *));
+E void FDECL(new_omailcmd, (struct obj *,char *));
+E void FDECL(free_omailcmd, (struct obj *));
 E struct obj *FDECL(mkobj_at, (CHAR_P,int,int,BOOLEAN_P));
 E struct obj *FDECL(mksobj_at, (int,int,int,BOOLEAN_P,BOOLEAN_P));
 E struct obj *FDECL(mkobj, (CHAR_P,BOOLEAN_P));
index 6e0eb71efd3c2fbc9395899c47407b2a019ff3d7..3e72c8b8d2c0982669c3a4f3418d733357623525 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)mextra.h   3.5     2006/02/19      */
+/*     SCCS Id: @(#)mextra.h   3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
  *      6. Adjust size_monst() in src/cmd.c appropriately.
  *      7. Adjust dealloc_mextra() in src/mon.c to clean up
  *         properly during monst deallocation.
- *      8. Adjust restmonchn() in src/restore.c to deal with your
- *         struct during a restore.
- *      9. Adjust buffer_to_mon() in src/restore.c to properly
- *         unpackage the mextra fields during revival.
- *     10. Adjust savemonchn() in src/save.c to deal with your
- *         struct during a save.
- *     11. Adjust mon_to_buffer() in src/save.c to properly package
- *         up your struct when the rest of the monst struct is
- *         packaged up.
+ *      8. Adjust copy_mextra() in src/mon.c to make duplicate
+ *         copies of your struct or data on another monst struct.
+ *      9. Adjust restmon() in src/restore.c to deal with your
+ *         struct or data during a restore.
+ *     10. Adjust savemon() in src/save.c to deal with your
+ *         struct or data during a save.
  */
  
 /***
@@ -184,6 +181,6 @@ struct mextra {
 #define ESHK(mon)      ((mon)->mextra->eshk)
 #define EMIN(mon)      ((mon)->mextra->emin)
 #define EDOG(mon)      ((mon)->mextra->edog)
-#define has_name(mon)  ((mon)->mextra && MNAME(mon))
+#define has_mname(mon) ((mon)->mextra && MNAME(mon))
 
 #endif /* MEXTRA_H */
index 32b3e0aaeedd36ea17f98b6afbb05899536d8902..c334a87316f78a58d9de7e6162d5b4a957892709 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)obj.h      3.5     2002/01/07      */
+/*     SCCS Id: @(#)obj.h      3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -14,6 +14,17 @@ union vptrs {
            struct monst *v_ocarry;     /* point back to carrying monst */
 };
 
+/***
+ **    oextra -- collection of all object extensions
+ */
+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 */
+};
+
 struct obj {
        struct obj *nobj;
        union vptrs v;
@@ -84,11 +95,7 @@ struct obj {
        Bitfield(oinvis,1);     /* invisible */
 #endif
        Bitfield(greased,1);    /* covered with grease */
-       Bitfield(oattached,2);  /* obj struct has special attachment */
-#define OATTACHED_NOTHING 0
-#define OATTACHED_MONST   1    /* monst struct in oextra */
-#define OATTACHED_M_ID    2    /* monst id in oextra */
-#define OATTACHED_UNUSED3 3
+       /* 2 free bits */
 
        Bitfield(in_use,1);     /* for magic items before useup items */
        Bitfield(bypass,1);     /* mark this as an object to be skipped by bhito() */
@@ -102,18 +109,23 @@ struct obj {
 #define fromsink  corpsenm     /* a potion from a sink */
        unsigned oeaten;        /* nutrition left in food, if partly eaten */
        long age;               /* creation date */
-
-       uchar onamelth;         /* length of name (following oxlth) */
-       short oxlth;            /* length of following data */
-       /* in order to prevent alignment problems oextra should
-          be (or follow) a long int */
        long owornmask;
-       long oextra[1];         /* used for name of ordinary objects - length
-                                  is flexible; amount for tmp gold objects */
+       struct oextra *oextra;  /* pointer to oextra struct */
 };
 
-#define newobj(xl)     (struct obj *)alloc((unsigned)(xl) + sizeof(struct obj))
-#define ONAME(otmp)    (((char *)(otmp)->oextra) + (otmp)->oxlth)
+#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 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 newobj()       (struct obj *)alloc(sizeof(struct obj))
 
 /* Weapons and weapon-tools */
 /* KMH -- now based on skill categories.  Formerly:
index 768e655e40de808ded465b3f28620df2a10e257c..38063451d7ec0e118521fb09a842dd78df762ab1 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)patchlevel.h       3.5     2006/03/25      */
+/*     SCCS Id: @(#)patchlevel.h       3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -13,7 +13,7 @@
  * Incrementing EDITLEVEL can be used to force invalidation of old bones
  * and save files.
  */
-#define EDITLEVEL      28
+#define EDITLEVEL      29
 
 #define COPYRIGHT_BANNER_A \
 "NetHack, Copyright 1985-2006"
index 3d79d17eb4819831bf25466225110f70979e7ad8..3b5ea3be79b4f32cb5b3ba98960db612c899fefc 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)artifact.c 3.5     2005/11/11      */
+/*     SCCS Id: @(#)artifact.c 3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -787,7 +787,7 @@ char *hittee;                       /* target's name: "you" or mon_nam(mdef) */
     boolean youattack = (magr == &youmonst),
            youdefend = (mdef == &youmonst),
            resisted = FALSE, do_stun, do_confuse, result;
-    boolean hitteename = (has_name(mdef) && !strcmpi(hittee, MNAME(mdef)));
+    boolean hitteename = (has_mname(mdef) && !strcmpi(hittee, MNAME(mdef)));
     int attack_indx, scare_dieroll = MB_MAX_DIEROLL / 2;
 
     result = FALSE;            /* no message given yet */
index 561740ccb4ea1b24fcf678e8650147395540d4f4..8220afb5adb99db7244b4eea90457f38d0805f2b 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)bones.c    3.5     2005/10/07      */
+/*     SCCS Id: @(#)bones.c    3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985,1993. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -68,14 +68,16 @@ boolean restore;
                        /* artifact bookeeping needs to be done during
                           restore; other fixups are done while saving */
                        if (otmp->oartifact) {
-                           if (exist_artifact(otmp->otyp, ONAME(otmp)) ||
+                           char *tmponame = "";
+                           if (has_oname(otmp)) tmponame = ONAME(otmp);
+                           if (exist_artifact(otmp->otyp, tmponame) ||
                                    is_quest_artifact(otmp)) {
                                /* prevent duplicate--revert to ordinary obj */
                                otmp->oartifact = 0;
-                               otmp->onamelth = 0;
-                               *ONAME(otmp) = '\0';
+                               if (has_oname(otmp))
+                                       free_oname(otmp);
                            } else {
-                               artifact_exists(otmp, ONAME(otmp), TRUE);
+                               artifact_exists(otmp, tmponame, TRUE);
                            }
                        }
                } else {        /* saving */
@@ -98,12 +100,11 @@ boolean restore;
                           some manner; then we could just check the flag
                           here and keep "real" names (dead pets, &c) while
                           discarding player notes attached to statues.] */
-                       if (otmp->onamelth &&
+                       if (has_oname(otmp) &&
                                !(otmp->oartifact || otmp->otyp == STATUE ||
                                    (otmp->otyp == CORPSE &&
                                         otmp->corpsenm >= SPECIAL_PM))) {
-                           otmp->onamelth = 0;
-                           *ONAME(otmp) = '\0';
+                           free_oname(otmp);
                        }
 
                        if (otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe);
@@ -126,9 +127,9 @@ boolean restore;
                               for revival flag), temple priests, and
                               vault guards in order to prevent corpse
                               revival or statue reanimation. */
-                           if (otmp->oattached == OATTACHED_MONST &&
+                           if (has_omonst(otmp) &&
                                  cant_revive(&mnum, FALSE, (struct obj *)0)) {
-                               otmp->oattached = OATTACHED_NOTHING;
+                               free_omonst(otmp);
                                /* mnum is now either human_zombie or
                                   doppelganger; for corpses of uniques,
                                   we need to force the transformation
index 1f6e95bf5c5715dde7a9fb2ad1240c24ac6400ef..412ac9f720be99d14cc7240242f9199b336a1c34 100644 (file)
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)cmd.c      3.5     2006/03/31      */
+/*     SCCS Id: @(#)cmd.c      3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -136,6 +136,7 @@ extern void FDECL(show_borlandc_stats, (winid));
 STATIC_PTR int NDECL(wiz_migrate_mons);
 #endif
 STATIC_DCL int FDECL(size_monst, (struct monst *));
+STATIC_DCL int FDECL(size_obj, (struct obj *));
 STATIC_DCL void FDECL(count_obj, (struct obj *, long *, long *, BOOLEAN_P, BOOLEAN_P));
 STATIC_DCL void FDECL(obj_chain, (winid, const char *, struct obj *, long *, long *));
 STATIC_DCL void FDECL(mon_invent_chain, (winid, const char *, struct monst *, long *, long *));
@@ -1896,6 +1897,23 @@ static const char template[] = "%-18s %4ld  %6ld";
 static const char count_str[] = "                   count  bytes";
 static const char separator[] = "------------------ -----  ------";
 
+STATIC_OVL int
+size_obj(otmp)
+struct obj *otmp;
+{
+       int sz = (int)sizeof (struct obj);
+
+       if (otmp->oextra) {
+               if (ONAME(otmp))  sz += (int)strlen(ONAME(otmp)) + 1;
+               if (OMONST(otmp)) sz += (int)sizeof (struct monst);
+               if (OMID(otmp))   sz += (int)sizeof (unsigned);
+               if (OLONG(otmp))  sz += (int)sizeof (long);
+               if (OMAILCMD(otmp))  sz += (int)strlen(OMAILCMD(otmp)) + 1;
+       }
+       return sz;
+}
+
+
 STATIC_OVL void
 count_obj(chain, total_count, total_size, top, recurse)
        struct obj *chain;
@@ -1910,7 +1928,7 @@ count_obj(chain, total_count, total_size, top, recurse)
        for (count = size = 0, obj = chain; obj; obj = obj->nobj) {
            if (top) {
                count++;
-               size += sizeof(struct obj) + obj->oxlth + obj->onamelth;
+               size += size_obj(obj);
            }
            if (recurse && obj->cobj)
                count_obj(obj->cobj, total_count, total_size, TRUE, TRUE);
index d42ef1a7829933496cd2563b6e15da3f7f3daf3d..7e5802c43dde79974052897936592151eb47c74b 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)do_name.c  3.5     2006/02/08      */
+/*     SCCS Id: @(#)do_name.c  3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -225,7 +225,7 @@ int lth;    /* desired length (caller handles adding 1 for terminator) */
        MNAME(mon) = (char *) alloc((unsigned) lth);
     } else {
        /* zero length: the new name is empty; get rid of the old name */
-       if (has_name(mon)) free_mname(mon);
+       if (has_mname(mon)) free_mname(mon);
     }
 }
 
@@ -234,12 +234,40 @@ void
 free_mname(mon)
 struct monst *mon;
 {
-    if (has_name(mon)) {
+    if (has_mname(mon)) {
        free((genericptr_t)MNAME(mon));
        MNAME(mon) = (char *)0;
     }
 }
 
+/* allocate space for an object's name; removes old name if there is one */
+void
+new_oname(obj, lth)
+struct obj *obj;
+int lth;       /* desired length (caller handles adding 1 for terminator) */
+{
+    if (lth) {
+       /* allocate oextra if necessary; otherwise get rid of old name */
+       if (!obj->oextra) obj->oextra = newoextra();
+       else free_oname(obj);   /* already has oextra, might also have name */
+       ONAME(obj) = (char *) alloc((unsigned) lth);
+    } else {
+       /* zero length: the new name is empty; get rid of the old name */
+       if (has_oname(obj)) free_oname(obj);
+    }
+}
+
+/* release an object's name; retains oextra even if all fields are now null */
+void
+free_oname(obj)
+struct obj *obj;
+{
+    if (has_oname(obj)) {
+       free((genericptr_t)ONAME(obj));
+       ONAME(obj) = (char *)0;
+    }
+}
+
 /* historical note: this returns a monster pointer because it used to
    allocate a new bigger block of memory to hold the monster and its name */
 struct monst *
@@ -368,79 +396,6 @@ register struct obj *obj;
        obj = oname(obj, buf);
 }
 
-/*
- * Allocate a new and possibly larger storage space for an obj.
- */
-struct obj *
-realloc_obj(obj, oextra_size, oextra_src, oname_size, name)
-struct obj *obj;
-int oextra_size;               /* storage to allocate for oextra            */
-genericptr_t oextra_src;
-int oname_size;                        /* size of name string + 1 (null terminator) */
-const char *name;
-{
-       struct obj *otmp;
-
-       otmp = newobj(oextra_size + oname_size);
-       *otmp = *obj;   /* the cobj pointer is copied to otmp */
-       if (oextra_size) {
-           if (oextra_src)
-               (void) memcpy((genericptr_t)otmp->oextra, oextra_src,
-                                                       oextra_size);
-       } else {
-           otmp->oattached = OATTACHED_NOTHING;
-       }
-       otmp->oxlth = oextra_size;
-
-       otmp->onamelth = oname_size;
-       otmp->timed = 0;        /* not timed, yet */
-       otmp->lamplit = 0;      /* ditto */
-       /* __GNUC__ note:  if the assignment of otmp->onamelth immediately
-          precedes this `if' statement, a gcc bug will miscompile the
-          test on vax (`insv' instruction used to store bitfield does
-          not set condition codes, but optimizer behaves as if it did).
-          gcc-2.7.2.1 finally fixed this. */
-       if (oname_size) {
-           if (name)
-               Strcpy(ONAME(otmp), name);
-       }
-
-       if (obj->owornmask) {
-               boolean save_twoweap = u.twoweap;
-               /* unwearing the old instance will clear dual-wield mode
-                  if this object is either of the two weapons */
-               setworn((struct obj *)0, obj->owornmask);
-               setworn(otmp, otmp->owornmask);
-               u.twoweap = save_twoweap;
-       }
-
-       /* replace obj with otmp */
-       replace_object(obj, otmp);
-
-       /* fix ocontainer pointers */
-       if (Has_contents(obj)) {
-               struct obj *inside;
-
-               for(inside = obj->cobj; inside; inside = inside->nobj)
-                       inside->ocontainer = otmp;
-       }
-
-       /* move timers and light sources from obj to otmp */
-       if (obj->timed) obj_move_timers(obj, otmp);
-       if (obj->lamplit) obj_move_light_source(obj, otmp);
-
-       /* objects possibly being manipulated by multi-turn occupations
-          which have been interrupted but might be subsequently resumed */
-       if (obj->oclass == FOOD_CLASS)
-           food_substitution(obj, otmp);       /* eat food or open tin */
-       else if (obj->oclass == SPBOOK_CLASS)
-           book_substitution(obj, otmp);       /* read spellbook */
-
-       /* obfree(obj, otmp);   now unnecessary: no pointers on bill */
-       dealloc_obj(obj);       /* let us hope nobody else saved a pointer */
-       return otmp;
-}
-
 struct obj *
 oname(obj, name)
 struct obj *obj;
@@ -462,13 +417,9 @@ const char *name;
        if (obj->oartifact || (lth && exist_artifact(obj->otyp, name)))
                return obj;
 
-       if (lth == obj->onamelth) {
-               /* no need to replace entire object */
-               if (lth) Strcpy(ONAME(obj), name);
-       } else {
-               obj = realloc_obj(obj, obj->oxlth,
-                             (genericptr_t)obj->oextra, lth, name);
-       }
+       new_oname(obj, lth);    /* removes old name if one is present */
+       if (lth) Strcpy(ONAME(obj), name);
+
        if (lth) artifact_exists(obj, name, TRUE);
        if (obj->oartifact) {
            /* can't dual-wield with artifact as secondary weapon */
@@ -543,8 +494,8 @@ register struct obj *obj;
        if (!obj->dknown) return; /* probably blind */
        otemp = *obj;
        otemp.quan = 1L;
-       otemp.onamelth = 0;
-       otemp.oxlth = 0;
+       otemp.oextra = (struct oextra *)0;
+
        if (objects[otemp.otyp].oc_class == POTION_CLASS && otemp.fromsink)
            /* kludge, meaning it's sink water */
            Sprintf(qbuf,"Call a stream of %s fluid:",
@@ -722,7 +673,7 @@ boolean called;
 
            Strcat(buf, rname);
            name_at_start = bogon_is_pname(rname);
-       } else if (has_name(mtmp)) {
+       } else if (has_mname(mtmp)) {
            char *name = MNAME(mtmp);
 
            if (mdat == &mons[PM_GHOST]) {
@@ -796,7 +747,7 @@ l_monnam(mtmp)
 register struct monst *mtmp;
 {
        return(x_monnam(mtmp, ARTICLE_NONE, (char *)0, 
-               (has_name(mtmp)) ? SUPPRESS_SADDLE : 0, TRUE));
+               (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, TRUE));
 }
 
 char *
@@ -804,7 +755,7 @@ mon_nam(mtmp)
 register struct monst *mtmp;
 {
        return(x_monnam(mtmp, ARTICLE_THE, (char *)0,
-               (has_name(mtmp)) ? SUPPRESS_SADDLE : 0, FALSE));
+               (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, FALSE));
 }
 
 /* print the name as if mon_nam() was called, but assume that the player
@@ -816,7 +767,7 @@ noit_mon_nam(mtmp)
 register struct monst *mtmp;
 {
        return(x_monnam(mtmp, ARTICLE_THE, (char *)0,
-               (has_name(mtmp)) ? (SUPPRESS_SADDLE|SUPPRESS_IT) :
+               (has_mname(mtmp)) ? (SUPPRESS_SADDLE|SUPPRESS_IT) :
                    SUPPRESS_IT, FALSE));
 }
 
@@ -856,7 +807,7 @@ struct monst *mtmp;
        int prefix, suppression_flag;
 
        prefix = mtmp->mtame ? ARTICLE_YOUR : ARTICLE_THE;
-       suppression_flag = (has_name(mtmp)
+       suppression_flag = (has_mname(mtmp)
 #ifdef STEED
                            /* "saddled" is redundant when mounted */
                            || mtmp == u.usteed
@@ -872,7 +823,7 @@ register struct monst *mtmp;
 register const char *adj;
 {
        register char *bp = x_monnam(mtmp, ARTICLE_THE, adj,
-               (has_name(mtmp)) ? SUPPRESS_SADDLE : 0, FALSE);
+               (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, FALSE);
 
        *bp = highc(*bp);
        return(bp);
@@ -883,7 +834,7 @@ a_monnam(mtmp)
 register struct monst *mtmp;
 {
        return x_monnam(mtmp, ARTICLE_A, (char *)0,
-               (has_name(mtmp)) ? SUPPRESS_SADDLE : 0, FALSE);
+               (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, FALSE);
 }
 
 char *
index d463ed0c6e681caadd5ccf36999f5c474749111c..4ba964f3455bc7679bd713033bd8306f629f7074 100644 (file)
--- a/src/dog.c
+++ b/src/dog.c
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)dog.c      3.5     2006/02/13      */
+/*     SCCS Id: @(#)dog.c      3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -129,7 +129,7 @@ boolean quietly;
                }
            }
            /* if figurine has been named, give same name to the monster */
-           if (otmp->onamelth)
+           if (has_oname(otmp))
                mtmp = christen_monst(mtmp, ONAME(otmp));
        }
        set_malign(mtmp); /* more alignment changes */
index 0cc70d910b4019b915da91c6231fbcdb3d26ca3c..e97914d3ceedb8866004c2b1cb86380873e780ac 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)dothrow.c  3.5     2006/04/05      */
+/*     SCCS Id: @(#)dothrow.c  3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -1473,7 +1473,7 @@ register struct obj *obj;
                        goto nopick;
                }
        /* making guesses */
-       } else if(obj->onamelth || objects[obj->otyp].oc_uname) {
+       } else if(has_oname(obj) || objects[obj->otyp].oc_uname) {
                if(is_gem) {
                        if(is_buddy) {
                                Strcat(buf,addluck);
index dc5d9672314a300358c6520ef6e5c33a450941d3..ee2f0d14610a4229ef5d91eb03b410012153e89c 100644 (file)
--- a/src/eat.c
+++ b/src/eat.c
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)eat.c      3.5     2006/02/22      */
+/*     SCCS Id: @(#)eat.c      3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -297,9 +297,9 @@ register struct obj *otmp;
                dropy(otmp);
                sellobj_state(SELL_NORMAL);
            } else {
-               otmp->oxlth++;          /* hack to prevent merge */
+               newolong(otmp);         /* hack to prevent merge */
                otmp = addinv(otmp);
-               otmp->oxlth--;
+               free_olong(otmp);
            }
        }
        return(otmp);
index cb1dbc2363d7ea96f4aca8453bc93a36391a565a..e6d02c0acce33e54b8030807a0c884e463b2f7fd 100644 (file)
--- a/src/end.c
+++ b/src/end.c
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)end.c      3.5     2005/11/02      */
+/*     SCCS Id: @(#)end.c      3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -204,7 +204,7 @@ register struct monst *mtmp;
            killer.format = KILLED_BY;
        }
        /* _the_ <invisible> <distorted> ghost of Dudley */
-       if (mtmp->data == &mons[PM_GHOST] && has_name(mtmp)) {
+       if (mtmp->data == &mons[PM_GHOST] && has_mname(mtmp)) {
                Strcat(buf, "the ");
                killer.format = KILLED_BY;
        }
@@ -215,7 +215,7 @@ register struct monst *mtmp;
 
        if(mtmp->data == &mons[PM_GHOST]) {
                Strcat(buf, "ghost");
-               if (has_name(mtmp)) Sprintf(eos(buf), " of %s", MNAME(mtmp));
+               if (has_mname(mtmp)) Sprintf(eos(buf), " of %s", MNAME(mtmp));
        } else if(mtmp->isshk) {
                const char *shknm = shkname(mtmp),
                           *honorific = shkname_is_pname(mtmp) ? "" :
@@ -229,7 +229,7 @@ register struct monst *mtmp;
                Strcat(buf, m_monnam(mtmp));
        } else {
                Strcat(buf, mtmp->data->mname);
-               if (has_name(mtmp))
+               if (has_mname(mtmp))
                    Sprintf(eos(buf), " called %s", MNAME(mtmp));
        }
 
@@ -888,7 +888,7 @@ die:
                        makeknown(otmp->otyp);
                        otmp->known = 1;        /* for fake amulets */
                        otmp->dknown = 1;       /* seen it (blindness fix) */
-                       otmp->onamelth = 0;
+                       if (has_oname(otmp)) free_oname(otmp);
                        otmp->quan = count;
                        Sprintf(pbuf, "%8ld %s (worth %ld %s),",
                                count, xname(otmp),
index bae65c6fd6e9dc9da34f3d65f23cf458ebbf6c4f..7de82850b7e5eee484d3cea9f35bd6773a5c70d3 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)invent.c   3.5     2006/04/10      */
+/*     SCCS Id: @(#)invent.c   3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -172,7 +172,7 @@ struct obj **potmp, **pobj;
 #endif
                if (otmp->oclass == COIN_CLASS) otmp->owt = weight(otmp);
                else otmp->owt += obj->owt;
-               if(!otmp->onamelth && obj->onamelth)
+               if(!has_oname(otmp) && has_oname(obj))
                        otmp = *potmp = oname(otmp, ONAME(obj));
                obj_extract_self(obj);
 
@@ -2393,6 +2393,7 @@ STATIC_OVL boolean
 mergable(otmp, obj)    /* returns TRUE if obj  & otmp can be merged */
        register struct obj *otmp, *obj;
 {
+       int objnamelth = 0, otmpnamelth = 0;
        if (obj->otyp != otmp->otyp) return FALSE;
 #ifdef GOLDOBJ
        /* coins of the same kind will always merge */
@@ -2448,15 +2449,19 @@ mergable(otmp, obj)     /* returns TRUE if obj  & otmp can be merged */
            return FALSE;
 
        /* if they have names, make sure they're the same */
-       if ( (obj->onamelth != otmp->onamelth &&
-               ((obj->onamelth && otmp->onamelth) || obj->otyp == CORPSE)
+       if (has_oname(obj)) objnamelth = strlen(ONAME(obj));
+       if (has_oname(otmp)) otmpnamelth = strlen(ONAME(otmp));
+       if ( (objnamelth != otmpnamelth &&
+               ((objnamelth && otmpnamelth) || obj->otyp == CORPSE)
             ) ||
-           (obj->onamelth && otmp->onamelth &&
-                   strncmp(ONAME(obj), ONAME(otmp), (int)obj->onamelth)))
+           (objnamelth && otmpnamelth &&
+                   strncmp(ONAME(obj), ONAME(otmp), objnamelth)))
                return FALSE;
 
        /* for the moment, any additional information is incompatible */
-       if (obj->oxlth || otmp->oxlth) return FALSE;
+       if (has_omonst(obj) || has_omid(obj) || has_olong(obj) ||
+           has_omonst(otmp) || has_omid(otmp) || has_olong(otmp))
+               return FALSE;
 
        if(obj->oartifact != otmp->oartifact) return FALSE;
 
@@ -2835,15 +2840,20 @@ doorganize()    /* inventory organizer by Del Lamb */
                   if destination is compatible, do merge with it,
                   otherwise bump whatever is there to an open slot */
                if (otmp->invlet == let) {
-                   int olth = obj->onamelth;
+                   int olth = 0;
 
+                   if (has_oname(obj)) olth = strlen(ONAME(obj));
                    /* ugly hack:  if these objects aren't going to merge
                       solely because they have conflicting user-assigned
                       names, strip off the name of the one being moved */
                    if (olth && !obj->oartifact && !mergable(otmp, obj)) {
-                       obj->onamelth = 0;
+                       char *holdname = ONAME(obj);
+                       ONAME(obj) = (char *)0;
                        /* restore name iff merging is still not possible */
-                       if (!mergable(otmp, obj)) obj->onamelth = olth;
+                       if (!mergable(otmp, obj)) {
+                               ONAME(obj) = holdname;
+                               holdname = (char *)0;
+                       } else free((genericptr_t)holdname);
                    }
 
                    if (merged(&otmp, &obj)) {
index 216161105b4328c4d99be51aec26928958c87aec..89833909961b351190faa636c4a76dc5911d046e 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)mail.c     3.5     2002/01/13      */
+/*     SCCS Id: @(#)mail.c     3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -355,6 +355,7 @@ md_rush(md,tx,ty)
     return TRUE;
 }
 
+
 /* Deliver a scroll of mail. */
 /*ARGSUSED*/
 STATIC_OVL void
@@ -382,14 +383,19 @@ struct mail_info *info;
            verbalize("Catch!");
        display_nhwindow(WIN_MESSAGE, FALSE);
        if (info->object_nam) {
-           obj = oname(obj, info->object_nam);
+           char *buf[BUFSZ];
+           Strncpy(buf, info->object_nam, BUFSZ - 1);
+           buf[BUFSZ - 1] = '\0';
            if (info->response_cmd) {   /*(hide extension of the obj name)*/
                int namelth = info->response_cmd - info->object_nam - 1;
-               if ( namelth <= 0 || namelth >= (int) obj->onamelth )
+               if ( namelth <= 0 )
                    impossible("mail delivery screwed up");
-               else
-                   *(ONAME(obj) + namelth) = '\0';
-               /* Note: renaming object will discard the hidden command. */
+               else {
+                   *(buf + namelth) = '\0';
+                   obj = oname(obj, buf);
+                   new_omailcmd(obj, info->response_cmd);
+               }
+               /* Note: renaming object won't discard the hidden cmd anymore. */
            }
        }
        obj = hold_another_object(obj, "Oops!",
@@ -548,10 +554,12 @@ struct obj *otmp;
     char *p, buf[BUFSZ], qbuf[BUFSZ];
     int len;
 
-    /* there should be a command hidden beyond the object name */
-    txt = otmp->onamelth ? ONAME(otmp) : "";
+    /* there should be a command in OMAILCMD */
+    if (has_oname(otmp)) txt = ONAME(otmp);
+    else txt = "";
     len = strlen(txt);
-    cmd = (len + 1 < otmp->onamelth) ? txt + len + 1 : (char *) 0;
+    if (has_omailcmd(otmp))
+       cmd = OMAILCMD(otmp);
     if (!cmd || !*cmd) cmd = "SPAWN";
 
     Sprintf(qbuf, "System command (%s)", cmd);
index 6984d593eb3062e818048b5722b0a31d3168cacd..49d8197f188b00ce304460088a206e684bb61d37 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)makemon.c  3.5     2006/03/11      */
+/*     SCCS Id: @(#)makemon.c  3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -717,7 +717,7 @@ xchar x, y; /* clone's preferred location or 0 (near mon) */
        if (emits_light(m2->data))
            new_light_source(m2->mx, m2->my, emits_light(m2->data),
                             LS_MONSTER, (genericptr_t)m2);
-       if (has_name(mon)) {
+       if (has_mname(mon)) {
                m2 = christen_monst(m2, MNAME(mon));
        } else if (mon->isshk) {
                m2 = christen_monst(m2, shkname(mon));
index 66ce21b9b27930699b7ddf0c4b486312c8edc60a..b31d0afa39cdace90c2527ff114a291c57b92c1c 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)mkobj.c    3.5     2006/01/07      */
+/*     SCCS Id: @(#)mkobj.c    3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -73,6 +73,119 @@ const struct icp hellprobs[] = {
 { 4, AMULET_CLASS}
 };
 
+struct oextra *
+newoextra()
+{
+       struct oextra *oextra;
+       oextra = (struct oextra *)alloc(sizeof(struct oextra));
+       if (oextra)
+           (void) memset((genericptr_t)oextra, 0, sizeof(struct oextra));
+       return oextra;
+}
+
+void
+dealloc_oextra(x)
+struct oextra *x;
+{
+       if (x) {
+               if (x->oname) free((genericptr_t)x->oname);
+               if (x->omonst) free((genericptr_t)x->omonst);
+               if (x->omid) free((genericptr_t)x->omid);
+               if (x->olong) free((genericptr_t)x->olong);
+               if (x->omailcmd) free((genericptr_t)x->omailcmd);
+               free((genericptr_t)x);
+       }
+}
+
+void
+newomonst(otmp)
+struct obj *otmp;
+{
+       if (!otmp->oextra) otmp->oextra = newoextra();
+       if (!OMONST(otmp)) {
+           OMONST(otmp) = (struct monst *)alloc(sizeof(struct monst));
+           (void) memset((genericptr_t) OMONST(otmp), 0, sizeof(struct monst));
+       }
+}
+
+void
+free_omonst(otmp)
+struct obj *otmp;
+{
+       if (otmp->oextra && OMONST(otmp)) {
+               free((genericptr_t) OMONST(otmp));
+               OMONST(otmp) = (struct monst *)0;
+       }
+}
+
+void
+newomid(otmp)
+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));
+       }
+}
+
+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;
+       }
+}
+
+void
+new_omailcmd(otmp,response_cmd)
+struct obj *otmp;
+char *response_cmd;
+{
+       if (!otmp->oextra) otmp->oextra = newoextra();
+       if (!OMAILCMD(otmp)) {
+           unsigned lth = strlen(response_cmd) + 1;
+           OMAILCMD(otmp) = (char *)alloc(lth);
+           if (OMAILCMD(otmp)) {
+               (void) memset((genericptr_t)OMAILCMD(otmp), 0, lth);
+               Strcpy(OMAILCMD(otmp), response_cmd);
+           }
+       }
+}
+
+void
+free_omailcmd(otmp)
+struct obj *otmp;
+{
+       if (otmp->oextra && OMAILCMD(otmp)) {
+               free((genericptr_t) OMAILCMD(otmp));
+               OMAILCMD(otmp) = (char *)0;
+       }
+}
+
 struct obj *
 mkobj_at(let, x, y, artif)
 char let;
@@ -212,6 +325,47 @@ rndmonnum()        /* select a random, common monster type */
        return(i);
 }
 
+void
+copy_oextra(obj2, obj1)
+struct obj *obj2, *obj1;
+{
+       if(!obj2 || !obj1 || !obj1->oextra) return;
+
+       if (!obj2->oextra) obj2->oextra = newoextra();
+       if (has_oname(obj1)) oname(obj2, ONAME(obj1));
+       if (has_omonst(obj1)) {
+               if (!OMONST(obj2)) newomonst(obj2);
+               (void)memcpy((genericptr_t)OMONST(obj2),
+                               (genericptr_t)OMONST(obj1),
+                               sizeof(struct monst));
+               OMONST(obj2)->mextra = (struct mextra *)0;
+               OMONST(obj2)->nmon = (struct monst *)0;
+#if 0
+               OMONST(obj2)->m_id = context.ident++;
+               if (OMONST(obj2)->m_id) /* ident overflowed */
+                       OMONST(obj2)->m_id = context.ident++;
+#endif
+               if (OMONST(obj1)->mextra)
+                       copy_mextra(OMONST(obj2),OMONST(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)) {
+               if (!OMAILCMD(obj2)) new_omailcmd(obj2, OMAILCMD(obj1));
+       }
+}
+
 /*
  * Split obj so that it gets size gets reduced by num. The quantity num is
  * put in the object structure delivered by this call.  The returned object
@@ -227,8 +381,9 @@ long num;
 
        if (obj->cobj || num <= 0L || obj->quan <= num)
            panic("splitobj");  /* can't split containers */
-       otmp = newobj(obj->oxlth + obj->onamelth);
+       otmp = newobj();
        *otmp = *obj;           /* copies whole structure */
+       otmp->oextra = (struct oextra *)0;
        otmp->o_id = context.ident++;
        if (!otmp->o_id) otmp->o_id = context.ident++;  /* ident overflowed */
        otmp->timed = 0;        /* not timed, yet */
@@ -243,11 +398,8 @@ long num;
        /* as a back pointer to the container object when contained. */
        if (obj->where == OBJ_FLOOR)
            obj->nexthere = otmp;
-       if (obj->oxlth)
-           (void)memcpy((genericptr_t)otmp->oextra, (genericptr_t)obj->oextra,
-                       obj->oxlth);
-       if (obj->onamelth)
-           (void)strncpy(ONAME(otmp), ONAME(obj), (int)obj->onamelth);
+       copy_oextra(otmp, obj);
+       if (has_omid(otmp)) free_omid(otmp);    /* only one association with m_id*/
        if (obj->unpaid) splitbill(obj,otmp);
        if (obj->timed) obj_split_timers(obj, otmp);
        if (obj_sheds_light(obj)) obj_split_light_source(obj, otmp);
@@ -333,17 +485,15 @@ register struct obj *otmp;
 
        if (otmp->unpaid)
            subfrombill(otmp, shop_keeper(*u.ushops));
-       dummy = newobj(otmp->oxlth + otmp->onamelth);
+       dummy = newobj();
        *dummy = *otmp;
+       dummy->oextra = (struct oextra *)0;
        dummy->where = OBJ_FREE;
        dummy->o_id = context.ident++;
        if (!dummy->o_id) dummy->o_id = context.ident++;        /* ident overflowed */
        dummy->timed = 0;
-       if (otmp->oxlth)
-           (void)memcpy((genericptr_t)dummy->oextra,
-                       (genericptr_t)otmp->oextra, otmp->oxlth);
-       if (otmp->onamelth)
-           (void)strncpy(ONAME(dummy), ONAME(otmp), (int)otmp->onamelth);
+       copy_oextra(dummy, otmp);
+       if (has_omid(dummy)) free_omid(dummy);  /* only one association with m_id*/
        if (Is_candle(dummy)) dummy->lamplit = 0;
        addtobill(dummy, FALSE, TRUE, TRUE);
        /* no_charge is only valid for some locations */
@@ -445,7 +595,7 @@ boolean artif;
        struct obj *otmp;
        char let = objects[otyp].oc_class;
 
-       otmp = newobj(0);
+       otmp = newobj();
        *otmp = zeroobj;
        otmp->age = monstermoves;
        otmp->o_id = context.ident++;
@@ -1027,7 +1177,7 @@ struct obj *obj;
 {
        int revivetype;
        struct monst *mtmp;
-       if (obj->oxlth && obj->oattached == OATTACHED_MONST &&
+       if (has_omonst(obj) &&
                ((mtmp = get_mtraits(obj, FALSE)) != (struct monst *)0)) {
            /* mtmp is a temporary pointer to a monster's stored
                attributes, not a real monster */
@@ -1046,22 +1196,10 @@ obj_attach_mid(obj, mid)
 struct obj *obj;
 unsigned mid;
 {
-    struct obj *otmp;
-    int lth, namelth;
-
     if (!mid || !obj) return (struct obj *)0;
-    lth = sizeof(mid);
-    namelth = obj->onamelth ? strlen(ONAME(obj)) + 1 : 0;
-    if (namelth) 
-       otmp = realloc_obj(obj, lth, (genericptr_t) &mid, namelth, ONAME(obj));
-    else {
-       otmp = obj;
-       otmp->oxlth = sizeof(mid);
-       (void) memcpy((genericptr_t)otmp->oextra, (genericptr_t)&mid,
-                                                               sizeof(mid));
-    }
-    if (otmp && otmp->oxlth) otmp->oattached = OATTACHED_M_ID; /* mark it */
-    return otmp;
+    newomid(obj);
+    *OMID(obj) = mid;
+    return obj;
 }
 
 static struct obj *
@@ -1069,17 +1207,12 @@ save_mtraits(obj, mtmp)
 struct obj *obj;
 struct monst *mtmp;
 {
-       struct obj *otmp;
-       genericptr_t buffer;
-       int lth, namelth;
-
-       namelth = obj->onamelth ? strlen(ONAME(obj)) + 1 : 0;
        if (mtmp->ispriest) forget_temple_entry(mtmp);  /* EPRI() */
-       buffer = mon_to_buffer(mtmp, &lth);
-       otmp = realloc_obj(obj, lth, buffer, namelth, ONAME(obj));
-       free(buffer);
-       if (otmp && otmp->oxlth) {
-               struct monst *mtmp2 = (struct monst *)otmp->oextra;
+       if (!has_omonst(obj)) newomonst(obj);
+       if (has_omonst(obj)) {
+               struct monst *mtmp2 = OMONST(obj);
+               *mtmp2 = *mtmp;
+               mtmp2->mextra = (struct mextra *)0;
                if (mtmp->data) mtmp2->mnum = monsndx(mtmp->data);
                /* invalidate pointers */
                /* m_id is needed to know if this is a revived quest leader */
@@ -1087,14 +1220,13 @@ struct monst *mtmp;
                mtmp2->nmon     = (struct monst *)0;
                mtmp2->data     = (struct permonst *)0;
                mtmp2->minvent  = (struct obj *)0;
-               /* mon_to_buffer() took care of mextra */
+               if (mtmp->mextra) copy_mextra(mtmp2, mtmp);
 #ifndef GOLDOBJ
                /* not a pointer but is discarded along with minvent */
                mtmp2->mgold    = 0L;
 #endif
-               otmp->oattached = OATTACHED_MONST;      /* mark it */
        }
-       return otmp;
+       return obj;
 }
 
 /* returns a pointer to a new monst structure based on
@@ -1108,11 +1240,13 @@ boolean copyof;
        struct monst *mtmp = (struct monst *)0;
        struct monst *mnew = (struct monst *)0;
 
-       if (obj->oxlth && obj->oattached == OATTACHED_MONST)
-               mtmp = (struct monst *)obj->oextra;
+       if (has_omonst(obj)) mtmp = OMONST(obj);
        if (mtmp) {
            if (copyof) {
-               mnew = buffer_to_mon((genericptr_t)mtmp);
+               mnew = newmonst();
+               *mnew = *mtmp;
+               mnew->mextra = (struct mextra *)0;
+               if (mtmp->mextra) copy_mextra(mnew, mtmp);
            } else {
              /* Never insert this returned pointer into mon chains! */
                mnew = mtmp;
@@ -1597,6 +1731,7 @@ dealloc_obj(obj)
 
     if (obj == thrownobj) thrownobj = (struct obj*)0;
 
+    if (obj->oextra) dealloc_oextra(obj->oextra);
     free((genericptr_t) obj);
 }
 
index a9e2890b74d766c0b4d3c9baab19a806703c1779..15c4395a95d918e191c5fa23a7c17b4e87d0c482 100644 (file)
--- a/src/mon.c
+++ b/src/mon.c
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)mon.c      3.5     2006/03/24      */
+/*     SCCS Id: @(#)mon.c      3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -298,7 +298,7 @@ unsigned corpseflags;
           prevent the same attack beam from hitting its corpse */
        if (context.bypasses) bypass_obj(obj);
 
-       if (has_name(mtmp))
+       if (has_mname(mtmp))
            obj = oname(obj, MNAME(mtmp));
 
        /* Avoid "It was hidden under a green mold corpse!" 
@@ -1347,6 +1347,52 @@ register struct monst *mon;
        }
 }
 
+void
+copy_mextra(mtmp2, mtmp1)
+struct monst *mtmp2, *mtmp1;
+{
+       if(!mtmp2 || !mtmp1 || !mtmp1->mextra) return;
+
+       if (!mtmp2->mextra) mtmp2->mextra = newmextra();
+       if (MNAME(mtmp1)) {
+               int lth = strlen(MNAME(mtmp1)) + 1;
+               if (lth) {
+                       new_mname(mtmp2, lth);
+                       Strcpy(MNAME(mtmp2), MNAME(mtmp1));
+               }
+       }
+       if (EGD(mtmp1)) {
+               if (!EGD(mtmp2)) newegd(mtmp2);
+               (void)memcpy((genericptr_t)EGD(mtmp2),
+                               (genericptr_t)EGD(mtmp1),
+                               sizeof(struct egd));
+       }
+       if (EPRI(mtmp1)) {
+               if (!EPRI(mtmp2)) newepri(mtmp2);
+               (void)memcpy((genericptr_t)EPRI(mtmp2),
+                               (genericptr_t)EPRI(mtmp1),
+                               sizeof(struct epri));
+       }
+       if (ESHK(mtmp1)) {
+               if (!ESHK(mtmp2)) neweshk(mtmp2);
+               (void)memcpy((genericptr_t)ESHK(mtmp2),
+                               (genericptr_t)ESHK(mtmp1),
+                               sizeof(struct eshk));
+       }
+       if (EMIN(mtmp1)) {
+               if (!EMIN(mtmp2)) newemin(mtmp2);
+               (void)memcpy((genericptr_t)EMIN(mtmp2),
+                               (genericptr_t)EMIN(mtmp1),
+                               sizeof(struct emin));
+       }
+       if (EDOG(mtmp1)) {
+               if (!EDOG(mtmp2)) newedog(mtmp2);
+               (void)memcpy((genericptr_t)EDOG(mtmp2),
+                               (genericptr_t)EDOG(mtmp1),
+                               sizeof(struct edog));
+       }
+}
+
 STATIC_OVL void
 dealloc_mextra(x)
 struct mextra *x;
@@ -1727,7 +1773,7 @@ register struct monst *mdef;
                   so that saved monster traits won't retain any stale
                   item-conferred attributes */
                otmp = mkcorpstat(STATUE, mdef, mdef->data, x, y, CORPSTAT_NONE);
-               if (has_name(mdef)) otmp = oname(otmp, MNAME(mdef));
+               if (has_mname(mdef)) otmp = oname(otmp, MNAME(mdef));
                while ((obj = oldminvent) != 0) {
                    oldminvent = obj->nobj;
                    (void) add_to_container(otmp, obj);
@@ -1848,9 +1894,9 @@ int dest;
                You("%s %s!", verb,
                    !mtmp->mtame ? mon_nam(mtmp) :
                        x_monnam(mtmp,
-                                (has_name(mtmp)) ? ARTICLE_NONE : ARTICLE_THE,
+                                (has_mname(mtmp)) ? ARTICLE_NONE : ARTICLE_THE,
                                 "poor",
-                                (has_name(mtmp)) ? SUPPRESS_SADDLE : 0,
+                                (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0,
                                 FALSE));
            }
        }
@@ -2509,7 +2555,7 @@ boolean msg;              /* "The oldmon turns into a newmon!" */
                if(!rn2(10)) mtmp->female = !mtmp->female;
        }
 
-       if (In_endgame(&u.uz) && is_mplayer(olddata) && has_name(mtmp)) {
+       if (In_endgame(&u.uz) && is_mplayer(olddata) && has_mname(mtmp)) {
                /* mplayers start out as "Foo the Bar", but some of the
                 * titles are inappropriate when polymorphed, particularly
                 * into the opposite sex.  players don't use ranks when
@@ -2604,7 +2650,7 @@ boolean msg;              /* "The oldmon turns into a newmon!" */
        if (msg) {
            char *save_mname = 0;
 
-           if (has_name(mtmp)) {
+           if (has_mname(mtmp)) {
                save_mname = MNAME(mtmp);
                MNAME(mtmp) = (char *)0; 
            }
index 6a758444b35ccc1b0974157b5749c978694d9c52..c96cff13a1d3cd9afb16fb2b721357fec58f0cfc 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)mplayer.c  3.5     1997/02/04      */
+/*     SCCS Id: @(#)mplayer.c  3.5     2006/04/14      */
 /*     Copyright (c) Izchak Miller, 1992.                        */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -51,7 +51,7 @@ dev_name()
            for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
                if(!is_mplayer(mtmp->data)) continue;
                if(!strncmp(developers[i],
-                            (has_name(mtmp)) ? MNAME(mtmp) : "",
+                            (has_mname(mtmp)) ? MNAME(mtmp) : "",
                              strlen(developers[i]))) {
                    match = TRUE;
                    break;
index e45d6e117c69058d9a44fcd6cd0c47252006c732..e250ae4a77598ec6e6620f0f7b688ff0afe68768 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)music.c    3.5     2003/05/25      */
+/*     SCCS Id: @(#)music.c    3.5     2006/04/14      */
 /*     Copyright (c) 1989 by Jean-Christophe Collet */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -330,7 +330,7 @@ do_pit:                 chasm = maketrap(x,y,PIT);
                                    else {
                                        You("destroy %s!", mtmp->mtame ?
                                            x_monnam(mtmp, ARTICLE_THE, "poor",
-                               (has_name(mtmp)) ? SUPPRESS_SADDLE : 0, FALSE):
+                               (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, FALSE):
                                            mon_nam(mtmp));
                                    }
                                    xkilled(mtmp,0);
index a3acb6c58d46e6e47124830a97a2484fe91f5c81..80cf59b54eeb55d2b767837ea35e2008d4f856f8 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)objnam.c   3.5     2005/12/07      */
+/*     SCCS Id: @(#)objnam.c   3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -168,7 +168,7 @@ obj_is_pname(obj)
 register struct obj *obj;
 {
     return((boolean)(
-       ((obj->dknown && obj->known) || iflags.override_ID) && obj->onamelth &&
+       ((obj->dknown && obj->known) || iflags.override_ID) && has_oname(obj) &&
                /* Since there aren't any objects which are both
                   artifacts and unique, the last check is redundant. */
                obj->oartifact && !objects[obj->otyp].oc_unique));
@@ -468,7 +468,7 @@ register struct obj *obj;
        }
        if (pluralize) Strcpy(buf, makeplural(buf));
 
-       if (obj->onamelth && dknown) {
+       if (has_oname(obj) && dknown) {
                Strcat(buf, " named ");
 nameit:
                Strcat(buf, ONAME(obj));
@@ -978,12 +978,14 @@ struct obj *obj;
 {
     struct obj save_obj;
     unsigned save_ocknown;
-    char *buf, *save_ocuname;
+    char *buf, *save_ocuname, *save_oname = (char *)0;
 
     /* remember original settings for core of the object;
-       oname and oattached extensions don't matter here--since they
+       oextra structs other than oname don't matter here--since they
        aren't modified they don't need to be saved and restored */
     save_obj = *obj;
+    if (has_oname(obj)) save_oname = ONAME(obj);
+
     /* killer name should be more specific than general xname; however, exact
        info like blessed/cursed and rustproof makes things be too verbose */
     obj->known = obj->dknown = 1;
@@ -996,7 +998,7 @@ struct obj *obj;
        be redundant when it is, so suppress "poisoned" prefix */
     obj->opoisoned = 0;
     /* strip user-supplied name; artifacts keep theirs */
-    if (!obj->oartifact) obj->onamelth = 0;
+    if (!obj->oartifact && save_oname) ONAME(obj) = (char *)0;
     /* temporarily identify the type of object */
     save_ocknown = objects[obj->otyp].oc_name_known;
     objects[obj->otyp].oc_name_known = 1;
@@ -1023,6 +1025,7 @@ struct obj *obj;
     objects[obj->otyp].oc_name_known = save_ocknown;
     objects[obj->otyp].oc_uname = save_ocuname;
     *obj = save_obj;   /* restore object's core settings */
+    if (!obj->oartifact && save_oname) ONAME(obj) = save_oname;
 
     return buf;
 }
@@ -2939,7 +2942,10 @@ typfnd:
            && !wizard
 #endif
            ) {
-           artifact_exists(otmp, ONAME(otmp), FALSE);
+           char *tnam = "";
+           if (has_oname(otmp))
+               tnam = ONAME(otmp);
+           artifact_exists(otmp, tnam, FALSE);
            obfree(otmp, (struct obj *) 0);
            otmp = &zeroobj;
            pline("For a moment, you feel %s in your %s, but it disappears!",
index 679a0387375101c4eb2ca6371d07620927a13931..4fce54477dc3948f17e1ae43649c894cdb2801d7 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)pray.c     3.5     2006/03/01      */
+/*     SCCS Id: @(#)pray.c     3.5     2006/04/14      */
 /* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -1265,7 +1265,7 @@ dosacrifice()
            if (carried(otmp)) useup(otmp);
            else useupf(otmp, 1L);
            return(1);
-       } else if (otmp->oxlth && otmp->oattached == OATTACHED_MONST
+       } else if (has_omonst(otmp)
                    && ((mtmp = get_mtraits(otmp, FALSE)) != (struct monst *)0)
                    && mtmp->mtame) {
            /* mtmp is a temporary pointer to a tame monster's attributes,
index 1ce663fb689b0ba5f4aea3854cd4bf6622f7f594..4a0deb067266ac21f7279b58fc72a6716e0972c8 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)read.c     3.5     2006/02/15      */
+/*     SCCS Id: @(#)read.c     3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -1966,7 +1966,7 @@ struct obj *from_obj;
                *mtype = PM_LONG_WORM;
                return TRUE;
        } else if (unique_corpstat(&mons[*mtype]) &&
-                   (!from_obj || from_obj->oattached != OATTACHED_MONST)) {
+                   (!from_obj || !has_omonst(from_obj))) {
                /* unique corpses (from bones or wizard mode wish) or
                   statues (bones or any wish) end up as shapechangers */
                *mtype = PM_DOPPELGANGER;
index 5690967572246199d0053621fd555d77d506389d..8175ee9af88e4c35ceae842f8a6de39962a695d1 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)restore.c  3.5     2006/04/01      */
+/*     SCCS Id: @(#)restore.c  3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -27,7 +27,9 @@ STATIC_DCL void FDECL(def_mread, (int,genericptr_t,unsigned int));
 STATIC_DCL void NDECL(find_lev_obj);
 STATIC_DCL void FDECL(restlevchn, (int));
 STATIC_DCL void FDECL(restdamage, (int,BOOLEAN_P));
+STATIC_DCL void FDECL(restobj, (int, struct obj *));
 STATIC_DCL struct obj *FDECL(restobjchn, (int,BOOLEAN_P,BOOLEAN_P));
+STATIC_OVL void FDECL(restmon, (int, struct monst *));
 STATIC_DCL struct monst *FDECL(restmonchn, (int,BOOLEAN_P));
 STATIC_DCL struct fruit *FDECL(loadfruitchn, (int));
 STATIC_DCL void FDECL(freefruitchn, (struct fruit *));
@@ -219,6 +221,59 @@ boolean ghostly;
        free((genericptr_t)tmp_dam);
 }
 
+STATIC_OVL void
+restobj(fd, otmp)
+int fd;
+struct obj *otmp;
+{
+       int buflen;
+       
+       mread(fd, (genericptr_t) otmp, sizeof(struct obj));
+
+       /* any saved pointers are mostly invalid */
+       otmp->nobj = (struct obj *)0;
+       otmp->oextra = (struct oextra *)0;
+
+       /* read the length of the name and the name */
+       mread(fd, (genericptr_t) &buflen, sizeof(buflen));
+       if (buflen > 0) {
+               new_oname(otmp, buflen);
+               mread(fd, (genericptr_t) ONAME(otmp), buflen);
+       }
+
+       /* omonst */
+       mread(fd, (genericptr_t) &buflen, sizeof(buflen));
+       if (buflen > 0) {
+               newomonst(otmp);
+               /* this is actually a monst struct, so we
+                  can just defer to restmon() here */
+               restmon(fd, OMONST(otmp));
+       }
+
+       /* omid */
+       mread(fd, (genericptr_t) &buflen, sizeof(buflen));
+       if (buflen > 0) {
+               newomid(otmp);
+               mread(fd, (genericptr_t) OMID(otmp), buflen);
+       }
+
+       /* olong */
+       mread(fd, (genericptr_t) &buflen, sizeof(buflen));
+       if (buflen > 0) {
+               newolong(otmp);
+               mread(fd, (genericptr_t) OLONG(otmp), buflen);
+       }
+
+       /* omailcmd */
+       mread(fd, (genericptr_t) &buflen, sizeof(buflen));
+       if (buflen > 0) {
+               char *omailcmd = (char *)alloc(buflen);
+               mread(fd, (genericptr_t) omailcmd, buflen);
+               new_omailcmd(otmp, omailcmd);
+               free((genericptr_t)omailcmd);
+       }
+}
+
 STATIC_OVL struct obj *
 restobjchn(fd, ghostly, frozen)
 register int fd;
@@ -226,16 +281,17 @@ boolean ghostly, frozen;
 {
        register struct obj *otmp, *otmp2 = 0;
        register struct obj *first = (struct obj *)0;
-       int xl;
+       int buflen;
 
        while(1) {
-               mread(fd, (genericptr_t) &xl, sizeof(xl));
-               if(xl == -1) break;
-               otmp = newobj(xl);
+               mread(fd, (genericptr_t) &buflen, sizeof buflen);
+               if(buflen == -1) break;
+
+               otmp = newobj();
+               restobj(fd, otmp);
                if(!first) first = otmp;
                else otmp2->nobj = otmp;
-               mread(fd, (genericptr_t) otmp,
-                                       (unsigned) xl + sizeof(struct obj));
+
                if (ghostly) {
                    unsigned nid = context.ident++;
                    add_id_mapping(otmp->o_id, nid);
@@ -277,77 +333,65 @@ boolean ghostly, frozen;
        return(first);
 }
 
-/*
- * used by get_mtraits() in mkobj.c
- * to retrieve the bundled up OATTACHED_MONST info.
- */
-struct monst *
-buffer_to_mon(buffer)
-genericptr_t buffer;
+STATIC_OVL void
+restmon(fd, mtmp)
+int fd;
+struct monst *mtmp;
 {
-       int lth;
-       struct monst *mtmp;
-       char *spot = (char *)buffer;
+       int buflen;
 
-       mtmp = newmonst();
-       (void) memcpy((genericptr_t)mtmp, (genericptr_t)spot, sizeof(struct monst));
-       spot += sizeof(struct monst);
-       
-       /* obtain the stored length of the monster name */
-       (void) memcpy((genericptr_t)&lth, (genericptr_t)spot, sizeof(int));
-       spot += sizeof(int);
-       if (lth) {
-               new_mname(mtmp, lth);
-               (void) memcpy((genericptr_t)MNAME(mtmp),
-                               (genericptr_t)spot, lth);
-               spot += lth;
+       mread(fd, (genericptr_t) mtmp, sizeof(struct monst));
+
+       /* any saved pointers are mostly invalid */
+       mtmp->nmon = (struct monst *)0;
+       mtmp->mextra = (struct mextra *)0;
+
+       /* read the length of the name and the name */
+       mread(fd, (genericptr_t) &buflen, sizeof(buflen));
+       if (buflen > 0) {
+               new_mname(mtmp, buflen);
+               mread(fd, (genericptr_t) MNAME(mtmp), buflen);
        }
-       /* obtain the length of the egd (vault guard) structure */
-       (void) memcpy((genericptr_t)&lth, (genericptr_t)spot, sizeof(int));
-       spot += sizeof(int);
-       if (lth) {
+
+       /* egd */               
+       mread(fd, (genericptr_t) &buflen, sizeof(buflen));
+       if (buflen > 0) {
                newegd(mtmp);
-               (void) memcpy((genericptr_t)EGD(mtmp),
-                               (genericptr_t)spot, lth);
-               spot += lth;
+               mread(fd, (genericptr_t) EGD(mtmp),
+                               sizeof(struct egd));
        }
-       /* obtain the length of the epri (priest) structure */
-       (void) memcpy((genericptr_t)&lth, (genericptr_t)spot, sizeof(int));
-       spot += sizeof(int);
-       if (lth) {
+
+       /* epri */
+       mread(fd, (genericptr_t) &buflen, sizeof(buflen));
+       if (buflen > 0) {
                newepri(mtmp);
-               (void) memcpy((genericptr_t)EPRI(mtmp),
-                               (genericptr_t)spot, lth);
-               spot += lth;
+               mread(fd, (genericptr_t) EPRI(mtmp),
+                               sizeof(struct epri));
        }
-       /* obtain the length of the eshk (shopkeeper) structure */
-       (void) memcpy((genericptr_t)&lth, (genericptr_t)spot, sizeof(int));
-       spot += sizeof(int);
-       if (lth) {
+
+       /* eshk */
+       mread(fd, (genericptr_t) &buflen, sizeof(buflen));
+       if (buflen > 0) {
                neweshk(mtmp);
-               (void) memcpy((genericptr_t)ESHK(mtmp),
-                               (genericptr_t)spot, lth);
-               spot += lth;
+               mread(fd, (genericptr_t) ESHK(mtmp),
+                               sizeof(struct eshk));
        }
-       /* obtain the length of the emin (minion) structure */
-       (void) memcpy((genericptr_t)&lth, (genericptr_t)spot, sizeof(int));
-       spot += sizeof(int);
-       if (lth) {
+
+       /* emin */
+       mread(fd, (genericptr_t) &buflen, sizeof(buflen));
+       if (buflen > 0) {
                newemin(mtmp);
-               (void) memcpy((genericptr_t)EMIN(mtmp),
-                               (genericptr_t)spot, lth);
-               spot += lth;
+               mread(fd, (genericptr_t) EMIN(mtmp),
+                               sizeof(struct emin));
        }
-       /* obtain the length of the edog (mtame) structure */
-       (void) memcpy((genericptr_t)&lth, (genericptr_t)spot, sizeof(int));
-       spot += sizeof(int);
-       if (lth) {
+
+       /* edog */              
+       mread(fd, (genericptr_t) &buflen, sizeof(buflen));
+       if (buflen > 0) {
                newedog(mtmp);
-               (void) memcpy((genericptr_t)EDOG(mtmp),
-                               (genericptr_t)spot, lth);
-               spot += lth;    /* actually not necessary */
+               mread(fd, (genericptr_t) EDOG(mtmp),
+                               sizeof(struct edog));
        }
-       return mtmp;
 }
 
 STATIC_OVL struct monst *
@@ -362,60 +406,12 @@ boolean ghostly;
        while(1) {
                mread(fd, (genericptr_t) &buflen, sizeof(buflen));
                if(buflen == -1) break;
-               mtmp = newmonst();
-               mread(fd, (genericptr_t) mtmp, sizeof(struct monst));
-               /* any saved mextra pointer is invalid */
-               mtmp->mextra = (struct mextra *)0;
-
-               /* read the length of the name and the name */
-               mread(fd, (genericptr_t) &buflen, sizeof(buflen));
-               if (buflen > 0) {
-                       new_mname(mtmp, buflen);
-                       mread(fd, (genericptr_t) MNAME(mtmp), buflen);
-               }
-
-               /* egd */               
-               mread(fd, (genericptr_t) &buflen, sizeof(buflen));
-               if (buflen > 0) {
-                       newegd(mtmp);
-                       mread(fd, (genericptr_t) EGD(mtmp),
-                                       sizeof(struct egd));
-               }
-
-               /* epri */
-               mread(fd, (genericptr_t) &buflen, sizeof(buflen));
-               if (buflen > 0) {
-                       newepri(mtmp);
-                       mread(fd, (genericptr_t) EPRI(mtmp),
-                                       sizeof(struct epri));
-               }
-
-               /* eshk */
-               mread(fd, (genericptr_t) &buflen, sizeof(buflen));
-               if (buflen > 0) {
-                       neweshk(mtmp);
-                       mread(fd, (genericptr_t) ESHK(mtmp),
-                                       sizeof(struct eshk));
-               }
-
-               /* emin */
-               mread(fd, (genericptr_t) &buflen, sizeof(buflen));
-               if (buflen > 0) {
-                       newemin(mtmp);
-                       mread(fd, (genericptr_t) EMIN(mtmp),
-                                       sizeof(struct emin));
-               }
-
-               /* edog */              
-               mread(fd, (genericptr_t) &buflen, sizeof(buflen));
-               if (buflen > 0) {
-                       newedog(mtmp);
-                       mread(fd, (genericptr_t) EDOG(mtmp),
-                                       sizeof(struct edog));
-               }
 
+               mtmp = newmonst();
+               restmon(fd, mtmp);
                if(!first) first = mtmp;
                else mtmp2->nmon = mtmp;
+
                if (ghostly) {
                        unsigned nid = context.ident++;
                        add_id_mapping(mtmp->m_id, nid);
@@ -1190,20 +1186,21 @@ boolean ghostly;
     struct obj *otmp;
     unsigned oldid, nid;
     for (otmp = fobj; otmp; otmp = otmp->nobj) {
-       if (ghostly && otmp->oattached == OATTACHED_MONST && otmp->oxlth) {
-           struct monst *mtmp = (struct monst *)otmp->oextra;
+       if (ghostly && has_omonst(otmp)) {
+           struct monst *mtmp = OMONST(otmp);
 
            mtmp->m_id = 0;
            mtmp->mpeaceful = mtmp->mtame = 0;  /* pet's owner died! */
        }
-       if (ghostly && otmp->oattached == OATTACHED_M_ID) {
-           (void) memcpy((genericptr_t)&oldid, (genericptr_t)otmp->oextra,
+       if (ghostly && has_omid(otmp)) {
+           (void) memcpy((genericptr_t)&oldid, (genericptr_t)OMID(otmp),
                                                                sizeof(oldid));
            if (lookup_id_mapping(oldid, &nid))
-               (void) memcpy((genericptr_t)otmp->oextra, (genericptr_t)&nid,
+               (void) memcpy((genericptr_t)OMID(otmp), (genericptr_t)&nid,
                                                                sizeof(nid));
            else
-               otmp->oattached = OATTACHED_NOTHING;
+               free_omid(otmp);
+
        }
     }
 }
index 22a57d27800d7d96c2dd621baf4ebf3b42d143c8..8c5437fe168a4e5c4fb9822e799e255f2d837eb2 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)save.c     3.5     2005/12/14      */
+/*     SCCS Id: @(#)save.c     3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -23,7 +23,9 @@ int dotcnt, dotrow;   /* also used in restore */
 
 STATIC_DCL void FDECL(savelevchn, (int,int));
 STATIC_DCL void FDECL(savedamage, (int,int));
+STATIC_DCL void FDECL(saveobj, (int,struct obj *));
 STATIC_DCL void FDECL(saveobjchn, (int,struct obj *,int));
+STATIC_DCL void FDECL(savemon, (int,struct monst *));
 STATIC_DCL void FDECL(savemonchn, (int,struct monst *,int));
 STATIC_DCL void FDECL(savetrapchn, (int,struct trap *,int));
 STATIC_DCL void FDECL(savegamestate, (int,int));
@@ -945,21 +947,66 @@ register int fd, mode;
            level.damagelist = 0;
 }
 
+STATIC_OVL void
+saveobj(fd, otmp)
+int fd;
+struct obj *otmp;
+{
+       int buflen, zerobuf = 0;
+
+       buflen = sizeof(struct obj);
+       bwrite(fd, (genericptr_t) &buflen, sizeof(int));
+       bwrite(fd, (genericptr_t) otmp, buflen);
+       if (!otmp->oextra) {
+               /* for oname, omonst, omid, olong, omailcmd */
+               bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
+               bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
+               bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
+               bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
+               bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
+       } else {
+               if (ONAME(otmp)) buflen = strlen(ONAME(otmp)) + 1;
+               else buflen = 0;
+               bwrite(fd, (genericptr_t) &buflen, sizeof buflen);
+               if (buflen > 0)
+                       bwrite(fd, (genericptr_t) ONAME(otmp), buflen);
+
+               /* defer to savemon() for this one */
+               if (OMONST(otmp)) savemon(fd, OMONST(otmp));
+               else bwrite(fd, (genericptr_t) &zerobuf, sizeof zerobuf);
+
+               if (OMID(otmp)) buflen = sizeof(unsigned);
+               else buflen = 0;
+               bwrite(fd, (genericptr_t) &buflen, sizeof buflen);
+               if (buflen > 0)
+                       bwrite(fd, (genericptr_t) OMID(otmp), buflen);
+
+               if (OLONG(otmp)) buflen = sizeof(long);
+               else buflen = 0;
+               bwrite(fd, (genericptr_t) &buflen, sizeof buflen);
+               if (buflen > 0)
+                       bwrite(fd, (genericptr_t) OLONG(otmp), buflen);
+
+               if (OMAILCMD(otmp)) buflen = strlen(OMAILCMD(otmp)) + 1;
+               else buflen = 0;
+               bwrite(fd, (genericptr_t) &buflen, sizeof buflen);
+               if (buflen > 0)
+                       bwrite(fd, (genericptr_t) OMAILCMD(otmp), buflen);
+       }
+}
+
 STATIC_OVL void
 saveobjchn(fd, otmp, mode)
 register int fd, mode;
 register struct obj *otmp;
 {
        register struct obj *otmp2;
-       unsigned int xl;
        int minusone = -1;
 
        while(otmp) {
            otmp2 = otmp->nobj;
            if (perform_bwrite(mode)) {
-               xl = otmp->oxlth + otmp->onamelth;
-               bwrite(fd, (genericptr_t) &xl, sizeof(int));
-               bwrite(fd, (genericptr_t) otmp, xl + sizeof(struct obj));
+               saveobj(fd, otmp);
            }
            if (Has_contents(otmp))
                saveobjchn(fd,otmp->cobj,mode);
@@ -1004,81 +1051,60 @@ register struct obj *otmp;
            bwrite(fd, (genericptr_t) &minusone, sizeof(int));
 }
 
-/*
- * Used by save_mtraits() in mkobj.c to ensure
- * that all the monst related information is stored in
- * an OATTACHED_MONST structure.
- */
-genericptr_t
-mon_to_buffer(mtmp,isize)
+STATIC_OVL void
+savemon(fd, mtmp)
+int fd;
 struct monst *mtmp;
-int *isize;
 {
-       char *spot;
-       int lth, k, xlth[6];
-       genericptr_t buffer, xptr[6];
-       struct monst *mbuf;
-
-     /* assert((sizeof (*mbuf->mextra) / sizeof (char *)) == 6); */
-       lth = (int)sizeof (struct monst);
-
-       /* there is always one sizeof(int) for each mextra field */
-       for (k = 0; k < SIZE(xlth); ++k) {
-               xlth[k] = 0;
-               xptr[k] = (genericptr_t)0;
-       }
-       if (mtmp->mextra) {
-               if (MNAME(mtmp)) {
-                       xlth[0] = (int)strlen(MNAME(mtmp)) + 1;
-                       xptr[0] = (genericptr_t)MNAME(mtmp);
-               }
-               if (EGD(mtmp)) {
-                       xlth[1] = (int)sizeof (struct egd);
-                       xptr[1] = (genericptr_t)EGD(mtmp);
-               }
-               if (EPRI(mtmp)) {
-                       xlth[2] = (int)sizeof (struct epri);
-                       xptr[2] = (genericptr_t)EPRI(mtmp);
-               }
-               if (ESHK(mtmp)) {
-                       xlth[3] = (int)sizeof (struct eshk);
-                       xptr[3] = (genericptr_t)ESHK(mtmp);
-               }
-               if (EMIN(mtmp)) {
-                       xlth[4] = (int)sizeof (struct emin);
-                       xptr[4] = (genericptr_t)EMIN(mtmp);
-               }
-               if (EDOG(mtmp)) {
-                       xlth[5] = (int)sizeof (struct edog);
-                       xptr[5] = (genericptr_t)EDOG(mtmp);
-               }
-       }
-       for (k = 0; k < SIZE(xlth); ++k) {
-               lth += (int)sizeof (int) + xlth[k];
-       }
-       if (isize) *isize = lth;
-
-       buffer = alloc((unsigned) lth);
-
-       spot = (char *)buffer;
-       (void) memcpy((genericptr_t)spot, (genericptr_t)mtmp,
-                       sizeof(struct monst));
-       spot += sizeof(struct monst);
-
-       mbuf = (struct monst *)buffer;
-       mbuf->mextra = (struct mextra *)0;
-
-       for (k = 0; k < SIZE(xlth); ++k) {
-               lth = xlth[k];
-               (void) memcpy((genericptr_t)spot,
-                               (genericptr_t)&lth, sizeof(lth));
-               spot += sizeof(lth);
-               if (lth > 0 && xptr[k] != 0) {
-                       (void) memcpy((genericptr_t)spot, xptr[k], lth);
-                       spot += lth;
-               }
+       int buflen, zerobuf = 0;
+
+       buflen = sizeof(struct monst);
+       bwrite(fd, (genericptr_t) &buflen, sizeof(int));
+       bwrite(fd, (genericptr_t) mtmp, buflen);
+       if (!mtmp->mextra) {
+               bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
+               bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
+               bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
+               bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
+               bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
+               bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
+       } else {
+               if (MNAME(mtmp)) buflen = strlen(MNAME(mtmp)) + 1;
+               else buflen = 0;
+               bwrite(fd, (genericptr_t) &buflen, sizeof buflen);
+               if (buflen > 0)
+                       bwrite(fd, (genericptr_t) MNAME(mtmp), buflen);
+
+               if (EGD(mtmp)) buflen = sizeof(struct egd);
+               else buflen = 0;
+               bwrite(fd, (genericptr_t) &buflen, sizeof(int));
+               if (buflen > 0)
+                       bwrite(fd, (genericptr_t) EGD(mtmp), buflen);
+
+               if (EPRI(mtmp)) buflen = sizeof(struct epri);
+               else buflen = 0;
+               bwrite(fd, (genericptr_t) &buflen, sizeof(int));
+               if (buflen > 0)
+                       bwrite(fd, (genericptr_t) EPRI(mtmp), buflen);
+
+               if (ESHK(mtmp)) buflen = sizeof(struct eshk);
+               else buflen = 0;
+               bwrite(fd, (genericptr_t) &buflen, sizeof(int));
+               if (buflen > 0)
+                       bwrite(fd, (genericptr_t) ESHK(mtmp), buflen);
+
+               if (EMIN(mtmp)) buflen = sizeof(struct emin);
+               else buflen = 0;
+               bwrite(fd, (genericptr_t) &buflen, sizeof(int));
+               if (buflen > 0)
+                       bwrite(fd, (genericptr_t) EMIN(mtmp), buflen);
+
+               if (EDOG(mtmp)) buflen = sizeof(struct edog);
+               else buflen = 0;
+               bwrite(fd, (genericptr_t) &buflen, sizeof(int));
+               if (buflen > 0)
+                       bwrite(fd, (genericptr_t) EDOG(mtmp), buflen);
        }
-       return (genericptr_t)buffer;
 }
 
 STATIC_OVL void
@@ -1087,7 +1113,7 @@ register int fd, mode;
 register struct monst *mtmp;
 {
        register struct monst *mtmp2;
-       int buflen, minusone = -1, zerobuf = 0;
+       int minusone = -1;
 
        while (mtmp) {
            mtmp2 = mtmp->nmon;
@@ -1105,60 +1131,7 @@ register struct monst *mtmp;
                        mtmp->minvent = goldobj;
                }
 #endif
-               buflen = sizeof(struct monst);
-               bwrite(fd, (genericptr_t) &buflen, sizeof(int));
-#if 0
-               {
-                   genericptr_t buffer = mon_to_buffer(mtmp, &buflen);
-                   bwrite(fd, buffer, buflen);
-               }
-#else
-               bwrite(fd, (genericptr_t) mtmp, buflen);
-               if (!mtmp->mextra) {
-                       bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
-                       bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
-                       bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
-                       bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
-                       bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
-                       bwrite(fd, (genericptr_t) &zerobuf, sizeof(int));
-               } else {
-                       if (MNAME(mtmp)) buflen = strlen(MNAME(mtmp)) + 1;
-                       else buflen = 0;
-                       bwrite(fd, (genericptr_t) &buflen, sizeof(int));
-                       if (buflen > 0)
-                               bwrite(fd, (genericptr_t) MNAME(mtmp), buflen);
-
-                       if (EGD(mtmp)) buflen = sizeof(struct egd);
-                       else buflen = 0;
-                       bwrite(fd, (genericptr_t) &buflen, sizeof(int));
-                       if (buflen > 0)
-                               bwrite(fd, (genericptr_t) EGD(mtmp), buflen);
-
-                       if (EPRI(mtmp)) buflen = sizeof(struct epri);
-                       else buflen = 0;
-                       bwrite(fd, (genericptr_t) &buflen, sizeof(int));
-                       if (buflen > 0)
-                               bwrite(fd, (genericptr_t) EPRI(mtmp), buflen);
-
-                       if (ESHK(mtmp)) buflen = sizeof(struct eshk);
-                       else buflen = 0;
-                       bwrite(fd, (genericptr_t) &buflen, sizeof(int));
-                       if (buflen > 0)
-                               bwrite(fd, (genericptr_t) ESHK(mtmp), buflen);
-
-                       if (EMIN(mtmp)) buflen = sizeof(struct emin);
-                       else buflen = 0;
-                       bwrite(fd, (genericptr_t) &buflen, sizeof(int));
-                       if (buflen > 0)
-                               bwrite(fd, (genericptr_t) EMIN(mtmp), buflen);
-
-                       if (EDOG(mtmp)) buflen = sizeof(struct edog);
-                       else buflen = 0;
-                       bwrite(fd, (genericptr_t) &buflen, sizeof(int));
-                       if (buflen > 0)
-                               bwrite(fd, (genericptr_t) EDOG(mtmp), buflen);
-               }
-#endif
+               savemon(fd, mtmp);
            }
            if (mtmp->minvent)
                saveobjchn(fd,mtmp->minvent,mode);
index 1293a9bc7de0de8d650ed9841eb89c803e8b17bc..cff645b8390cf9bc2ad307cc8ba729aa8bc441e3 100644 (file)
--- a/src/shk.c
+++ b/src/shk.c
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)shk.c      3.5     2006/01/09      */
+/*     SCCS Id: @(#)shk.c      3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -2333,15 +2333,13 @@ register struct monst *shkp;
 
                obj->unpaid = 0;
                if(bp->bquan > obj->quan){
-                       otmp = newobj(0);
+                       otmp = newobj();
                        *otmp = *obj;
+                       otmp->oextra = (struct oextra *)0;
                        bp->bo_id = otmp->o_id = context.ident++;
                        otmp->where = OBJ_FREE;
                        otmp->quan = (bp->bquan -= obj->quan);
                        otmp->owt = 0;  /* superfluous */
-                       otmp->onamelth = 0;
-                       otmp->oxlth = 0;
-                       otmp->oattached = OATTACHED_NOTHING;
                        bp->useup = 1;
                        add_to_billobjs(otmp);
                        return;
index 8c696c28e5d872182c3fe44ae0ed61003bdefa15..670bf480fc963f6df184d47ee0ba6d653cfe94d9 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)steed.c    3.5     2003/01/10      */
+/*     SCCS Id: @(#)steed.c    3.5     2006/04/14      */
 /* Copyright (c) Kevin Hugo, 1998-1999. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -512,7 +512,7 @@ dismount_steed(reason)
                    You("can't. There isn't anywhere for you to stand.");
                    return;
                }
-               if (!has_name(mtmp)) {
+               if (!has_mname(mtmp)) {
                        pline("You've been through the dungeon on %s with no name.",
                                an(mtmp->data->mname));
                        if (Hallucination)
index ba57add4349f60a491e91e30302c39677b2a7e75..60802e2bd34598438aac315382154639e4f10b96 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)timeout.c  3.5     2005/06/22      */
+/*     SCCS Id: @(#)timeout.c  3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -679,7 +679,7 @@ slip_or_trip()
            pline("%s %s%s on the ice.",
 #ifdef STEED
                u.usteed ? upstart(x_monnam(u.usteed,
-                               (has_name(u.usteed)) ? ARTICLE_NONE : ARTICLE_THE,
+                               (has_mname(u.usteed)) ? ARTICLE_NONE : ARTICLE_THE,
                                (char *)0, SUPPRESS_SADDLE, FALSE)) :
 #endif
                "You", rn2(2) ? "slip" : "slide", on_foot ? "" : "s");
index dc4d913f6facdebd2c43d723a992fb07753f28ea..f56e5bee98b1e1388b8f41f145f168d4fdcbb3ac 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)trap.c     3.5     2006/04/05      */
+/*     SCCS Id: @(#)trap.c     3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -432,8 +432,7 @@ int *fail_reason;
            mptr = &mons[PM_FLESH_GOLEM];
            use_saved_traits = FALSE;
        } else {
-           use_saved_traits = (statue->oxlth &&
-                               statue->oattached == OATTACHED_MONST);
+           use_saved_traits = has_omonst(statue);
        }
 
        if (use_saved_traits) {
@@ -475,7 +474,7 @@ int *fail_reason;
        else if (statue->spe & STATUE_FEMALE)
            mon->female = TRUE;
        /* if statue has been named, give same name to the monster */
-       if (statue->onamelth)
+       if (has_oname(statue))
            mon = christen_monst(mon, ONAME(statue));
        /* mimic statue becomes seen mimic; other hiders won't be hidden */
        if (mon->m_ap_type) seemimic(mon);
@@ -600,9 +599,8 @@ struct obj *objchn, *saddle;
 {
        if (!saddle) return FALSE;
        while(objchn) {
-               if(objchn->otyp == CORPSE &&
-                  objchn->oattached == OATTACHED_MONST && objchn->oxlth) {
-                       struct monst *mtmp = (struct monst *)objchn->oextra;
+               if(objchn->otyp == CORPSE && has_omonst(objchn)) {
+                       struct monst *mtmp = OMONST(objchn);
                        if (mtmp->m_id == steed_mid) {
                                /* move saddle */
                                xchar x,y;
@@ -682,7 +680,7 @@ unsigned trflags;
            u.usteed->mtrapseen |= (1 << (ttype - 1));
            /* suppress article in various steed messages when using its
               name (which won't occur when hallucinating) */
-           if (has_name(u.usteed) && !Hallucination)
+           if (has_mname(u.usteed) && !Hallucination)
                steed_article = ARTICLE_NONE;
        }
 #endif
index 9a45a76b5bb1918233f710f86fc68024c2c142d4..1708c4d869f29bc962d8f96056601c4e090787dd 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)wield.c    3.5     2005/12/26      */
+/*     SCCS Id: @(#)wield.c    3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -707,7 +707,7 @@ register struct obj *otmp;
 register int amount;
 {
        const char *color = hcolor((amount < 0) ? NH_BLACK : NH_BLUE);
-       const char *xtime;
+       const char *xtime, *wepname = "";
        int otyp = STRANGE_OBJECT;
 
        if(!uwep || (uwep->oclass != WEAPON_CLASS && !is_weptool(uwep))) {
@@ -742,7 +742,9 @@ register int amount;
                return 1;
        }
 
-       if (amount < 0 && uwep->oartifact && restrict_name(uwep, ONAME(uwep))) {
+       if (has_oname(uwep))
+               wepname = ONAME(uwep);
+       if (amount < 0 && uwep->oartifact && restrict_name(uwep, wepname)) {
            if (!Blind)
                pline("%s %s.", Yobjnam2(uwep, "faintly glow"), color);
            return(1);
index f8f2a986035d326643e84d0a61791c5db37aea87..7aab24c6fd6575a86e0e65038f1b025615487a7e 100644 (file)
--- a/src/zap.c
+++ b/src/zap.c
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)zap.c      3.5     2006/04/05      */
+/*     SCCS Id: @(#)zap.c      3.5     2006/04/14      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -510,7 +510,7 @@ coord *cc;
        struct monst *mtmp = (struct monst *)0;
        struct monst *mtmp2 = (struct monst *)0;
 
-       if (obj->oxlth && (obj->oattached == OATTACHED_MONST))
+       if (has_omonst(obj))
                mtmp2 = get_mtraits(obj, TRUE);
        if (mtmp2) {
                /* save_mtraits() validated mtmp2->mnum */
@@ -694,7 +694,9 @@ boolean by_hero;
        /* note: montype has changed; mptr keeps old value for newcham() */
        mtmp = makemon(&mons[montype], x, y, NO_MINVENT|MM_NOWAIT);
        if (mtmp) {
-           corpse->oattached = OATTACHED_NOTHING;  /* skip ghost handling */
+           /* skip ghost handling */
+           if (has_omid(corpse)) free_omid(corpse);
+           if (has_omonst(corpse)) free_omonst(corpse);
            if (mtmp->cham == PM_DOPPELGANGER) {
                /* change shape to match the corpse */
                (void) newcham(mtmp, mptr, FALSE, FALSE);
@@ -703,7 +705,7 @@ boolean by_hero;
                mon_adjust_speed(mtmp, 2, (struct obj *)0); /* MFAST */
            }
        }
-    } else if (corpse->oxlth && corpse->oattached == OATTACHED_MONST) {
+    } else if (has_omonst(corpse)) {
        /* use saved traits */
        xy.x = x,  xy.y = y;
        mtmp = montraits(corpse, &xy);
@@ -739,13 +741,13 @@ boolean by_hero;
     }
 
     /* handle recorporealization of an active ghost */
-    if (corpse->oxlth && corpse->oattached == OATTACHED_M_ID) {
+    if (has_omid(corpse)) {
        unsigned m_id;
        struct monst *ghost;
        struct obj *otmp;
 
        (void) memcpy((genericptr_t)&m_id,
-                     (genericptr_t)corpse->oextra, sizeof m_id);
+                     (genericptr_t)OMID(corpse), sizeof m_id);
        ghost = find_mid(m_id, FM_FMON);
        if (ghost && ghost->data == &mons[PM_GHOST]) {
            if (canseemon(ghost))
@@ -768,11 +770,11 @@ boolean by_hero;
            /* separate ghost monster no longer exists */
            mongone(ghost);
        }
-       corpse->oattached = OATTACHED_NOTHING;
+       free_omid(corpse);
     }
 
     /* monster retains its name */
-    if (corpse->onamelth)
+    if (has_oname(corpse))
        mtmp = christen_monst(mtmp, ONAME(corpse));
     /* partially eaten corpse yields wounded monster */
     if (corpse->oeaten)
@@ -4013,9 +4015,8 @@ register struct obj *obj;            /* no texts here! */
        obj->owt = weight(obj);
        obj->dknown = obj->bknown = obj->rknown = 0;
        obj->known = objects[obj->otyp].oc_uses_known ? 0 : 1;
-       obj->onamelth = 0;              /* no names */
-       obj->oxlth = 0;                 /* no extra data */
-       obj->oattached = OATTACHED_NOTHING;
+       if (obj->oextra) dealloc_oextra(obj->oextra);
+       obj->oextra = (struct oextra *)0;
        if (obj->where == OBJ_FLOOR) {
                obj_extract_self(obj);          /* move rocks back on top */
                place_object(obj, obj->ox, obj->oy);