OSDN Git Service

shrink mine
[nethackexpress/trunk.git] / include / obj.h
1 /*      SCCS Id: @(#)obj.h      3.4     2002/01/07      */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 #ifndef OBJ_H
6 #define OBJ_H
7
8 /* #define obj obj_nh */ /* uncomment for SCO UNIX, which has a conflicting
9                           * typedef for "obj" in <sys/types.h> */
10
11 union vptrs {
12             struct obj *v_nexthere;     /* floor location lists */
13             struct obj *v_ocontainer;   /* point back to container */
14             struct monst *v_ocarry;     /* point back to carrying monst */
15 };
16
17 struct obj {
18         struct obj *nobj;
19         union vptrs v;
20 #define nexthere        v.v_nexthere
21 #define ocontainer      v.v_ocontainer
22 #define ocarry          v.v_ocarry
23
24         struct obj *cobj;       /* contents list for containers */
25         unsigned o_id;
26         xchar ox,oy;
27         short otyp;             /* object class number */
28         unsigned owt;
29         long quan;              /* number of items */
30
31         schar spe;              /* quality of weapon, armor or ring (+ or -)
32                                    number of charges for wand ( >= -1 )
33                                    marks your eggs, spinach tins
34                                    royal coffers for a court ( == 2)
35                                    tells which fruit a fruit is
36                                    special for uball and amulet
37                                    historic and gender for statues */
38 #define STATUE_HISTORIC 0x01
39 #define STATUE_MALE     0x02
40 #define STATUE_FEMALE   0x04
41         char    oclass;         /* object class */
42         char    invlet;         /* designation in inventory */
43         char    oartifact;      /* artifact array index */
44
45         xchar where;            /* where the object thinks it is */
46 #define OBJ_FREE        0               /* object not attached to anything */
47 #define OBJ_FLOOR       1               /* object on floor */
48 #define OBJ_CONTAINED   2               /* object in a container */
49 #define OBJ_INVENT      3               /* object in the hero's inventory */
50 #define OBJ_MINVENT     4               /* object in a monster inventory */
51 #define OBJ_MIGRATING   5               /* object sent off to another level */
52 #define OBJ_BURIED      6               /* object buried */
53 #define OBJ_ONBILL      7               /* object on shk bill */
54 #define NOBJ_STATES     8
55         xchar timed;            /* # of fuses (timers) attached to this obj */
56
57         Bitfield(cursed,1);
58         Bitfield(blessed,1);
59         Bitfield(unpaid,1);     /* on some bill */
60         Bitfield(no_charge,1);  /* if shk shouldn't charge for this */
61         Bitfield(known,1);      /* exact nature known */
62         Bitfield(dknown,1);     /* color or text known */
63         Bitfield(bknown,1);     /* blessing or curse known */
64         Bitfield(rknown,1);     /* rustproof or not known */
65
66         Bitfield(oeroded,2);    /* rusted/burnt weapon/armor */
67         Bitfield(oeroded2,2);   /* corroded/rotted weapon/armor */
68 #define greatest_erosion(otmp) (int)((otmp)->oeroded > (otmp)->oeroded2 ? (otmp)->oeroded : (otmp)->oeroded2)
69 #define MAX_ERODE 3
70 #define orotten oeroded         /* rotten food */
71 #define odiluted oeroded        /* diluted potions */
72 #define norevive oeroded2
73         Bitfield(oerodeproof,1); /* erodeproof weapon/armor */
74         Bitfield(olocked,1);    /* object is locked */
75         Bitfield(obroken,1);    /* lock has been broken */
76         Bitfield(otrapped,1);   /* container is trapped */
77                                 /* or accidental tripped rolling boulder trap */
78 #define opoisoned otrapped      /* object (weapon) is coated with poison */
79
80         Bitfield(recharged,3);  /* number of times it's been recharged */
81         Bitfield(lamplit,1);    /* a light-source -- can be lit */
82 #ifdef INVISIBLE_OBJECTS
83         Bitfield(oinvis,1);     /* invisible */
84 #endif
85         Bitfield(greased,1);    /* covered with grease */
86         Bitfield(oattached,2);  /* obj struct has special attachment */
87 #define OATTACHED_NOTHING 0
88 #define OATTACHED_MONST   1     /* monst struct in oextra */
89 #define OATTACHED_M_ID    2     /* monst id in oextra */
90 #define OATTACHED_UNUSED3 3
91
92         Bitfield(in_use,1);     /* for magic items before useup items */
93         Bitfield(bypass,1);     /* mark this as an object to be skipped by bhito() */
94         /* 6 free bits */
95
96         int     corpsenm;       /* type of corpse is mons[corpsenm] */
97 #define leashmon  corpsenm      /* gets m_id of attached pet */
98 #define spestudied corpsenm     /* # of times a spellbook has been studied */
99 #define fromsink  corpsenm      /* a potion from a sink */
100         unsigned oeaten;        /* nutrition left in food, if partly eaten */
101         long age;               /* creation date */
102
103         uchar onamelth;         /* length of name (following oxlth) */
104         short oxlth;            /* length of following data */
105         /* in order to prevent alignment problems oextra should
106            be (or follow) a long int */
107         long owornmask;
108         long oextra[1];         /* used for name of ordinary objects - length
109                                    is flexible; amount for tmp gold objects */
110 };
111
112 #define newobj(xl)      (struct obj *)alloc((unsigned)(xl) + sizeof(struct obj))
113 #define ONAME(otmp)     (((char *)(otmp)->oextra) + (otmp)->oxlth)
114
115 /* Weapons and weapon-tools */
116 /* KMH -- now based on skill categories.  Formerly:
117  *      #define is_sword(otmp)  (otmp->oclass == WEAPON_CLASS && \
118  *                       objects[otmp->otyp].oc_wepcat == WEP_SWORD)
119  *      #define is_blade(otmp)  (otmp->oclass == WEAPON_CLASS && \
120  *                       (objects[otmp->otyp].oc_wepcat == WEP_BLADE || \
121  *                        objects[otmp->otyp].oc_wepcat == WEP_SWORD))
122  *      #define is_weptool(o)   ((o)->oclass == TOOL_CLASS && \
123  *                       objects[(o)->otyp].oc_weptool)
124  *      #define is_multigen(otyp) (otyp <= SHURIKEN)
125  *      #define is_poisonable(otyp) (otyp <= BEC_DE_CORBIN)
126  */
127 #define is_blade(otmp)  (otmp->oclass == WEAPON_CLASS && \
128                          objects[otmp->otyp].oc_skill >= P_DAGGER && \
129                          objects[otmp->otyp].oc_skill <= P_SABER)
130 #define is_axe(otmp)    ((otmp->oclass == WEAPON_CLASS || \
131                          otmp->oclass == TOOL_CLASS) && \
132                          objects[otmp->otyp].oc_skill == P_AXE)
133 #define is_pick(otmp)   ((otmp->oclass == WEAPON_CLASS || \
134                          otmp->oclass == TOOL_CLASS) && \
135                          objects[otmp->otyp].oc_skill == P_PICK_AXE)
136 #define is_sword(otmp)  (otmp->oclass == WEAPON_CLASS && \
137                          objects[otmp->otyp].oc_skill >= P_SHORT_SWORD && \
138                          objects[otmp->otyp].oc_skill <= P_SABER)
139 #define is_pole(otmp)   ((otmp->oclass == WEAPON_CLASS || \
140                         otmp->oclass == TOOL_CLASS) && \
141                          (objects[otmp->otyp].oc_skill == P_POLEARMS || \
142                          objects[otmp->otyp].oc_skill == P_LANCE))
143 #define is_spear(otmp)  (otmp->oclass == WEAPON_CLASS && \
144                          objects[otmp->otyp].oc_skill >= P_SPEAR && \
145                          objects[otmp->otyp].oc_skill <= P_JAVELIN)
146 #define is_launcher(otmp)       (otmp->oclass == WEAPON_CLASS && \
147                          objects[otmp->otyp].oc_skill >= P_BOW && \
148                          objects[otmp->otyp].oc_skill <= P_CROSSBOW)
149 #define is_ammo(otmp)   ((otmp->oclass == WEAPON_CLASS || \
150                          otmp->oclass == GEM_CLASS) && \
151                          objects[otmp->otyp].oc_skill >= -P_CROSSBOW && \
152                          objects[otmp->otyp].oc_skill <= -P_BOW)
153 #define ammo_and_launcher(otmp,ltmp) \
154                          (is_ammo(otmp) && (ltmp) && \
155                          objects[(otmp)->otyp].oc_skill == -objects[(ltmp)->otyp].oc_skill)
156 #define is_missile(otmp)        ((otmp->oclass == WEAPON_CLASS || \
157                          otmp->oclass == TOOL_CLASS) && \
158                          objects[otmp->otyp].oc_skill >= -P_BOOMERANG && \
159                          objects[otmp->otyp].oc_skill <= -P_DART)
160 #define is_weptool(o)   ((o)->oclass == TOOL_CLASS && \
161                          objects[(o)->otyp].oc_skill != P_NONE)
162 #define bimanual(otmp)  ((otmp->oclass == WEAPON_CLASS || \
163                          otmp->oclass == TOOL_CLASS) && \
164                          objects[otmp->otyp].oc_bimanual)
165 #define is_multigen(otmp)       (otmp->oclass == WEAPON_CLASS && \
166                          objects[otmp->otyp].oc_skill >= -P_SHURIKEN && \
167                          objects[otmp->otyp].oc_skill <= -P_BOW)
168 #define is_poisonable(otmp)     (otmp->oclass == WEAPON_CLASS && \
169                          objects[otmp->otyp].oc_skill >= -P_SHURIKEN && \
170                          objects[otmp->otyp].oc_skill <= -P_BOW)
171 #define uslinging()     (uwep && objects[uwep->otyp].oc_skill == P_SLING)
172
173 /* Armor */
174 #define is_shield(otmp) (otmp->oclass == ARMOR_CLASS && \
175                          objects[otmp->otyp].oc_armcat == ARM_SHIELD)
176 #define is_helmet(otmp) (otmp->oclass == ARMOR_CLASS && \
177                          objects[otmp->otyp].oc_armcat == ARM_HELM)
178 #define is_boots(otmp)  (otmp->oclass == ARMOR_CLASS && \
179                          objects[otmp->otyp].oc_armcat == ARM_BOOTS)
180 #define is_gloves(otmp) (otmp->oclass == ARMOR_CLASS && \
181                          objects[otmp->otyp].oc_armcat == ARM_GLOVES)
182 #define is_cloak(otmp)  (otmp->oclass == ARMOR_CLASS && \
183                          objects[otmp->otyp].oc_armcat == ARM_CLOAK)
184 #define is_shirt(otmp)  (otmp->oclass == ARMOR_CLASS && \
185                          objects[otmp->otyp].oc_armcat == ARM_SHIRT)
186 #define is_suit(otmp)   (otmp->oclass == ARMOR_CLASS && \
187                          objects[otmp->otyp].oc_armcat == ARM_SUIT)
188 #define is_elven_armor(otmp)    ((otmp)->otyp == ELVEN_LEATHER_HELM\
189                                 || (otmp)->otyp == ELVEN_MITHRIL_COAT\
190                                 || (otmp)->otyp == ELVEN_CLOAK\
191                                 || (otmp)->otyp == ELVEN_SHIELD\
192                                 || (otmp)->otyp == ELVEN_BOOTS)
193 #define is_orcish_armor(otmp)   ((otmp)->otyp == ORCISH_HELM\
194                                 || (otmp)->otyp == ORCISH_CHAIN_MAIL\
195                                 || (otmp)->otyp == ORCISH_RING_MAIL\
196                                 || (otmp)->otyp == ORCISH_CLOAK\
197                                 || (otmp)->otyp == URUK_HAI_SHIELD\
198                                 || (otmp)->otyp == ORCISH_SHIELD)
199 #define is_dwarvish_armor(otmp) ((otmp)->otyp == DWARVISH_IRON_HELM\
200                                 || (otmp)->otyp == DWARVISH_MITHRIL_COAT\
201                                 || (otmp)->otyp == DWARVISH_CLOAK\
202                                 || (otmp)->otyp == DWARVISH_ROUNDSHIELD)
203 #define is_gnomish_armor(otmp)  (FALSE)
204
205                                 
206 /* Eggs and other food */
207 #define MAX_EGG_HATCH_TIME 200  /* longest an egg can remain unhatched */
208 #define stale_egg(egg)  ((monstermoves - (egg)->age) > (2*MAX_EGG_HATCH_TIME))
209 #define ofood(o) ((o)->otyp == CORPSE || (o)->otyp == EGG || (o)->otyp == TIN)
210 #define polyfodder(obj) (ofood(obj) && \
211                          pm_to_cham((obj)->corpsenm) != CHAM_ORDINARY)
212 #define mlevelgain(obj) (ofood(obj) && (obj)->corpsenm == PM_WRAITH)
213 #define mhealup(obj)    (ofood(obj) && (obj)->corpsenm == PM_NURSE)
214
215 /* Containers */
216 #define carried(o)      ((o)->where == OBJ_INVENT)
217 #define mcarried(o)     ((o)->where == OBJ_MINVENT)
218 #define Has_contents(o) (/* (Is_container(o) || (o)->otyp == STATUE) && */ \
219                          (o)->cobj != (struct obj *)0)
220 #define Is_container(o) ((o)->otyp >= LARGE_BOX && (o)->otyp <= BAG_OF_TRICKS)
221 #define Is_box(otmp)    (otmp->otyp == LARGE_BOX || otmp->otyp == CHEST)
222 #define Is_mbag(otmp)   (otmp->otyp == BAG_OF_HOLDING || \
223                          otmp->otyp == BAG_OF_TRICKS)
224
225 /* dragon gear */
226 #define Is_dragon_scales(obj)   ((obj)->otyp >= GRAY_DRAGON_SCALES && \
227                                  (obj)->otyp <= YELLOW_DRAGON_SCALES)
228 #define Is_dragon_mail(obj)     ((obj)->otyp >= GRAY_DRAGON_SCALE_MAIL && \
229                                  (obj)->otyp <= YELLOW_DRAGON_SCALE_MAIL)
230 #define Is_dragon_armor(obj)    (Is_dragon_scales(obj) || Is_dragon_mail(obj))
231 #define Dragon_scales_to_pm(obj) &mons[PM_GRAY_DRAGON + (obj)->otyp \
232                                        - GRAY_DRAGON_SCALES]
233 #define Dragon_mail_to_pm(obj)  &mons[PM_GRAY_DRAGON + (obj)->otyp \
234                                       - GRAY_DRAGON_SCALE_MAIL]
235 #define Dragon_to_scales(pm)    (GRAY_DRAGON_SCALES + (pm - mons))
236
237 /* Elven gear */
238 #define is_elven_weapon(otmp)   ((otmp)->otyp == ELVEN_ARROW\
239                                 || (otmp)->otyp == ELVEN_SPEAR\
240                                 || (otmp)->otyp == ELVEN_DAGGER\
241                                 || (otmp)->otyp == ELVEN_SHORT_SWORD\
242                                 || (otmp)->otyp == ELVEN_BROADSWORD\
243                                 || (otmp)->otyp == ELVEN_BOW)
244 #define is_elven_obj(otmp)      (is_elven_armor(otmp) || is_elven_weapon(otmp))
245
246 /* Orcish gear */
247 #define is_orcish_obj(otmp)     (is_orcish_armor(otmp)\
248                                 || (otmp)->otyp == ORCISH_ARROW\
249                                 || (otmp)->otyp == ORCISH_SPEAR\
250                                 || (otmp)->otyp == ORCISH_DAGGER\
251                                 || (otmp)->otyp == ORCISH_SHORT_SWORD\
252                                 || (otmp)->otyp == ORCISH_BOW)
253
254 /* Dwarvish gear */
255 #define is_dwarvish_obj(otmp)   (is_dwarvish_armor(otmp)\
256                                 || (otmp)->otyp == DWARVISH_SPEAR\
257                                 || (otmp)->otyp == DWARVISH_SHORT_SWORD\
258                                 || (otmp)->otyp == DWARVISH_MATTOCK)
259
260 /* Gnomish gear */
261 #define is_gnomish_obj(otmp)    (is_gnomish_armor(otmp))
262
263 /* Light sources */
264 #define Is_candle(otmp) (otmp->otyp == TALLOW_CANDLE || \
265                          otmp->otyp == WAX_CANDLE)
266 #define MAX_OIL_IN_FLASK 400    /* maximum amount of oil in a potion of oil */
267
268 /* MAGIC_LAMP intentionally excluded below */
269 /* age field of this is relative age rather than absolute */
270 #define age_is_relative(otmp)   ((otmp)->otyp == BRASS_LANTERN\
271                                 || (otmp)->otyp == OIL_LAMP\
272                                 || (otmp)->otyp == CANDELABRUM_OF_INVOCATION\
273                                 || (otmp)->otyp == TALLOW_CANDLE\
274                                 || (otmp)->otyp == WAX_CANDLE\
275                                 || (otmp)->otyp == POT_OIL)
276 /* object can be ignited */
277 #define ignitable(otmp) ((otmp)->otyp == BRASS_LANTERN\
278                                 || (otmp)->otyp == OIL_LAMP\
279                                 || (otmp)->otyp == CANDELABRUM_OF_INVOCATION\
280                                 || (otmp)->otyp == TALLOW_CANDLE\
281                                 || (otmp)->otyp == WAX_CANDLE\
282                                 || (otmp)->otyp == POT_OIL)
283
284 /* special stones */
285 #define is_graystone(obj)       ((obj)->otyp == LUCKSTONE || \
286                                  (obj)->otyp == LOADSTONE || \
287                                  (obj)->otyp == FLINT     || \
288                                  (obj)->otyp == TOUCHSTONE)
289
290 /* misc */
291 #ifdef KOPS
292 #define is_flimsy(otmp)         (objects[(otmp)->otyp].oc_material <= LEATHER || \
293                                  (otmp)->otyp == RUBBER_HOSE)
294 #else
295 #define is_flimsy(otmp)         (objects[(otmp)->otyp].oc_material <= LEATHER)
296 #endif
297
298 /* helpers, simple enough to be macros */
299 #define is_plural(o)    ((o)->quan > 1 || \
300                          (o)->oartifact == ART_EYES_OF_THE_OVERWORLD)
301
302 /* Flags for get_obj_location(). */
303 #define CONTAINED_TOO   0x1
304 #define BURIED_TOO      0x2
305
306 #endif /* OBJ_H */