From f55210be79067bbdcea2376463e757bdab6b6be7 Mon Sep 17 00:00:00 2001 From: "nethack.allison" Date: Fri, 14 Apr 2006 16:23:56 +0000 Subject: [PATCH] code change - oextra 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. --- doc/fixes35.0 | 3 + include/extern.h | 14 +++ include/mextra.h | 19 ++-- include/obj.h | 42 +++++--- include/patchlevel.h | 4 +- src/artifact.c | 4 +- src/bones.c | 21 ++-- src/cmd.c | 22 +++- src/do_name.c | 135 ++++++++---------------- src/dog.c | 4 +- src/dothrow.c | 4 +- src/eat.c | 6 +- src/end.c | 10 +- src/invent.c | 30 ++++-- src/mail.c | 26 +++-- src/makemon.c | 4 +- src/mkobj.c | 227 +++++++++++++++++++++++++++++++--------- src/mon.c | 60 +++++++++-- src/mplayer.c | 4 +- src/music.c | 4 +- src/objnam.c | 20 ++-- src/pray.c | 4 +- src/read.c | 4 +- src/restore.c | 241 +++++++++++++++++++++---------------------- src/save.c | 237 +++++++++++++++++++----------------------- src/shk.c | 8 +- src/steed.c | 4 +- src/timeout.c | 4 +- src/trap.c | 14 ++- src/wield.c | 8 +- src/zap.c | 23 +++-- 31 files changed, 690 insertions(+), 520 deletions(-) diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 1c694c3e0..287cbaef3 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -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 + + diff --git a/include/extern.h b/include/extern.h index 4c7292b97..6e0ddc35e 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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)); diff --git a/include/mextra.h b/include/mextra.h index 6e0eb71ef..3e72c8b8d 100644 --- a/include/mextra.h +++ b/include/mextra.h @@ -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. */ @@ -47,15 +47,12 @@ * 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 */ diff --git a/include/obj.h b/include/obj.h index 32b3e0aae..c334a8731 100644 --- a/include/obj.h +++ b/include/obj.h @@ -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: diff --git a/include/patchlevel.h b/include/patchlevel.h index 768e655e4..38063451d 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -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" diff --git a/src/artifact.c b/src/artifact.c index 3d79d17eb..3b5ea3be7 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -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 */ diff --git a/src/bones.c b/src/bones.c index 561740ccb..8220afb5a 100644 --- a/src/bones.c +++ b/src/bones.c @@ -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 diff --git a/src/cmd.c b/src/cmd.c index 1f6e95bf5..412ac9f72 100644 --- 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); diff --git a/src/do_name.c b/src/do_name.c index d42ef1a78..7e5802c43 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -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 * diff --git a/src/dog.c b/src/dog.c index d463ed0c6..4ba964f34 100644 --- 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 */ diff --git a/src/dothrow.c b/src/dothrow.c index 0cc70d910..e97914d3c 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -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); diff --git a/src/eat.c b/src/eat.c index dc5d96723..ee2f0d146 100644 --- 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); diff --git a/src/end.c b/src/end.c index cb1dbc236..e6d02c0ac 100644 --- 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_ 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), diff --git a/src/invent.c b/src/invent.c index bae65c6fd..7de82850b 100644 --- a/src/invent.c +++ b/src/invent.c @@ -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)) { diff --git a/src/mail.c b/src/mail.c index 216161105..898339099 100644 --- a/src/mail.c +++ b/src/mail.c @@ -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); diff --git a/src/makemon.c b/src/makemon.c index 6984d593e..49d8197f1 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -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)); diff --git a/src/mkobj.c b/src/mkobj.c index 66ce21b9b..b31d0afa3 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -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, <h); - 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); } diff --git a/src/mon.c b/src/mon.c index a9e2890b7..15c4395a9 100644 --- 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; } diff --git a/src/mplayer.c b/src/mplayer.c index 6a758444b..c96cff13a 100644 --- a/src/mplayer.c +++ b/src/mplayer.c @@ -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; diff --git a/src/music.c b/src/music.c index e45d6e117..e250ae4a7 100644 --- a/src/music.c +++ b/src/music.c @@ -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); diff --git a/src/objnam.c b/src/objnam.c index a3acb6c58..80cf59b54 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -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!", diff --git a/src/pray.c b/src/pray.c index 679a03873..4fce54477 100644 --- a/src/pray.c +++ b/src/pray.c @@ -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, diff --git a/src/read.c b/src/read.c index 1ce663fb6..4a0deb067 100644 --- a/src/read.c +++ b/src/read.c @@ -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; diff --git a/src/restore.c b/src/restore.c index 569096757..8175ee9af 100644 --- a/src/restore.c +++ b/src/restore.c @@ -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)<h, (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)<h, (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)<h, (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)<h, (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)<h, (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)<h, (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); + } } } diff --git a/src/save.c b/src/save.c index 22a57d278..8c5437fe1 100644 --- a/src/save.c +++ b/src/save.c @@ -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)<h, 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); diff --git a/src/shk.c b/src/shk.c index 1293a9bc7..cff645b83 100644 --- 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; diff --git a/src/steed.c b/src/steed.c index 8c696c28e..670bf480f 100644 --- a/src/steed.c +++ b/src/steed.c @@ -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) diff --git a/src/timeout.c b/src/timeout.c index ba57add43..60802e2bd 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -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"); diff --git a/src/trap.c b/src/trap.c index dc4d913f6..f56e5bee9 100644 --- a/src/trap.c +++ b/src/trap.c @@ -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 diff --git a/src/wield.c b/src/wield.c index 9a45a76b5..1708c4d86 100644 --- a/src/wield.c +++ b/src/wield.c @@ -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); diff --git a/src/zap.c b/src/zap.c index f8f2a9860..7aab24c6f 100644 --- 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); -- 2.40.0