OSDN Git Service

no bone
[nethackexpress/trunk.git] / include / display.h
1 /*      SCCS Id: @(#)display.h  3.4     1999/11/30      */
2 /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */
3 /* and Dave Cohrs, 1990.                                          */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 #ifndef DISPLAY_H
7 #define DISPLAY_H
8
9 #ifndef VISION_H
10 #include "vision.h"
11 #endif
12
13 #ifndef MONDATA_H
14 #include "mondata.h"    /* for mindless() */
15 #endif
16
17 #ifndef INVISIBLE_OBJECTS
18 #define vobj_at(x,y) (level.objects[x][y])
19 #endif
20
21 /*
22  * sensemon()
23  *
24  * Returns true if the hero can sense the given monster.  This includes
25  * monsters that are hiding or mimicing other monsters.
26  */
27 #define tp_sensemon(mon) (      /* The hero can always sense a monster IF:  */\
28     (!mindless(mon->data)) &&   /* 1. the monster has a brain to sense AND  */\
29       ((Blind && Blind_telepat) ||      /* 2a. hero is blind and telepathic OR      */\
30                                 /* 2b. hero is using a telepathy inducing   */\
31                                 /*       object and in range                */\
32       (Unblind_telepat &&                                             \
33         (distu(mon->mx, mon->my) <= (BOLT_LIM * BOLT_LIM))))                  \
34 )
35
36 #define sensemon(mon) (tp_sensemon(mon) || Detect_monsters || MATCH_WARN_OF_MON(mon))
37
38 /*
39  * mon_warning() is used to warn of any dangerous monsters in your
40  * vicinity, and a glyph representing the warning level is displayed.
41  */
42
43 #define mon_warning(mon) (Warning && !(mon)->mpeaceful &&                               \
44                          (distu((mon)->mx, (mon)->my) < 100) &&                         \
45                          (((int) ((mon)->m_lev / 4)) >= flags.warnlevel))
46
47 /*
48  * mon_visible()
49  *
50  * Returns true if the hero can see the monster.  It is assumed that the
51  * hero can physically see the location of the monster.  The function
52  * vobj_at() returns a pointer to an object that the hero can see there.
53  * Infravision is not taken into account.
54  */
55 #define mon_visible(mon) (              /* The hero can see the monster     */\
56                                         /* IF the monster                   */\
57     (!mon->minvis || See_invisible) &&  /* 1. is not invisible AND          */\
58     (!mon->mundetected) &&              /* 2. not an undetected hider       */\
59     (!(mon->mburied || u.uburied))      /* 3. neither you or it is buried   */\
60 )
61
62 /*
63  * see_with_infrared()
64  *
65  * This function is true if the player can see a monster using infravision.
66  * The caller must check for invisibility (invisible monsters are also
67  * invisible to infravision), because this is usually called from within
68  * canseemon() or canspotmon() which already check that.
69  */
70 #define see_with_infrared(mon) (!Blind && Infravision && infravisible(mon->data) && couldsee(mon->mx, mon->my))
71
72
73 /*
74  * canseemon()
75  *
76  * This is the globally used canseemon().  It is not called within the display
77  * routines.  Like mon_visible(), but it checks to see if the hero sees the
78  * location instead of assuming it.  (And also considers worms.)
79  */
80 #define canseemon(mon) ((mon->wormno ? worm_known(mon) : \
81             (cansee(mon->mx, mon->my) || see_with_infrared(mon))) \
82         && mon_visible(mon))
83
84
85 /*
86  * canspotmon(mon)
87  *
88  * This function checks whether you can either see a monster or sense it by
89  * telepathy, and is what you usually call for monsters about which nothing is
90  * known.
91  */
92 #define canspotmon(mon) \
93         (canseemon(mon) || sensemon(mon))
94
95 /* knowninvisible(mon)
96  * This one checks to see if you know a monster is both there and invisible.
97  * 1) If you can see the monster and have see invisible, it is assumed the
98  * monster is transparent, but visible in some manner.  (Earlier versions of
99  * Nethack were really inconsistent on this.)
100  * 2) If you can't see the monster, but can see its location and you have
101  * telepathy that works when you can see, you can tell that there is a
102  * creature in an apparently empty spot.
103  * Infravision is not relevant; we assume that invisible monsters are also
104  * invisible to infravision.
105  */
106 #define knowninvisible(mon) \
107         (mtmp->minvis && \
108             ((cansee(mon->mx, mon->my) && (See_invisible || Detect_monsters)) || \
109                 (!Blind && (HTelepat & ~INTRINSIC) && \
110                     distu(mon->mx, mon->my) <= (BOLT_LIM * BOLT_LIM) \
111                 ) \
112             ) \
113         )
114
115 /*
116  * is_safepet(mon)
117  *
118  * A special case check used in attack() and domove().  Placing the
119  * definition here is convenient.
120  */
121 #define is_safepet(mon) \
122         (mon && mon->mtame && canspotmon(mon) && flags.safe_dog \
123                 && !Confusion && !Hallucination && !Stunned)
124
125
126 /*
127  * canseeself()
128  * senseself()
129  *
130  * This returns true if the hero can see her/himself.
131  *
132  * The u.uswallow check assumes that you can see yourself even if you are
133  * invisible.  If not, then we don't need the check.
134  */
135 #define canseeself()    (Blind || u.uswallow || (!Invisible && !u.uundetected))
136 #define senseself()     (canseeself() || Unblind_telepat || Detect_monsters)
137
138 /*
139  * random_monster()
140  * random_object()
141  * random_trap()
142  *
143  * Respectively return a random monster, object, or trap number.
144  */
145 #define random_monster() rn2(NUMMONS)
146 #define random_object()  rn1(NUM_OBJECTS-1,1)
147 #define random_trap()    rn1(TRAPNUM-1,1)
148
149 /*
150  * what_obj()
151  * what_mon()
152  * what_trap()
153  *
154  * If hallucinating, choose a random object/monster, otherwise, use the one
155  * given.
156  */
157 #define what_obj(obj)   (Hallucination ? random_object()  : obj)
158 #define what_mon(mon)   (Hallucination ? random_monster() : mon)
159 #define what_trap(trp)  (Hallucination ? random_trap()    : trp)
160
161 /*
162  * covers_objects()
163  * covers_traps()
164  *
165  * These routines are true if what is really at the given location will
166  * "cover" any objects or traps that might be there.
167  */
168 #define covers_objects(xx,yy)                                                 \
169     ((is_pool(xx,yy) && !Underwater) || (levl[xx][yy].typ == LAVAPOOL))
170
171 #define covers_traps(xx,yy)     covers_objects(xx,yy)
172
173
174 /*
175  * tmp_at() control calls.
176  */
177 #define DISP_BEAM    (-1)  /* Keep all glyphs showing & clean up at end. */
178 #define DISP_FLASH   (-2)  /* Clean up each glyph before displaying new one. */
179 #define DISP_ALWAYS  (-3)  /* Like flash, but still displayed if not visible. */
180 #define DISP_CHANGE  (-4)  /* Change glyph. */
181 #define DISP_END     (-5)  /* Clean up. */
182 #define DISP_FREEMEM (-6)  /* Free all memory during exit only. */
183
184
185 /* Total number of cmap indices in the sheild_static[] array. */
186 #define SHIELD_COUNT 21
187
188
189 /*
190  * display_self()
191  *
192  * Display the hero.  It is assumed that all checks necessary to determine
193  * _if_ the hero can be seen have already been done.
194  */
195 #ifdef STEED
196 #define maybe_display_usteed    (u.usteed && mon_visible(u.usteed)) ? \
197                                         ridden_mon_to_glyph(u.usteed) :
198 #else
199 #define maybe_display_usteed    /* empty */
200 #endif
201
202 #define display_self()                                                  \
203     show_glyph(u.ux, u.uy,                                              \
204         maybe_display_usteed                    /* else */              \
205         youmonst.m_ap_type == M_AP_NOTHING ?                            \
206                                 hero_glyph :                            \
207         youmonst.m_ap_type == M_AP_FURNITURE ?                          \
208                                 cmap_to_glyph(youmonst.mappearance) :   \
209         youmonst.m_ap_type == M_AP_OBJECT ?                             \
210                                 objnum_to_glyph(youmonst.mappearance) : \
211         /* else M_AP_MONSTER */ monnum_to_glyph(youmonst.mappearance))
212
213 /*
214  * A glyph is an abstraction that represents a _unique_ monster, object,
215  * dungeon part, or effect.  The uniqueness is important.  For example,
216  * It is not enough to have four (one for each "direction") zap beam glyphs,
217  * we need a set of four for each beam type.  Why go to so much trouble?
218  * Because it is possible that any given window dependent display driver
219  * [print_glyph()] can produce something different for each type of glyph.
220  * That is, a beam of cold and a beam of fire would not only be different
221  * colors, but would also be represented by different symbols.
222  *
223  * Glyphs are grouped for easy accessibility:
224  *
225  * monster      Represents all the wild (not tame) monsters.  Count: NUMMONS.
226  *
227  * pet          Represents all of the tame monsters.  Count: NUMMONS
228  *
229  * invisible    Invisible monster placeholder.  Count: 1
230  *
231  * detect       Represents all detected monsters.  Count: NUMMONS
232  *
233  * corpse       One for each monster.  Count: NUMMONS
234  *
235  * ridden       Represents all monsters being ridden.  Count: NUMMONS 
236  *
237  * object       One for each object.  Count: NUM_OBJECTS
238  *
239  * cmap         One for each entry in the character map.  The character map
240  *              is the dungeon features and other miscellaneous things.
241  *              Count: MAXPCHARS
242  *
243  * explosions   A set of nine for each of the following seven explosion types:
244  *                   dark, noxious, muddy, wet, magical, fiery, frosty.
245  *              The nine positions represent those surrounding the hero.
246  *              Count: MAXEXPCHARS * EXPL_MAX (EXPL_MAX is defined in hack.h)
247  *
248  * zap beam     A set of four (there are four directions) for each beam type.
249  *              The beam type is shifted over 2 positions and the direction
250  *              is stored in the lower 2 bits.  Count: NUM_ZAP << 2
251  *
252  * swallow      A set of eight for each monster.  The eight positions rep-
253  *              resent those surrounding the hero.  The monster number is
254  *              shifted over 3 positions and the swallow position is stored
255  *              in the lower three bits.  Count: NUMMONS << 3
256  *
257  * warning      A set of six representing the different warning levels.
258  *
259  * The following are offsets used to convert to and from a glyph.
260  */
261 #define NUM_ZAP 8       /* number of zap beam types */
262
263 #define GLYPH_MON_OFF           0
264 #define GLYPH_PET_OFF           (NUMMONS        + GLYPH_MON_OFF)
265 #define GLYPH_INVIS_OFF         (NUMMONS        + GLYPH_PET_OFF)
266 #define GLYPH_DETECT_OFF        (1              + GLYPH_INVIS_OFF)
267 #define GLYPH_BODY_OFF          (NUMMONS        + GLYPH_DETECT_OFF)
268 #define GLYPH_RIDDEN_OFF        (NUMMONS        + GLYPH_BODY_OFF)
269 #define GLYPH_OBJ_OFF           (NUMMONS        + GLYPH_RIDDEN_OFF)
270 #define GLYPH_CMAP_OFF          (NUM_OBJECTS    + GLYPH_OBJ_OFF)
271 #define GLYPH_EXPLODE_OFF       ((MAXPCHARS - MAXEXPCHARS) + GLYPH_CMAP_OFF)
272 #define GLYPH_ZAP_OFF           ((MAXEXPCHARS * EXPL_MAX) + GLYPH_EXPLODE_OFF)
273 #define GLYPH_SWALLOW_OFF       ((NUM_ZAP << 2) + GLYPH_ZAP_OFF)
274 #define GLYPH_WARNING_OFF       ((NUMMONS << 3) + GLYPH_SWALLOW_OFF)
275 #define MAX_GLYPH               (WARNCOUNT      + GLYPH_WARNING_OFF)
276
277 #define NO_GLYPH MAX_GLYPH
278
279 #define GLYPH_INVISIBLE GLYPH_INVIS_OFF
280
281 #define warning_to_glyph(mwarnlev) ((mwarnlev)+GLYPH_WARNING_OFF)
282 #define mon_to_glyph(mon) ((int) what_mon(monsndx((mon)->data))+GLYPH_MON_OFF)
283 #define detected_mon_to_glyph(mon) ((int) what_mon(monsndx((mon)->data))+GLYPH_DETECT_OFF)
284 #define ridden_mon_to_glyph(mon) ((int) what_mon(monsndx((mon)->data))+GLYPH_RIDDEN_OFF)
285 #define pet_to_glyph(mon) ((int) what_mon(monsndx((mon)->data))+GLYPH_PET_OFF)
286
287 /* This has the unfortunate side effect of needing a global variable    */
288 /* to store a result. 'otg_temp' is defined and declared in decl.{ch}.  */
289 #define obj_to_glyph(obj)                                                     \
290     (Hallucination ?                                                          \
291         ((otg_temp = random_object()) == CORPSE ?                             \
292             random_monster() + GLYPH_BODY_OFF :                               \
293             otg_temp + GLYPH_OBJ_OFF)   :                                     \
294         ((obj)->otyp == CORPSE ?                                              \
295             (int) (obj)->corpsenm + GLYPH_BODY_OFF :                          \
296             (int) (obj)->otyp + GLYPH_OBJ_OFF))
297
298 #define cmap_to_glyph(cmap_idx) ((int) (cmap_idx)   + GLYPH_CMAP_OFF)
299 #define explosion_to_glyph(expltype,idx)        \
300                 ((((expltype) * MAXEXPCHARS) + ((idx) - S_explode1)) + GLYPH_EXPLODE_OFF)
301
302 #define trap_to_glyph(trap)     \
303                         cmap_to_glyph(trap_to_defsym(what_trap((trap)->ttyp)))
304
305 /* Not affected by hallucination.  Gives a generic body for CORPSE */
306 #define objnum_to_glyph(onum)   ((int) (onum) + GLYPH_OBJ_OFF)
307 #define monnum_to_glyph(mnum)   ((int) (mnum) + GLYPH_MON_OFF)
308 #define detected_monnum_to_glyph(mnum)  ((int) (mnum) + GLYPH_DETECT_OFF)
309 #define ridden_monnum_to_glyph(mnum)    ((int) (mnum) + GLYPH_RIDDEN_OFF)
310 #define petnum_to_glyph(mnum)   ((int) (mnum) + GLYPH_PET_OFF)
311
312 /* The hero's glyph when seen as a monster.
313  */
314 #define hero_glyph \
315         monnum_to_glyph((Upolyd || !iflags.showrace) ? u.umonnum : \
316                         (flags.female && urace.femalenum != NON_PM) ? urace.femalenum : \
317                         urace.malenum)
318
319
320 /*
321  * Change the given glyph into it's given type.  Note:
322  *      1) Pets, detected, and ridden monsters are animals and are converted
323  *         to the proper monster number.
324  *      2) Bodies are all mapped into the generic CORPSE object
325  *      3) If handed a glyph out of range for the type, these functions
326  *         will return NO_GLYPH (see exception below)
327  *      4) glyph_to_swallow() does not return a showsyms[] index, but an
328  *         offset from the first swallow symbol.  If handed something
329  *         out of range, it will return zero (for lack of anything better
330  *         to return).
331  */
332 #define glyph_to_mon(glyph)                                             \
333         (glyph_is_normal_monster(glyph) ? ((glyph)-GLYPH_MON_OFF) :     \
334         glyph_is_pet(glyph) ? ((glyph)-GLYPH_PET_OFF) :                 \
335         glyph_is_detected_monster(glyph) ? ((glyph)-GLYPH_DETECT_OFF) : \
336         glyph_is_ridden_monster(glyph) ? ((glyph)-GLYPH_RIDDEN_OFF) :   \
337         NO_GLYPH)
338 #define glyph_to_obj(glyph)                                             \
339         (glyph_is_body(glyph) ? CORPSE :                                \
340         glyph_is_normal_object(glyph) ? ((glyph)-GLYPH_OBJ_OFF) :       \
341         NO_GLYPH)
342 #define glyph_to_trap(glyph)                                            \
343         (glyph_is_trap(glyph) ?                                         \
344                 ((int) defsym_to_trap((glyph) - GLYPH_CMAP_OFF)) :      \
345         NO_GLYPH)
346 #define glyph_to_cmap(glyph)                                            \
347         (glyph_is_cmap(glyph) ? ((glyph) - GLYPH_CMAP_OFF) :            \
348         NO_GLYPH)
349 #define glyph_to_swallow(glyph)                                         \
350         (glyph_is_swallow(glyph) ? (((glyph) - GLYPH_SWALLOW_OFF) & 0x7) : \
351         0)
352 #define glyph_to_warning(glyph)                                         \
353         (glyph_is_warning(glyph) ? ((glyph) - GLYPH_WARNING_OFF) :      \
354         NO_GLYPH);
355
356 /*
357  * Return true if the given glyph is what we want.  Note that bodies are
358  * considered objects.
359  */
360 #define glyph_is_monster(glyph)                                         \
361                 (glyph_is_normal_monster(glyph)                         \
362                 || glyph_is_pet(glyph)                                  \
363                 || glyph_is_ridden_monster(glyph)                       \
364                 || glyph_is_detected_monster(glyph))
365 #define glyph_is_normal_monster(glyph)                                  \
366     ((glyph) >= GLYPH_MON_OFF && (glyph) < (GLYPH_MON_OFF+NUMMONS))
367 #define glyph_is_pet(glyph)                                             \
368     ((glyph) >= GLYPH_PET_OFF && (glyph) < (GLYPH_PET_OFF+NUMMONS))
369 #define glyph_is_body(glyph)                                            \
370     ((glyph) >= GLYPH_BODY_OFF && (glyph) < (GLYPH_BODY_OFF+NUMMONS))
371 #define glyph_is_ridden_monster(glyph)                                  \
372     ((glyph) >= GLYPH_RIDDEN_OFF && (glyph) < (GLYPH_RIDDEN_OFF+NUMMONS))
373 #define glyph_is_detected_monster(glyph)                                \
374     ((glyph) >= GLYPH_DETECT_OFF && (glyph) < (GLYPH_DETECT_OFF+NUMMONS))
375 #define glyph_is_invisible(glyph) ((glyph) == GLYPH_INVISIBLE)
376 #define glyph_is_normal_object(glyph)                                   \
377     ((glyph) >= GLYPH_OBJ_OFF && (glyph) < (GLYPH_OBJ_OFF+NUM_OBJECTS))
378 #define glyph_is_object(glyph)                                          \
379                 (glyph_is_normal_object(glyph)                          \
380                 || glyph_is_body(glyph))
381 #define glyph_is_trap(glyph)                                            \
382     ((glyph) >= (GLYPH_CMAP_OFF+trap_to_defsym(1)) &&                   \
383      (glyph) <  (GLYPH_CMAP_OFF+trap_to_defsym(1)+TRAPNUM))
384 #define glyph_is_cmap(glyph)                                            \
385     ((glyph) >= GLYPH_CMAP_OFF && (glyph) < (GLYPH_CMAP_OFF+MAXPCHARS))
386 #define glyph_is_swallow(glyph) \
387     ((glyph) >= GLYPH_SWALLOW_OFF && (glyph) < (GLYPH_SWALLOW_OFF+(NUMMONS << 3)))
388 #define glyph_is_warning(glyph) \
389     ((glyph) >= GLYPH_WARNING_OFF && (glyph) < (GLYPH_WARNING_OFF + WARNCOUNT))
390 #endif /* DISPLAY_H */