OSDN Git Service

[Refactor] #38997 no_lite() に player_type * 引数を追加. / Add player_type * argument to...
[hengband/hengband.git] / src / grid.h
1 #pragma once
2
3 /*!
4  * @file grid.h
5  * @brief ダンジョンの生成処理の基幹部分ヘッダーファイル
6  * @date 2014/08/15
7  * @details
8  * Purpose: header file for grid.c, used only in dungeon generation
9  * files (generate.c, rooms.c)
10  * @author
11  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
12  * This software may be copied and distributed for educational, research, and
13  * not for profit purposes provided that this copyright and statement are
14  * included in all such copies.
15  */
16
17
18  /*
19   * A single "grid" in a Cave
20   *
21   * Note that several aspects of the code restrict the actual grid
22   * to a max size of 256 by 256.  In partcular, locations are often
23   * saved as bytes, limiting each coordinate to the 0-255 range.
24   *
25   * The "o_idx" and "m_idx" fields are very interesting.  There are
26   * many places in the code where we need quick access to the actual
27   * monster or object(s) in a given grid.  The easiest way to
28   * do this is to simply keep the index of the monster and object
29   * (if any) with the grid, but this takes 198*66*4 bytes of memory.
30   * Several other methods come to mind, which require only half this
31   * amound of memory, but they all seem rather complicated, and would
32   * probably add enough code that the savings would be lost.  So for
33   * these reasons, we simply store an index into the "o_list" and
34   * ">m_list" arrays, using "zero" when no monster/object is present.
35   *
36   * Note that "o_idx" is the index of the top object in a stack of
37   * objects, using the "next_o_idx" field of objects (see below) to
38   * create the singly linked list of objects.  If "o_idx" is zero
39   * then there are no objects in the grid.
40   *
41   * Note the special fields for the "MONSTER_FLOW" code.
42   */
43
44 typedef struct player_type player_type; // TODO: Delete Finally.
45
46 typedef struct grid_type grid_type;
47
48 struct grid_type
49 {
50         BIT_FLAGS info;         /* Hack -- grid flags */
51
52         FEAT_IDX feat;          /* Hack -- feature type */
53         OBJECT_IDX o_idx;               /* Object in this grid */
54         MONSTER_IDX m_idx;              /* Monster in this grid */
55
56         /*! 地形の特別な情報を保存する / Special grid info
57          * 具体的な使用一覧はクエスト行き階段の移行先クエストID、
58          * 各ダンジョン入口の移行先ダンジョンID、
59          *
60          */
61         s16b special;
62
63         FEAT_IDX mimic;         /* Feature to mimic */
64
65         byte cost;              /* Hack -- cost of flowing */
66         byte dist;              /* Hack -- distance from player */
67         byte when;              /* Hack -- when cost was computed */
68 };
69
70 /*
71  *  A structure type for terrain template of saving dungeon floor
72  */
73 typedef struct
74 {
75         BIT_FLAGS info;
76         FEAT_IDX feat;
77         FEAT_IDX mimic;
78         s16b special;
79         u16b occurrence;
80 } grid_template_type;
81
82 #define feat_locked_door_random(DOOR_TYPE) \
83         (feat_door[(DOOR_TYPE)].num_locked ? \
84          feat_door[(DOOR_TYPE)].locked[randint0(feat_door[(DOOR_TYPE)].num_locked)] : feat_none)
85
86 #define feat_jammed_door_random(DOOR_TYPE) \
87         (feat_door[(DOOR_TYPE)].num_jammed ? \
88          feat_door[(DOOR_TYPE)].jammed[randint0(feat_door[(DOOR_TYPE)].num_jammed)] : feat_none)
89
90 /* Macros */
91 #define set_cave_feat(FL,Y,X,F)    ((FL)->grid_array[(Y)][(X)].feat = (F))
92 #define add_cave_info(FL,Y,X,I)    ((FL)->grid_array[(Y)][(X)].info |= (I))
93
94 /*!
95  * @brief 指定座標に瓦礫を配置する
96  * @param Y 指定Y座標
97  * @param X 指定X座標
98  */
99 #define place_rubble(F,Y,X)       set_cave_feat(F,Y,X,feat_rubble)
100
101 /*!
102  * @brief 指定座標がFLOOR属性を持ったマスかどうかを返す
103  * @param Y 指定Y座標
104  * @param X 指定X座標
105  * @return FLOOR属性を持っているならばTRUE
106  */
107 #define is_floor_bold(F,Y,X) (F->grid_array[Y][X].info & CAVE_FLOOR)
108 #define is_extra_bold(F,Y,X) (F->grid_array[Y][X].info & CAVE_EXTRA)
109
110 #define is_inner_bold(F,Y,X) (F->grid_array[Y][X].info & CAVE_INNER)
111 #define is_outer_bold(F,Y,X) (F->grid_array[Y][X].info & CAVE_OUTER)
112 #define is_solid_bold(F,Y,X) (F->grid_array[Y][X].info & CAVE_SOLID)
113
114 #define is_floor_grid(C) ((C)->info & CAVE_FLOOR)
115 #define is_extra_grid(C) ((C)->info & CAVE_EXTRA)
116 #define is_inner_grid(C) ((C)->info & CAVE_INNER)
117 #define is_outer_grid(C) ((C)->info & CAVE_OUTER)
118 #define is_solid_grid(C) ((C)->info & CAVE_SOLID)
119
120 #define place_floor_bold(F, Y, X) \
121 { \
122         set_cave_feat((F), Y,X,feat_ground_type[randint0(100)]); \
123         (F)->grid_array[Y][X].info &= ~(CAVE_MASK); \
124         add_cave_info((F), Y,X,CAVE_FLOOR); \
125         delete_monster(F, Y, X); \
126 }
127
128 #define place_floor_grid(C) \
129 { \
130         (C)->feat = feat_ground_type[randint0(100)]; \
131         (C)->info &= ~(CAVE_MASK); \
132         (C)->info |= CAVE_FLOOR; \
133         if ((C)->m_idx) delete_monster_idx((C)->m_idx); \
134 }
135
136 #define place_extra_bold(F, Y, X) \
137 { \
138         set_cave_feat((F), Y,X,feat_wall_type[randint0(100)]); \
139         (F)->grid_array[Y][X].info &= ~(CAVE_MASK); \
140         add_cave_info((F), Y,X,CAVE_EXTRA); \
141         delete_monster(F, Y, X); \
142 }
143
144 #define place_extra_grid(C) \
145 { \
146         (C)->feat = feat_wall_type[randint0(100)]; \
147         (C)->info &= ~(CAVE_MASK); \
148         (C)->info |= CAVE_EXTRA; \
149         if ((C)->m_idx) delete_monster_idx((C)->m_idx); \
150 }
151
152 #define place_extra_perm_bold(F, Y, X) \
153 { \
154         set_cave_feat(F, Y, X,feat_permanent); \
155         (F)->grid_array[Y][X].info &= ~(CAVE_MASK); \
156         add_cave_info(F, Y, X, CAVE_EXTRA); \
157         delete_monster(F, Y, X); \
158 }
159
160 #define place_extra_perm_grid(C) \
161 { \
162         (C)->feat = feat_permanent; \
163         (C)->info &= ~(CAVE_MASK); \
164         (C)->info |= CAVE_EXTRA; \
165         if ((C)->m_idx) delete_monster_idx((C)->m_idx); \
166 }
167
168 #define place_extra_noperm_bold(F, Y, X) \
169 { \
170         feature_type *_f_ptr; \
171         set_cave_feat((F), Y,X,feat_wall_type[randint0(100)]); \
172         _f_ptr = &f_info[(F)->grid_array[Y][X].feat]; \
173         if (permanent_wall(_f_ptr)) (F)->grid_array[Y][X].feat = feat_state((F)->grid_array[Y][X].feat, FF_UNPERM); \
174         (F)->grid_array[Y][X].info &= ~(CAVE_MASK); \
175         add_cave_info((F), Y, X, CAVE_EXTRA); \
176         delete_monster(Y, X); \
177 }
178
179 #define place_inner_bold(F, Y, X) \
180 { \
181         set_cave_feat((F), Y, X, feat_wall_inner); \
182         (F)->grid_array[Y][X].info &= ~(CAVE_MASK); \
183         add_cave_info((F), Y, X, CAVE_INNER); \
184         delete_monster(F, Y, X); \
185 }
186
187 #define place_inner_grid(C) \
188 { \
189         (C)->feat = feat_wall_inner; \
190         (C)->info &= ~(CAVE_MASK); \
191         (C)->info |= CAVE_INNER; \
192         if ((C)->m_idx) delete_monster_idx((C)->m_idx); \
193 }
194
195 #define place_inner_perm_bold(F, Y, X) \
196 { \
197         set_cave_feat(F, Y,X,feat_permanent); \
198         (F)->grid_array[Y][X].info &= ~(CAVE_MASK); \
199         add_cave_info((F), Y,X,CAVE_INNER); \
200         delete_monster(F, Y, X); \
201 }
202
203 #define place_inner_perm_grid(C) \
204 { \
205         (C)->feat = feat_permanent; \
206         (C)->info &= ~(CAVE_MASK); \
207         (C)->info |= CAVE_INNER; \
208         if ((C)->m_idx) delete_monster_idx((C)->m_idx); \
209 }
210
211 #define place_outer_bold(F, Y, X) \
212 { \
213         set_cave_feat((F), Y, X, feat_wall_outer); \
214         (F)->grid_array[Y][X].info &= ~(CAVE_MASK); \
215         add_cave_info((F), Y,X,CAVE_OUTER); \
216         delete_monster(F, Y, X); \
217 }
218
219 #define place_outer_grid(C) \
220 { \
221         (C)->feat = feat_wall_outer; \
222         (C)->info &= ~(CAVE_MASK); \
223         (C)->info |= CAVE_OUTER; \
224         if ((C)->m_idx) delete_monster_idx((C)->m_idx); \
225 }
226
227 #define place_outer_perm_bold(F, Y, X) \
228 { \
229         set_cave_feat(F, Y, X, feat_permanent); \
230         (F)->grid_array[Y][X].info &= ~(CAVE_MASK); \
231         add_cave_info((F), Y,X,CAVE_OUTER); \
232         delete_monster(F, Y, X); \
233 }
234
235 #define place_outer_perm_grid(C) \
236 { \
237         (C)->feat = feat_permanent; \
238         (C)->info &= ~(CAVE_MASK); \
239         (C)->info |= CAVE_OUTER; \
240         if ((C)->m_idx) delete_monster_idx((C)->m_idx); \
241 }
242
243 #define place_outer_noperm_bold(F, Y, X) \
244 { \
245         feature_type *_f_ptr = &f_info[feat_wall_outer]; \
246         if (permanent_wall(_f_ptr)) set_cave_feat((F), Y, X, (s16b)feat_state(feat_wall_outer, FF_UNPERM)); \
247         else set_cave_feat((F), Y,X,feat_wall_outer); \
248         (F)->grid_array[Y][X].info &= ~(CAVE_MASK); \
249         add_cave_info((F), Y,X,(CAVE_OUTER | CAVE_VAULT)); \
250         delete_monster(F, Y, X); \
251 }
252
253 #define place_outer_noperm_grid(C) \
254 { \
255         feature_type *_f_ptr = &f_info[feat_wall_outer]; \
256         if (permanent_wall(_f_ptr)) (C)->feat = (s16b)feat_state(feat_wall_outer, FF_UNPERM); \
257         else (C)->feat = feat_wall_outer; \
258         (C)->info &= ~(CAVE_MASK); \
259         (C)->info |= (CAVE_OUTER | CAVE_VAULT); \
260         if ((C)->m_idx) delete_monster_idx((C)->m_idx); \
261 }
262
263 #define place_solid_bold(F, Y, X) \
264 { \
265         set_cave_feat(F,Y,X,feat_wall_solid); \
266         F->grid_array[Y][X].info &= ~(CAVE_MASK); \
267         add_cave_info(F,Y,X,CAVE_SOLID); \
268         delete_monster(F, Y, X); \
269 }
270
271 #define place_solid_grid(C) \
272 { \
273         (C)->feat = feat_wall_solid; \
274         (C)->info &= ~(CAVE_MASK); \
275         (C)->info |= CAVE_SOLID; \
276         if ((C)->m_idx) delete_monster_idx((C)->m_idx); \
277 }
278
279 #define place_solid_perm_bold(F, Y, X) \
280 { \
281         set_cave_feat(F, Y, X, feat_permanent); \
282         F->grid_array[Y][X].info &= ~(CAVE_MASK); \
283         add_cave_info(F, Y, X, CAVE_SOLID); \
284         delete_monster(F, Y, X); \
285 }
286
287 #define place_solid_perm_grid(C) \
288 { \
289         (C)->feat = feat_permanent; \
290         (C)->info &= ~(CAVE_MASK); \
291         (C)->info |= CAVE_SOLID; \
292         if ((C)->m_idx) delete_monster_idx((C)->m_idx); \
293 }
294
295 #define place_solid_noperm_bold(Y, X) \
296 { \
297         feature_type *_f_ptr = &f_info[feat_wall_solid]; \
298         if ((p_ptr->current_floor_ptr->grid_array[Y][X].info & CAVE_VAULT) && permanent_wall(_f_ptr)) \
299                 set_cave_feat(p_ptr->current_floor_ptr, Y, X, feat_state(feat_wall_solid, FF_UNPERM)); \
300         else set_cave_feat(p_ptr->current_floor_ptr, Y,X,feat_wall_solid); \
301         p_ptr->current_floor_ptr->grid_array[Y][X].info &= ~(CAVE_MASK); \
302         add_cave_info(p_ptr->current_floor_ptr, Y,X,CAVE_SOLID); \
303         delete_monster(p_ptr->current_floor_ptr, Y, X); \
304 }
305
306 #define place_solid_noperm_grid(C) \
307 { \
308         feature_type *_f_ptr = &f_info[feat_wall_solid]; \
309         if (((C)->info & CAVE_VAULT) && permanent_wall(_f_ptr)) \
310                 (C)->feat = feat_state(feat_wall_solid, FF_UNPERM); \
311         else (C)->feat = feat_wall_solid; \
312         (C)->info &= ~(CAVE_MASK); \
313         (C)->info |= CAVE_SOLID; \
314         if ((C)->m_idx) delete_monster_idx((C)->m_idx); \
315 }
316
317
318 /*
319  * 特殊なマス状態フラグ / Special grid flags
320  */
321 #define CAVE_MARK       0x0001    /*!< 現在プレイヤーの記憶に収まっている / memorized feature */
322 #define CAVE_GLOW       0x0002    /*!< マス自体が光源を持っている / self-illuminating */
323 #define CAVE_ICKY       0x0004    /*!< 生成されたVaultの一部である / part of a vault */
324 #define CAVE_ROOM       0x0008    /*!< 生成された部屋の一部である / part of a room */
325 #define CAVE_LITE       0x0010    /*!< 現在光に照らされている / lite flag  */
326 #define CAVE_VIEW       0x0020    /*!< 現在プレイヤーの視界に収まっている / view flag */
327 #define CAVE_TEMP       0x0040    /*!< 光源に関する処理のアルゴリズム用記録フラグ / temp flag */
328 #define CAVE_XTRA       0x0080    /*!< 視界に関する処理のアルゴリズム用記録フラグ(update_view()等参照) / misc flag */
329 #define CAVE_MNLT       0x0100    /*!< モンスターの光源によって照らされている / Illuminated by monster */
330 #define CAVE_MNDK       0x8000    /*!< モンスターの暗源によって暗闇になっている / Darken by monster */
331
332  /* Used only while floor generation */
333 #define CAVE_FLOOR      0x0200  /*!< フロア属性のあるマス */
334 #define CAVE_EXTRA      0x0400
335 #define CAVE_INNER      0x0800
336 #define CAVE_OUTER      0x1000
337 #define CAVE_SOLID      0x2000
338 #define CAVE_VAULT      0x4000
339 #define CAVE_MASK (CAVE_FLOOR | CAVE_EXTRA | CAVE_INNER | CAVE_OUTER | CAVE_SOLID | CAVE_VAULT)
340
341 /* Used only after floor generation */
342 #define CAVE_KNOWN      0x0200    /* Directly viewed or map detected flag */
343 #define CAVE_NOTE       0x0400    /* Flag for delayed visual update (needs note_spot()) */
344 #define CAVE_REDRAW     0x0800    /* Flag for delayed visual update (needs lite_spot()) */
345 #define CAVE_OBJECT     0x1000    /* Mirror, glyph, etc. */
346 #define CAVE_UNSAFE     0x2000    /* Might have trap */
347 #define CAVE_IN_DETECT  0x4000    /* trap detected area (inner circle only) */
348
349 /* Types of conversions */
350 #define CONVERT_TYPE_FLOOR   0
351 #define CONVERT_TYPE_WALL    1
352 #define CONVERT_TYPE_INNER   2
353 #define CONVERT_TYPE_OUTER   3
354 #define CONVERT_TYPE_SOLID   4
355 #define CONVERT_TYPE_STREAM1 5
356 #define CONVERT_TYPE_STREAM2 6
357
358 /* Externs */
359
360 extern bool new_player_spot(player_type *creature_ptr);
361
362 /* Types of doors */
363 #define DOOR_DEFAULT    -1
364 #define DOOR_DOOR        0
365 #define DOOR_GLASS_DOOR  1
366 #define DOOR_CURTAIN     2
367
368 #define MAX_DOOR_TYPES   3
369
370 extern void vault_traps(POSITION y, POSITION x, POSITION yd, POSITION xd, int num);
371
372 extern void place_bound_perm_wall(grid_type *g_ptr);
373
374 extern bool is_known_trap(grid_type *g_ptr);
375 extern bool is_hidden_door(grid_type *g_ptr);
376 extern bool is_mirror_grid(grid_type *g_ptr);
377 extern bool is_glyph_grid(grid_type *g_ptr);
378 extern bool is_explosive_rune_grid(grid_type *g_ptr);
379
380 extern bool player_can_enter(player_type *creature_ptr, FEAT_IDX feature, BIT_FLAGS16 mode);
381
382 /*!
383  * マス構造体のspecial要素を利用する地形かどうかを判定するマクロ / Is this feature has special meaning (except floor_id) with g_ptr->special?
384  */
385 #define feat_uses_special(F) (have_flag(f_info[(F)].flags, FF_SPECIAL))
386
387 /* grids.c */
388 extern POSITION distance(POSITION y1, POSITION x1, POSITION y2, POSITION x2);
389 extern void update_local_illumination(player_type *creature_ptr, POSITION y, POSITION x);
390 extern bool no_lite(player_type *creature_ptr);
391 extern void map_info(POSITION y, POSITION x, TERM_COLOR *ap, SYMBOL_CODE *cp, TERM_COLOR *tap, SYMBOL_CODE *tcp);
392 extern void print_rel(player_type *subject_ptr, SYMBOL_CODE c, TERM_COLOR a, TERM_LEN y, TERM_LEN x);
393 extern void note_spot(POSITION y, POSITION x);
394 extern void lite_spot(POSITION y, POSITION x);
395 extern void delayed_visual_update(void);
396 extern void update_flow(player_type *subject_ptr);
397 extern FEAT_IDX feat_state(FEAT_IDX feat, int action);
398 extern void cave_alter_feat(POSITION y, POSITION x, int action);
399 extern void remove_mirror(player_type *caster_ptr, POSITION y, POSITION x);
400 extern bool is_open(FEAT_IDX feat);
401 extern bool check_local_illumination(player_type *creature_ptr, POSITION y, POSITION x);
402
403 extern bool cave_monster_teleportable_bold(MONSTER_IDX m_idx, POSITION y, POSITION x, BIT_FLAGS mode);
404 extern bool cave_player_teleportable_bold(POSITION y, POSITION x, BIT_FLAGS mode);
405
406
407 /*!
408  * モンスターにより照明が消されている地形か否かを判定する。 / Is this grid "darkened" by monster?
409  */
410 #define darkened_grid(C) \
411         ((((C)->info & (CAVE_VIEW | CAVE_LITE | CAVE_MNLT | CAVE_MNDK)) == (CAVE_VIEW | CAVE_MNDK)) && \
412         !p_ptr->see_nocto)
413
414 /*
415  * Get feature mimic from f_info[] (applying "mimic" field)
416  */
417 #define get_feat_mimic(C) \
418         (f_info[(C)->mimic ? (C)->mimic : (C)->feat].mimic)
419
420 /*
421  * This macro allows us to efficiently add a grid to the "lite" array,
422  * note that we are never called for illegal grids, or for grids which
423  * have already been placed into the "lite" array, and we are never
424  * called when the "lite" array is full.
425  */
426 #define cave_lite_hack(F,Y,X) \
427 {\
428         if (!((F)->grid_array[Y][X].info & (CAVE_LITE))) \
429         { \
430                 (F)->grid_array[Y][X].info |= (CAVE_LITE); \
431                 (F)->lite_y[(F)->lite_n] = (Y); \
432                 (F)->lite_x[(F)->lite_n++] = (X); \
433         } \
434 }
435
436 /*
437  * For delayed visual update
438  */
439 #define cave_note_and_redraw_later(C,Y,X) \
440 {\
441         (C)->info |= CAVE_NOTE; \
442         cave_redraw_later(p_ptr->current_floor_ptr, (C), (Y), (X)); \
443 }
444
445 /*
446  * For delayed visual update
447  */
448 #define cave_redraw_later(F,G,Y,X) \
449 {\
450         if (!((G)->info & CAVE_REDRAW)) \
451         { \
452                 (G)->info |= CAVE_REDRAW; \
453                 (F)->redraw_y[(F)->redraw_n] = (Y); \
454                 (F)->redraw_x[(F)->redraw_n++] = (X); \
455         } \
456 }
457
458  /*
459   * This macro allows us to efficiently add a grid to the "view" array,
460   * note that we are never called for illegal grids, or for grids which
461   * have already been placed into the "view" array, and we are never
462   * called when the "view" array is full.
463   */
464 #define cave_view_hack(C,Y,X) \
465 {\
466     if (!((C)->info & (CAVE_VIEW))){\
467     (C)->info |= (CAVE_VIEW); \
468     p_ptr->current_floor_ptr->view_y[p_ptr->current_floor_ptr->view_n] = (Y); \
469     p_ptr->current_floor_ptr->view_x[p_ptr->current_floor_ptr->view_n] = (X); \
470     p_ptr->current_floor_ptr->view_n++;}\
471 }
472