OSDN Git Service

force nhdefkey.dll
[jnethack/source.git] / include / obj.h
1 /* NetHack 3.6  obj.h   $NHDT-Date: 1508827590 2017/10/24 06:46:30 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.60 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Michael Allison, 2006. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 #ifndef OBJ_H
7 #define OBJ_H
8
9 /* #define obj obj_nh */ /* uncomment for SCO UNIX, which has a conflicting
10                           * typedef for "obj" in <sys/types.h> */
11
12 union vptrs {
13     struct obj *v_nexthere;   /* floor location lists */
14     struct obj *v_ocontainer; /* point back to container */
15     struct monst *v_ocarry;   /* point back to carrying monst */
16 };
17
18 /****
19  ***    oextra -- collection of all object extensions
20  **     (see the note at the bottom of this file before adding oextra fields)
21  */
22 struct oextra {
23     char *oname;          /* ptr to name of object */
24     struct monst *omonst; /* ptr to attached monst struct */
25     unsigned *omid;       /* ptr to m_id */
26     long *olong;          /* ptr to misc long (temporary gold object) */
27     char *omailcmd;       /* response_cmd for mail deliver */
28 };
29
30 struct obj {
31     struct obj *nobj;
32     union vptrs v;
33 #define nexthere v.v_nexthere
34 #define ocontainer v.v_ocontainer
35 #define ocarry v.v_ocarry
36
37     struct obj *cobj; /* contents list for containers */
38     unsigned o_id;
39     xchar ox, oy;
40     short otyp; /* object class number */
41     unsigned owt;
42     long quan; /* number of items */
43
44     schar spe; /* quality of weapon, weptool, armor or ring (+ or -);
45                   number of charges for wand or charged tool ( >= -1 );
46                   number of candles attached to candelabrum;
47                   marks your eggs, tin variety and spinach tins;
48                   Schroedinger's Box (1) or royal coffers for a court (2);
49                   tells which fruit a fruit is;
50                   special for uball and amulet;
51                   scroll of mail (normal==0, bones or wishing==1, written==2);
52                   historic and gender for statues */
53 #define STATUE_HISTORIC 0x01
54 #define STATUE_MALE 0x02
55 #define STATUE_FEMALE 0x04
56     char oclass;    /* object class */
57     char invlet;    /* designation in inventory */
58     char oartifact; /* artifact array index */
59
60     xchar where;        /* where the object thinks it is */
61 #define OBJ_FREE 0      /* object not attached to anything */
62 #define OBJ_FLOOR 1     /* object on floor */
63 #define OBJ_CONTAINED 2 /* object in a container */
64 #define OBJ_INVENT 3    /* object in the hero's inventory */
65 #define OBJ_MINVENT 4   /* object in a monster inventory */
66 #define OBJ_MIGRATING 5 /* object sent off to another level */
67 #define OBJ_BURIED 6    /* object buried */
68 #define OBJ_ONBILL 7    /* object on shk bill */
69 #define NOBJ_STATES 8
70     xchar timed; /* # of fuses (timers) attached to this obj */
71
72     Bitfield(cursed, 1);
73     Bitfield(blessed, 1);
74     Bitfield(unpaid, 1);    /* on some bill */
75     Bitfield(no_charge, 1); /* if shk shouldn't charge for this */
76     Bitfield(known, 1);     /* exact nature known */
77     Bitfield(dknown, 1);    /* color or text known */
78     Bitfield(bknown, 1);    /* blessing or curse known */
79     Bitfield(rknown, 1);    /* rustproof or not known */
80
81     Bitfield(oeroded, 2);  /* rusted/burnt weapon/armor */
82     Bitfield(oeroded2, 2); /* corroded/rotted weapon/armor */
83 #define greatest_erosion(otmp)                                 \
84     (int)((otmp)->oeroded > (otmp)->oeroded2 ? (otmp)->oeroded \
85                                              : (otmp)->oeroded2)
86 #define MAX_ERODE 3
87 #define orotten oeroded  /* rotten food */
88 #define odiluted oeroded /* diluted potions */
89 #define norevive oeroded2
90     Bitfield(oerodeproof, 1); /* erodeproof weapon/armor */
91     Bitfield(olocked, 1);     /* object is locked */
92     Bitfield(obroken, 1);     /* lock has been broken */
93 #define degraded_horn obroken /* unicorn horn will poly to non-magic */
94     Bitfield(otrapped, 1);    /* container is trapped */
95 /* or accidental tripped rolling boulder trap */
96 #define opoisoned otrapped /* object (weapon) is coated with poison */
97
98     Bitfield(recharged, 3); /* number of times it's been recharged */
99 #define on_ice recharged    /* corpse on ice */
100     Bitfield(lamplit, 1);   /* a light-source -- can be lit */
101     Bitfield(globby, 1);    /* combines with like types on adjacent squares */
102     Bitfield(greased, 1);    /* covered with grease */
103     Bitfield(nomerge, 1);    /* set temporarily to prevent merging */
104     Bitfield(was_thrown, 1); /* thrown by hero since last picked up */
105
106     Bitfield(in_use, 1); /* for magic items before useup items */
107     Bitfield(bypass, 1); /* mark this as an object to be skipped by bhito() */
108     Bitfield(cknown, 1); /* contents of container assumed to be known */
109     Bitfield(lknown, 1); /* locked/unlocked status is known */
110     /* 4 free bits */
111
112     int corpsenm;         /* type of corpse is mons[corpsenm] */
113 #define leashmon corpsenm /* gets m_id of attached pet */
114 #define fromsink corpsenm /* a potion from a sink */
115 #define novelidx corpsenm /* 3.6 tribute - the index of the novel title */
116 #define record_achieve_special corpsenm
117     int usecount;           /* overloaded for various things that tally */
118 #define spestudied usecount /* # of times a spellbook has been studied */
119     unsigned oeaten;        /* nutrition left in food, if partly eaten */
120     long age;               /* creation date */
121     long owornmask;
122     struct oextra *oextra; /* pointer to oextra struct */
123 };
124
125 #define newobj() (struct obj *) alloc(sizeof(struct obj))
126
127 /***
128  **     oextra referencing and testing macros
129  */
130
131 #define ONAME(o) ((o)->oextra->oname)
132 #define OMID(o) ((o)->oextra->omid)
133 #define OMONST(o) ((o)->oextra->omonst)
134 #define OLONG(o) ((o)->oextra->olong)
135 #define OMAILCMD(o) ((o)->oextra->omailcmd)
136
137 #define has_oname(o) ((o)->oextra && ONAME(o))
138 #define has_omid(o) ((o)->oextra && OMID(o))
139 #define has_omonst(o) ((o)->oextra && OMONST(o))
140 #define has_olong(o) ((o)->oextra && OLONG(o))
141 #define has_omailcmd(o) ((o)->oextra && OMAILCMD(o))
142
143 /* Weapons and weapon-tools */
144 /* KMH -- now based on skill categories.  Formerly:
145  *      #define is_sword(otmp)  (otmp->oclass == WEAPON_CLASS && \
146  *                       objects[otmp->otyp].oc_wepcat == WEP_SWORD)
147  *      #define is_blade(otmp)  (otmp->oclass == WEAPON_CLASS && \
148  *                       (objects[otmp->otyp].oc_wepcat == WEP_BLADE || \
149  *                        objects[otmp->otyp].oc_wepcat == WEP_SWORD))
150  *      #define is_weptool(o)   ((o)->oclass == TOOL_CLASS && \
151  *                       objects[(o)->otyp].oc_weptool)
152  *      #define is_multigen(otyp) (otyp <= SHURIKEN)
153  *      #define is_poisonable(otyp) (otyp <= BEC_DE_CORBIN)
154  */
155 #define is_blade(otmp)                           \
156     (otmp->oclass == WEAPON_CLASS                \
157      && objects[otmp->otyp].oc_skill >= P_DAGGER \
158      && objects[otmp->otyp].oc_skill <= P_SABER)
159 #define is_axe(otmp)                                              \
160     ((otmp->oclass == WEAPON_CLASS || otmp->oclass == TOOL_CLASS) \
161      && objects[otmp->otyp].oc_skill == P_AXE)
162 #define is_pick(otmp)                                             \
163     ((otmp->oclass == WEAPON_CLASS || otmp->oclass == TOOL_CLASS) \
164      && objects[otmp->otyp].oc_skill == P_PICK_AXE)
165 #define is_sword(otmp)                                \
166     (otmp->oclass == WEAPON_CLASS                     \
167      && objects[otmp->otyp].oc_skill >= P_SHORT_SWORD \
168      && objects[otmp->otyp].oc_skill <= P_SABER)
169 #define is_pole(otmp)                                             \
170     ((otmp->oclass == WEAPON_CLASS || otmp->oclass == TOOL_CLASS) \
171      && (objects[otmp->otyp].oc_skill == P_POLEARMS               \
172          || objects[otmp->otyp].oc_skill == P_LANCE))
173 #define is_spear(otmp) \
174     (otmp->oclass == WEAPON_CLASS && objects[otmp->otyp].oc_skill == P_SPEAR)
175 #define is_launcher(otmp)                                                  \
176     (otmp->oclass == WEAPON_CLASS && objects[otmp->otyp].oc_skill >= P_BOW \
177      && objects[otmp->otyp].oc_skill <= P_CROSSBOW)
178 #define is_ammo(otmp)                                            \
179     ((otmp->oclass == WEAPON_CLASS || otmp->oclass == GEM_CLASS) \
180      && objects[otmp->otyp].oc_skill >= -P_CROSSBOW              \
181      && objects[otmp->otyp].oc_skill <= -P_BOW)
182 #define matching_launcher(a, l) \
183     ((l) && objects[(a)->otyp].oc_skill == -objects[(l)->otyp].oc_skill)
184 #define ammo_and_launcher(a, l) (is_ammo(a) && matching_launcher(a, l))
185 #define is_missile(otmp)                                          \
186     ((otmp->oclass == WEAPON_CLASS || otmp->oclass == TOOL_CLASS) \
187      && objects[otmp->otyp].oc_skill >= -P_BOOMERANG              \
188      && objects[otmp->otyp].oc_skill <= -P_DART)
189 #define is_weptool(o) \
190     ((o)->oclass == TOOL_CLASS && objects[(o)->otyp].oc_skill != P_NONE)
191         /* towel is not a weptool:  spe isn't an enchantment, cursed towel
192            doesn't weld to hand, and twoweapon won't work with one */
193 #define is_wet_towel(o) ((o)->otyp == TOWEL && (o)->spe > 0)
194 #define bimanual(otmp)                                            \
195     ((otmp->oclass == WEAPON_CLASS || otmp->oclass == TOOL_CLASS) \
196      && objects[otmp->otyp].oc_bimanual)
197 #define is_multigen(otmp)                           \
198     (otmp->oclass == WEAPON_CLASS                   \
199      && objects[otmp->otyp].oc_skill >= -P_SHURIKEN \
200      && objects[otmp->otyp].oc_skill <= -P_BOW)
201 #define is_poisonable(otmp)                         \
202     (otmp->oclass == WEAPON_CLASS                   \
203      && objects[otmp->otyp].oc_skill >= -P_SHURIKEN \
204      && objects[otmp->otyp].oc_skill <= -P_BOW)
205 #define uslinging() (uwep && objects[uwep->otyp].oc_skill == P_SLING)
206 /* 'is_quest_artifact()' only applies to the current role's artifact */
207 #define any_quest_artifact(o) ((o)->oartifact >= ART_ORB_OF_DETECTION)
208
209 /* Armor */
210 #define is_shield(otmp)          \
211     (otmp->oclass == ARMOR_CLASS \
212      && objects[otmp->otyp].oc_armcat == ARM_SHIELD)
213 #define is_helmet(otmp) \
214     (otmp->oclass == ARMOR_CLASS && objects[otmp->otyp].oc_armcat == ARM_HELM)
215 #define is_boots(otmp)           \
216     (otmp->oclass == ARMOR_CLASS \
217      && objects[otmp->otyp].oc_armcat == ARM_BOOTS)
218 #define is_gloves(otmp)          \
219     (otmp->oclass == ARMOR_CLASS \
220      && objects[otmp->otyp].oc_armcat == ARM_GLOVES)
221 #define is_cloak(otmp)           \
222     (otmp->oclass == ARMOR_CLASS \
223      && objects[otmp->otyp].oc_armcat == ARM_CLOAK)
224 #define is_shirt(otmp)           \
225     (otmp->oclass == ARMOR_CLASS \
226      && objects[otmp->otyp].oc_armcat == ARM_SHIRT)
227 #define is_suit(otmp) \
228     (otmp->oclass == ARMOR_CLASS && objects[otmp->otyp].oc_armcat == ARM_SUIT)
229 #define is_elven_armor(otmp)                                              \
230     ((otmp)->otyp == ELVEN_LEATHER_HELM                                   \
231      || (otmp)->otyp == ELVEN_MITHRIL_COAT || (otmp)->otyp == ELVEN_CLOAK \
232      || (otmp)->otyp == ELVEN_SHIELD || (otmp)->otyp == ELVEN_BOOTS)
233 #define is_orcish_armor(otmp)                                            \
234     ((otmp)->otyp == ORCISH_HELM || (otmp)->otyp == ORCISH_CHAIN_MAIL    \
235      || (otmp)->otyp == ORCISH_RING_MAIL || (otmp)->otyp == ORCISH_CLOAK \
236      || (otmp)->otyp == URUK_HAI_SHIELD || (otmp)->otyp == ORCISH_SHIELD)
237 #define is_dwarvish_armor(otmp)               \
238     ((otmp)->otyp == DWARVISH_IRON_HELM       \
239      || (otmp)->otyp == DWARVISH_MITHRIL_COAT \
240      || (otmp)->otyp == DWARVISH_CLOAK        \
241      || (otmp)->otyp == DWARVISH_ROUNDSHIELD)
242 #define is_gnomish_armor(otmp) (FALSE)
243
244 /* Eggs and other food */
245 #define MAX_EGG_HATCH_TIME 200 /* longest an egg can remain unhatched */
246 #define stale_egg(egg) \
247     ((monstermoves - (egg)->age) > (2 * MAX_EGG_HATCH_TIME))
248 #define ofood(o) ((o)->otyp == CORPSE || (o)->otyp == EGG || (o)->otyp == TIN)
249 #define polyfodder(obj) (ofood(obj) && pm_to_cham((obj)->corpsenm) != NON_PM)
250 #define mlevelgain(obj) (ofood(obj) && (obj)->corpsenm == PM_WRAITH)
251 #define mhealup(obj) (ofood(obj) && (obj)->corpsenm == PM_NURSE)
252 #define Is_pudding(o)                                                 \
253     (o->otyp == GLOB_OF_GRAY_OOZE || o->otyp == GLOB_OF_BROWN_PUDDING \
254      || o->otyp == GLOB_OF_GREEN_SLIME || o->otyp == GLOB_OF_BLACK_PUDDING)
255
256 /* Containers */
257 #define carried(o) ((o)->where == OBJ_INVENT)
258 #define mcarried(o) ((o)->where == OBJ_MINVENT)
259 #define Has_contents(o)                                \
260     (/* (Is_container(o) || (o)->otyp == STATUE) && */ \
261      (o)->cobj != (struct obj *) 0)
262 #define Is_container(o) ((o)->otyp >= LARGE_BOX && (o)->otyp <= BAG_OF_TRICKS)
263 #define Is_box(otmp) (otmp->otyp == LARGE_BOX || otmp->otyp == CHEST)
264 #define Is_mbag(otmp) \
265     (otmp->otyp == BAG_OF_HOLDING || otmp->otyp == BAG_OF_TRICKS)
266 #define SchroedingersBox(o) ((o)->otyp == LARGE_BOX && (o)->spe == 1)
267
268 /* dragon gear */
269 #define Is_dragon_scales(obj) \
270     ((obj)->otyp >= GRAY_DRAGON_SCALES && (obj)->otyp <= YELLOW_DRAGON_SCALES)
271 #define Is_dragon_mail(obj)                \
272     ((obj)->otyp >= GRAY_DRAGON_SCALE_MAIL \
273      && (obj)->otyp <= YELLOW_DRAGON_SCALE_MAIL)
274 #define Is_dragon_armor(obj) (Is_dragon_scales(obj) || Is_dragon_mail(obj))
275 #define Dragon_scales_to_pm(obj) \
276     &mons[PM_GRAY_DRAGON + (obj)->otyp - GRAY_DRAGON_SCALES]
277 #define Dragon_mail_to_pm(obj) \
278     &mons[PM_GRAY_DRAGON + (obj)->otyp - GRAY_DRAGON_SCALE_MAIL]
279 #define Dragon_to_scales(pm) (GRAY_DRAGON_SCALES + (pm - mons))
280
281 /* Elven gear */
282 #define is_elven_weapon(otmp)                                             \
283     ((otmp)->otyp == ELVEN_ARROW || (otmp)->otyp == ELVEN_SPEAR           \
284      || (otmp)->otyp == ELVEN_DAGGER || (otmp)->otyp == ELVEN_SHORT_SWORD \
285      || (otmp)->otyp == ELVEN_BROADSWORD || (otmp)->otyp == ELVEN_BOW)
286 #define is_elven_obj(otmp) (is_elven_armor(otmp) || is_elven_weapon(otmp))
287
288 /* Orcish gear */
289 #define is_orcish_obj(otmp)                                           \
290     (is_orcish_armor(otmp) || (otmp)->otyp == ORCISH_ARROW            \
291      || (otmp)->otyp == ORCISH_SPEAR || (otmp)->otyp == ORCISH_DAGGER \
292      || (otmp)->otyp == ORCISH_SHORT_SWORD || (otmp)->otyp == ORCISH_BOW)
293
294 /* Dwarvish gear */
295 #define is_dwarvish_obj(otmp)                                  \
296     (is_dwarvish_armor(otmp) || (otmp)->otyp == DWARVISH_SPEAR \
297      || (otmp)->otyp == DWARVISH_SHORT_SWORD                   \
298      || (otmp)->otyp == DWARVISH_MATTOCK)
299
300 /* Gnomish gear */
301 #define is_gnomish_obj(otmp) (is_gnomish_armor(otmp))
302
303 /* Light sources */
304 #define Is_candle(otmp) \
305     (otmp->otyp == TALLOW_CANDLE || otmp->otyp == WAX_CANDLE)
306 #define MAX_OIL_IN_FLASK 400 /* maximum amount of oil in a potion of oil */
307
308 /* MAGIC_LAMP intentionally excluded below */
309 /* age field of this is relative age rather than absolute */
310 #define age_is_relative(otmp)                                       \
311     ((otmp)->otyp == BRASS_LANTERN || (otmp)->otyp == OIL_LAMP      \
312      || (otmp)->otyp == CANDELABRUM_OF_INVOCATION                   \
313      || (otmp)->otyp == TALLOW_CANDLE || (otmp)->otyp == WAX_CANDLE \
314      || (otmp)->otyp == POT_OIL)
315 /* object can be ignited */
316 #define ignitable(otmp)                                             \
317     ((otmp)->otyp == BRASS_LANTERN || (otmp)->otyp == OIL_LAMP      \
318      || (otmp)->otyp == CANDELABRUM_OF_INVOCATION                   \
319      || (otmp)->otyp == TALLOW_CANDLE || (otmp)->otyp == WAX_CANDLE \
320      || (otmp)->otyp == POT_OIL)
321
322 /* things that can be read */
323 #define is_readable(otmp)                                                    \
324     ((otmp)->otyp == FORTUNE_COOKIE || (otmp)->otyp == T_SHIRT               \
325      || (otmp)->otyp == ALCHEMY_SMOCK || (otmp)->otyp == CREDIT_CARD         \
326      || (otmp)->otyp == CAN_OF_GREASE || (otmp)->otyp == MAGIC_MARKER        \
327      || (otmp)->oclass == COIN_CLASS || (otmp)->oartifact == ART_ORB_OF_FATE \
328      || (otmp)->otyp == CANDY_BAR)
329
330 /* special stones */
331 #define is_graystone(obj)                                 \
332     ((obj)->otyp == LUCKSTONE || (obj)->otyp == LOADSTONE \
333      || (obj)->otyp == FLINT || (obj)->otyp == TOUCHSTONE)
334
335 /* misc helpers, simple enough to be macros */
336 #define is_flimsy(otmp)                           \
337     (objects[(otmp)->otyp].oc_material <= LEATHER \
338      || (otmp)->otyp == RUBBER_HOSE)
339 #define is_plural(o) \
340     ((o)->quan != 1L                                                    \
341      /* "the Eyes of the Overworld" are plural, but                     \
342         "a pair of lenses named the Eyes of the Overworld" is not */    \
343      || ((o)->oartifact == ART_EYES_OF_THE_OVERWORLD                    \
344          && !undiscovered_artifact(ART_EYES_OF_THE_OVERWORLD)))
345 #define pair_of(o) ((o)->otyp == LENSES || is_gloves(o) || is_boots(o))
346
347 /* 'PRIZE' values override obj->corpsenm so prizes mustn't be object types
348    which use that field for monster type (or other overloaded purpose) */
349 #define MINES_PRIZE 1
350 #define SOKO_PRIZE1 2
351 #define SOKO_PRIZE2 3
352 #define is_mines_prize(o) \
353     ((o)->otyp == iflags.mines_prize_type                \
354      && (o)->record_achieve_special == MINES_PRIZE)
355 #define is_soko_prize(o) \
356     (((o)->otyp == iflags.soko_prize_type1               \
357       && (o)->record_achieve_special == SOKO_PRIZE1)     \
358      || ((o)->otyp == iflags.soko_prize_type2            \
359          && (o)->record_achieve_special == SOKO_PRIZE2))
360
361 /* Flags for get_obj_location(). */
362 #define CONTAINED_TOO 0x1
363 #define BURIED_TOO 0x2
364
365 /* object erosion types */
366 #define ERODE_BURN 0
367 #define ERODE_RUST 1
368 #define ERODE_ROT 2
369 #define ERODE_CORRODE 3
370
371 /* erosion flags for erode_obj() */
372 #define EF_NONE 0
373 #define EF_GREASE 0x1  /* check for a greased object */
374 #define EF_DESTROY 0x2 /* potentially destroy the object */
375 #define EF_VERBOSE 0x4 /* print extra messages */
376 #define EF_PAY 0x8     /* it's the player's fault */
377
378 /* erosion return values for erode_obj(), water_damage() */
379 #define ER_NOTHING 0   /* nothing happened */
380 #define ER_GREASED 1   /* protected by grease */
381 #define ER_DAMAGED 2   /* object was damaged in some way */
382 #define ER_DESTROYED 3 /* object was destroyed */
383
384 /* propeller method for potionhit() */
385 #define POTHIT_HERO_BASH   0 /* wielded by hero */
386 #define POTHIT_HERO_THROW  1 /* thrown by hero */
387 #define POTHIT_MONST_THROW 2 /* thrown by a monster */
388 #define POTHIT_OTHER_THROW 3 /* propelled by some other means [scatter()] */
389
390 /*
391  *  Notes for adding new oextra structures:
392  *
393  *       1. Add the structure definition and any required macros in an
394  *          appropriate header file that precedes this one.
395  *       2. Add a pointer to your new struct to oextra struct in this file.
396  *       3. Add a referencing macro to this file after the newobj macro above
397  *          (see ONAME, OMONST, OMIN, OLONG, or OMAILCMD for examples).
398  *       4. Add a testing macro after the set of referencing macros
399  *          (see has_oname(), has_omonst(), has_omin(), has_olong(),
400  *          has_omailcmd() for examples).
401  *       5. Create newXX(otmp) function and possibly free_XX(otmp) function
402  *          in an appropriate new or existing source file and add a prototype
403  *          for it to include/extern.h.  The majority of these are currently
404  *          located in mkobj.c for convenience.
405  *
406  *              void FDECL(newXX, (struct obj *));
407  *              void FDECL(free_XX, (struct obj *));
408  *
409  *                void
410  *                newxx(otmp)
411  *                struct obj *otmp;
412  *                {
413  *                    if (!otmp->oextra) otmp->oextra = newoextra();
414  *                    if (!XX(otmp)) {
415  *                        XX(otmp) = (struct XX *)alloc(sizeof(struct xx));
416  *                        (void) memset((genericptr_t) XX(otmp),
417  *                                   0, sizeof(struct xx));
418  *                    }
419  *                }
420  *
421  *       6. Adjust size_obj() in src/cmd.c appropriately.
422  *       7. Adjust dealloc_oextra() in src/mkobj.c to clean up
423  *          properly during obj deallocation.
424  *       8. Adjust copy_oextra() in src/mkobj.c to make duplicate
425  *          copies of your struct or data onto another obj struct.
426  *       9. Adjust restobj() in src/restore.c to deal with your
427  *          struct or data during a restore.
428  *      10. Adjust saveobj() in src/save.c to deal with your
429  *          struct or data during a save.
430  */
431
432 #endif /* OBJ_H */