OSDN Git Service

[Refactor] #40399 Separated object-mark-types.h from object.h
[hengband/hengband.git] / src / grid / grid.c
1 /*!
2  * @file grid.c
3  * @brief グリッドの実装 / low level dungeon routines -BEN-
4  * @date 2013/12/30
5  * @author
6  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke\n
7  *\n
8  * This software may be copied and distributed for educational, research,\n
9  * and not for profit purposes provided that this copyright and statement\n
10  * are included in all such copies.  Other copyrights may also apply.\n
11  * \n
12  * Support for Adam Bolt's tileset, lighting and transparency effects\n
13  * by Robert Ruehlmann (rr9@angband.org)\n
14  * \n
15  * 2013 Deskull Doxygen向けのコメント整理\n
16  */
17
18 #include "system/angband.h"
19 #include "util/util.h"
20 #include "term/gameterm.h"
21
22 #include "world/world.h"
23 #include "object/object-flavor.h"
24 #include "object/object-hook.h"
25 #include "object/object-mark-types.h"
26 #include "dungeon/dungeon.h"
27 #include "floor/floor-generate.h"
28 #include "grid/grid.h"
29 #include "grid/trap.h"
30 #include "room/rooms.h"
31 #include "monster/monster.h"
32 #include "dungeon/quest.h"
33 #include "grid/feature.h"
34 #include "monster/monster-status.h"
35 #include "player/player-status.h"
36 #include "player/player-effects.h"
37 #include "player/player-class.h"
38 #include "view/display-main-window.h"
39 #include "realm/realm-song.h"
40 #include "spell/process-effect.h"
41 #include "effect/effect-characteristics.h"
42
43 #define MONSTER_FLOW_DEPTH 32 /*!< 敵のプレイヤーに対する移動道のりの最大値(この値以上は処理を打ち切る) / OPTION: Maximum flow depth when using "MONSTER_FLOW" */
44
45  /*
46   * Feature action flags
47   */
48 #define FAF_DESTROY     0x01
49 #define FAF_NO_DROP     0x02
50 #define FAF_CRASH_GLASS 0x04
51
52   /*!
53    * @brief 地形状態フラグテーブル /
54    * The table of features' actions
55    */
56 static const byte feature_action_flags[FF_FLAG_MAX] =
57 {
58         0, /* LOS */
59         0, /* PROJECT */
60         0, /* MOVE */
61         0, /* PLACE */
62         0, /* DROP */
63         0, /* SECRET */
64         0, /* NOTICE */
65         0, /* REMEMBER */
66         0, /* OPEN */
67         0, /* CLOSE */
68         FAF_CRASH_GLASS, /* BASH */
69         0, /* SPIKE */
70         FAF_DESTROY, /* DISARM */
71         0, /* STORE */
72         FAF_DESTROY | FAF_CRASH_GLASS, /* TUNNEL */
73         0, /* MAY_HAVE_GOLD */
74         0, /* HAS_GOLD */
75         0, /* HAS_ITEM */
76         0, /* DOOR */
77         0, /* TRAP */
78         0, /* STAIRS */
79         0, /* GLYPH */
80         0, /* LESS */
81         0, /* MORE */
82         0, /* RUN */
83         0, /* FLOOR */
84         0, /* WALL */
85         0, /* PERMANENT */
86         0, /* INNER */
87         0, /* OUTER */
88         0, /* SOLID */
89         0, /* HIT_TRAP */
90
91         0, /* BRIDGE */
92         0, /* RIVER */
93         0, /* LAKE */
94         0, /* BRIDGED */
95         0, /* COVERED */
96         0, /* GLOW */
97         0, /* ENSECRET */
98         0, /* WATER */
99         0, /* LAVA */
100         0, /* SHALLOW */
101         0, /* DEEP */
102         0, /* FILLED */
103         FAF_DESTROY | FAF_CRASH_GLASS, /* HURT_ROCK */
104         0, /* HURT_FIRE */
105         0, /* HURT_COLD */
106         0, /* HURT_ACID */
107         0, /* ICE */
108         0, /* ACID */
109         0, /* OIL */
110         0, /* XXX04 */
111         0, /* CAN_CLIMB */
112         0, /* CAN_FLY */
113         0, /* CAN_SWIM */
114         0, /* CAN_PASS */
115         0, /* CAN_OOZE */
116         0, /* CAN_DIG */
117         0, /* HIDE_ITEM */
118         0, /* HIDE_SNEAK */
119         0, /* HIDE_SWIM */
120         0, /* HIDE_DIG */
121         0, /* KILL_HUGE */
122         0, /* KILL_MOVE */
123
124         0, /* PICK_TRAP */
125         0, /* PICK_DOOR */
126         0, /* ALLOC */
127         0, /* CHEST */
128         0, /* DROP_1D2 */
129         0, /* DROP_2D2 */
130         0, /* DROP_GOOD */
131         0, /* DROP_GREAT */
132         0, /* HURT_POIS */
133         0, /* HURT_ELEC */
134         0, /* HURT_WATER */
135         0, /* HURT_BWATER */
136         0, /* USE_FEAT */
137         0, /* GET_FEAT */
138         0, /* GROUND */
139         0, /* OUTSIDE */
140         0, /* EASY_HIDE */
141         0, /* EASY_CLIMB */
142         0, /* MUST_CLIMB */
143         0, /* TREE */
144         0, /* NEED_TREE */
145         0, /* BLOOD */
146         0, /* DUST */
147         0, /* SLIME */
148         0, /* PLANT */
149         0, /* XXX2 */
150         0, /* INSTANT */
151         0, /* EXPLODE */
152         0, /* TIMED */
153         0, /* ERUPT */
154         0, /* STRIKE */
155         0, /* SPREAD */
156
157         0, /* SPECIAL */
158         FAF_DESTROY | FAF_NO_DROP | FAF_CRASH_GLASS, /* HURT_DISI */
159         0, /* QUEST_ENTER */
160         0, /* QUEST_EXIT */
161         0, /* QUEST */
162         0, /* SHAFT */
163         0, /* MOUNTAIN */
164         0, /* BLDG */
165         0, /* MINOR_GLYPH */
166         0, /* PATTERN */
167         0, /* TOWN */
168         0, /* ENTRANCE */
169         0, /* MIRROR */
170         0, /* UNPERM */
171         0, /* TELEPORTABLE */
172         0, /* CONVERT */
173         0, /* GLASS */
174 };
175
176 /*!
177  * @brief 新規フロアに入りたてのプレイヤーをランダムな場所に配置する / Returns random co-ordinates for player/monster/object
178  * @param creature_ptr 配置したいクリーチャーの参照ポインタ
179  * @return 配置に成功したらTRUEを返す
180  */
181 bool new_player_spot(player_type *creature_ptr)
182 {
183         POSITION y = 0, x = 0;
184         int max_attempts = 10000;
185
186         grid_type *g_ptr;
187         feature_type *f_ptr;
188
189         while (max_attempts--)
190         {
191                 /* Pick a legal spot */
192                 y = (POSITION)rand_range(1, creature_ptr->current_floor_ptr->height - 2);
193                 x = (POSITION)rand_range(1, creature_ptr->current_floor_ptr->width - 2);
194
195                 g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
196
197                 /* Must be a "naked" floor grid */
198                 if (g_ptr->m_idx) continue;
199                 if (creature_ptr->current_floor_ptr->dun_level)
200                 {
201                         f_ptr = &f_info[g_ptr->feat];
202
203                         if (max_attempts > 5000) /* Rule 1 */
204                         {
205                                 if (!have_flag(f_ptr->flags, FF_FLOOR)) continue;
206                         }
207                         else /* Rule 2 */
208                         {
209                                 if (!have_flag(f_ptr->flags, FF_MOVE)) continue;
210                                 if (have_flag(f_ptr->flags, FF_HIT_TRAP)) continue;
211                         }
212
213                         /* Refuse to start on anti-teleport grids in dungeon */
214                         if (!have_flag(f_ptr->flags, FF_TELEPORTABLE)) continue;
215                 }
216                 if (!player_can_enter(creature_ptr, g_ptr->feat, 0)) continue;
217                 if (!in_bounds(creature_ptr->current_floor_ptr, y, x)) continue;
218
219                 /* Refuse to start on anti-teleport grids */
220                 if (g_ptr->info & (CAVE_ICKY)) continue;
221
222                 break;
223         }
224
225         if (max_attempts < 1) /* Should be -1, actually if we failed... */
226                 return FALSE;
227
228         /* Save the new player grid */
229         creature_ptr->y = y;
230         creature_ptr->x = x;
231
232         return TRUE;
233 }
234
235 /*!
236  * @brief マスにフロア端用の永久壁を配置する / Set boundary mimic and add "solid" perma-wall
237  * @param g_ptr 永久壁を配置したいマス構造体の参照ポインタ
238  * @return なし
239  */
240 void place_bound_perm_wall(player_type *player_ptr, grid_type *g_ptr)
241 {
242         if (bound_walls_perm)
243         {
244                 /* Clear boundary mimic */
245                 g_ptr->mimic = 0;
246         }
247         else
248         {
249                 feature_type *f_ptr = &f_info[g_ptr->feat];
250
251                 /* Hack -- Decline boundary walls with known treasure  */
252                 if ((have_flag(f_ptr->flags, FF_HAS_GOLD) || have_flag(f_ptr->flags, FF_HAS_ITEM)) &&
253                         !have_flag(f_ptr->flags, FF_SECRET))
254                         g_ptr->feat = feat_state(player_ptr, g_ptr->feat, FF_ENSECRET);
255
256                 /* Set boundary mimic */
257                 g_ptr->mimic = g_ptr->feat;
258         }
259
260         /* Add "solid" perma-wall */
261         place_grid(player_ptr, g_ptr, GB_SOLID_PERM);
262 }
263
264 /*!
265  * @brief マスに看破済みの罠があるかの判定を行う。 / Return TRUE if the given grid is a known trap
266  * @param player_ptr プレーヤーへの参照ポインタ
267  * @param g_ptr マス構造体の参照ポインタ
268  * @return 看破済みの罠があるならTRUEを返す。
269  */
270 bool is_known_trap(player_type *player_ptr, grid_type *g_ptr)
271 {
272         if (!g_ptr->mimic && !cave_have_flag_grid(g_ptr, FF_SECRET) &&
273                 is_trap(player_ptr, g_ptr->feat)) return TRUE;
274         else
275                 return FALSE;
276 }
277
278
279
280 /*!
281  * @brief マスに隠されたドアがあるかの判定を行う。 / Return TRUE if the given grid is a hidden closed door
282  * @param player_ptr プレーヤーへの参照ポインタ
283  * @param g_ptr マス構造体の参照ポインタ
284  * @return 隠されたドアがあるならTRUEを返す。
285  */
286 bool is_hidden_door(player_type *player_ptr, grid_type *g_ptr)
287 {
288         if ((g_ptr->mimic || cave_have_flag_grid(g_ptr, FF_SECRET)) &&
289                 is_closed_door(player_ptr, g_ptr->feat))
290                 return TRUE;
291         else
292                 return FALSE;
293 }
294
295 #define COMPLEX_WALL_ILLUMINATION /*!< 照明状態を壁により影響を受ける、より複雑な判定に切り替えるマクロ */
296
297
298 /*!
299  * @brief 指定された座標のマスが現在照らされているかを返す。 / Check for "local" illumination
300  * @param y y座標
301  * @param x x座標
302  * @return 指定された座標に照明がかかっているならTRUEを返す。。
303  */
304 bool check_local_illumination(player_type *creature_ptr, POSITION y, POSITION x)
305 {
306         /* Hack -- move towards player */
307         POSITION yy = (y < creature_ptr->y) ? (y + 1) : (y > creature_ptr->y) ? (y - 1) : y;
308         POSITION xx = (x < creature_ptr->x) ? (x + 1) : (x > creature_ptr->x) ? (x - 1) : x;
309
310         /* Check for "local" illumination */
311
312 #ifdef COMPLEX_WALL_ILLUMINATION /* COMPLEX_WALL_ILLUMINATION */
313
314         /* Check for "complex" illumination */
315         if ((feat_supports_los(get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[yy][xx])) &&
316                 (creature_ptr->current_floor_ptr->grid_array[yy][xx].info & CAVE_GLOW)) ||
317                 (feat_supports_los(get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[y][xx])) &&
318                 (creature_ptr->current_floor_ptr->grid_array[y][xx].info & CAVE_GLOW)) ||
319                         (feat_supports_los(get_feat_mimic(&creature_ptr->current_floor_ptr->grid_array[yy][x])) &&
320                 (creature_ptr->current_floor_ptr->grid_array[yy][x].info & CAVE_GLOW)))
321         {
322                 return TRUE;
323         }
324         else return FALSE;
325
326 #else /* COMPLEX_WALL_ILLUMINATION */
327
328         /* Check for "simple" illumination */
329         return (creature_ptr->current_floor_ptr->grid_array[yy][xx].info & CAVE_GLOW) ? TRUE : FALSE;
330
331 #endif /* COMPLEX_WALL_ILLUMINATION */
332 }
333
334
335 /*! 対象座標のマスの照明状態を更新する際の補助処理マクロ */
336 #define update_local_illumination_aux(C, Y, X) \
337 { \
338         if (player_has_los_bold((C), (Y), (X))) \
339         { \
340                 /* Update the monster */ \
341                 if ((C)->current_floor_ptr->grid_array[(Y)][(X)].m_idx) update_monster((C), (C)->current_floor_ptr->grid_array[(Y)][(X)].m_idx, FALSE); \
342 \
343                 /* Notice and redraw */ \
344                 note_spot((C), (Y), (X)); \
345                 lite_spot((C), (Y), (X)); \
346         } \
347 }
348
349 /*!
350  * @brief 指定された座標の照明状態を更新する / Update "local" illumination
351  * @param creature_ptr 視界元のクリーチャー
352  * @param y 視界先y座標
353  * @param x 視界先x座標
354  * @return なし
355  */
356 void update_local_illumination(player_type * creature_ptr, POSITION y, POSITION x)
357 {
358         int i;
359         POSITION yy, xx;
360
361         if (!in_bounds(creature_ptr->current_floor_ptr, y, x)) return;
362
363 #ifdef COMPLEX_WALL_ILLUMINATION /* COMPLEX_WALL_ILLUMINATION */
364
365         if ((y != creature_ptr->y) && (x != creature_ptr->x))
366         {
367                 yy = (y < creature_ptr->y) ? (y - 1) : (y + 1);
368                 xx = (x < creature_ptr->x) ? (x - 1) : (x + 1);
369                 update_local_illumination_aux(creature_ptr, yy, xx);
370                 update_local_illumination_aux(creature_ptr, y, xx);
371                 update_local_illumination_aux(creature_ptr, yy, x);
372         }
373         else if (x != creature_ptr->x) /* y == creature_ptr->y */
374         {
375                 xx = (x < creature_ptr->x) ? (x - 1) : (x + 1);
376                 for (i = -1; i <= 1; i++)
377                 {
378                         yy = y + i;
379                         update_local_illumination_aux(creature_ptr, yy, xx);
380                 }
381                 yy = y - 1;
382                 update_local_illumination_aux(creature_ptr, yy, x);
383                 yy = y + 1;
384                 update_local_illumination_aux(creature_ptr, yy, x);
385         }
386         else if (y != creature_ptr->y) /* x == creature_ptr->x */
387         {
388                 yy = (y < creature_ptr->y) ? (y - 1) : (y + 1);
389                 for (i = -1; i <= 1; i++)
390                 {
391                         xx = x + i;
392                         update_local_illumination_aux(creature_ptr, yy, xx);
393                 }
394                 xx = x - 1;
395                 update_local_illumination_aux(creature_ptr, y, xx);
396                 xx = x + 1;
397                 update_local_illumination_aux(creature_ptr, y, xx);
398         }
399         else /* Player's grid */
400         {
401                 for (i = 0; i < 8; i++)
402                 {
403                         yy = y + ddy_cdd[i];
404                         xx = x + ddx_cdd[i];
405                         update_local_illumination_aux(creature_ptr, yy, xx);
406                 }
407         }
408
409 #else /* COMPLEX_WALL_ILLUMINATION */
410
411         if ((y != creature_ptr->y) && (x != creature_ptr->x))
412         {
413                 yy = (y < creature_ptr->y) ? (y - 1) : (y + 1);
414                 xx = (x < creature_ptr->x) ? (x - 1) : (x + 1);
415                 update_local_illumination_aux(creature_ptr, yy, xx);
416         }
417         else if (x != creature_ptr->x) /* y == creature_ptr->y */
418         {
419                 xx = (x < creature_ptr->x) ? (x - 1) : (x + 1);
420                 for (i = -1; i <= 1; i++)
421                 {
422                         yy = y + i;
423                         update_local_illumination_aux(creature_ptr, yy, xx);
424                 }
425         }
426         else if (y != creature_ptr->y) /* x == creature_ptr->x */
427         {
428                 yy = (y < creature_ptr->y) ? (y - 1) : (y + 1);
429                 for (i = -1; i <= 1; i++)
430                 {
431                         xx = x + i;
432                         update_local_illumination_aux(creature_ptr, yy, xx);
433                 }
434         }
435         else /* Player's grid */
436         {
437                 for (i = 0; i < 8; i++)
438                 {
439                         yy = y + ddy_cdd[i];
440                         xx = x + ddx_cdd[i];
441                         update_local_illumination_aux(creature_ptr, yy, xx);
442                 }
443         }
444
445 #endif /* COMPLEX_WALL_ILLUMINATION */
446 }
447
448
449 /*!
450  * @brief 指定された座標をプレイヤー収められていない状態かどうか / Returns true if the player's grid is dark
451  * @return 視覚に収められていないならTRUEを返す
452  * @details player_can_see_bold()関数の返り値の否定を返している。
453  */
454 bool no_lite(player_type *creature_ptr)
455 {
456         return (!player_can_see_bold(creature_ptr, creature_ptr->y, creature_ptr->x));
457 }
458
459 /*
460  * Place an attr/char pair at the given map coordinate, if legal.
461  */
462 void print_rel(player_type *subject_ptr, SYMBOL_CODE c, TERM_COLOR a, TERM_LEN y, TERM_LEN x)
463 {
464         /* Only do "legal" locations */
465         if (panel_contains(y, x))
466         {
467                 /* Hack -- fake monochrome */
468                 if (!use_graphics)
469                 {
470                         if (current_world_ptr->timewalk_m_idx) a = TERM_DARK;
471                         else if (IS_INVULN(subject_ptr) || subject_ptr->timewalk) a = TERM_WHITE;
472                         else if (subject_ptr->wraith_form) a = TERM_L_DARK;
473                 }
474
475                 /* Draw the char using the attr */
476                 Term_queue_bigchar(panel_col_of(x), y - panel_row_prt, a, c, 0, 0);
477         }
478 }
479
480
481 /*
482  * todo ここにplayer_type を追加した時のコンパイルエラーに対処できなかったので保留
483  * Memorize interesting viewable object/features in the given grid
484  *
485  * This function should only be called on "legal" grids.
486  *
487  * This function will memorize the object and/or feature in the given
488  * grid, if they are (1) viewable and (2) interesting.  Note that all
489  * objects are interesting, all terrain features except floors (and
490  * invisible traps) are interesting, and floors (and invisible traps)
491  * are interesting sometimes (depending on various options involving
492  * the illumination of floor grids).
493  *
494  * The automatic memorization of all objects and non-floor terrain
495  * features as soon as they are displayed allows incredible amounts
496  * of optimization in various places, especially "map_info()".
497  *
498  * Note that the memorization of objects is completely separate from
499  * the memorization of terrain features, preventing annoying floor
500  * memorization when a detected object is picked up from a dark floor,
501  * and object memorization when an object is dropped into a floor grid
502  * which is memorized but out-of-sight.
503  *
504  * This function should be called every time the "memorization" of
505  * a grid (or the object in a grid) is called into question, such
506  * as when an object is created in a grid, when a terrain feature
507  * "changes" from "floor" to "non-floor", when any grid becomes
508  * "illuminated" or "viewable", and when a "floor" grid becomes
509  * "torch-lit".
510  *
511  * Note the relatively efficient use of this function by the various
512  * "update_view()" and "update_lite()" calls, to allow objects and
513  * terrain features to be memorized (and drawn) whenever they become
514  * viewable or illuminated in any way, but not when they "maintain"
515  * or "lose" their previous viewability or illumination.
516  *
517  * Note the butchered "internal" version of "player_can_see_bold()",
518  * optimized primarily for the most common cases, that is, for the
519  * non-marked floor grids.
520  */
521 void note_spot(player_type *player_ptr, POSITION y, POSITION x)
522 {
523         grid_type *g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
524         OBJECT_IDX this_o_idx, next_o_idx = 0;
525
526         /* Blind players see nothing */
527         if (player_ptr->blind) return;
528
529         /* Analyze non-torch-lit grids */
530         if (!(g_ptr->info & (CAVE_LITE | CAVE_MNLT)))
531         {
532                 /* Require line of sight to the grid */
533                 if (!(g_ptr->info & (CAVE_VIEW))) return;
534
535                 /* Require "perma-lite" of the grid */
536                 if ((g_ptr->info & (CAVE_GLOW | CAVE_MNDK)) != CAVE_GLOW)
537                 {
538                         /* Not Ninja */
539                         if (!player_ptr->see_nocto) return;
540                 }
541         }
542
543
544         /* Hack -- memorize objects */
545         for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
546         {
547                 object_type *o_ptr = &player_ptr->current_floor_ptr->o_list[this_o_idx];
548                 next_o_idx = o_ptr->next_o_idx;
549
550                 /* Memorize objects */
551                 o_ptr->marked |= OM_FOUND;
552         }
553
554
555         /* Hack -- memorize grids */
556         if (!(g_ptr->info & (CAVE_MARK)))
557         {
558                 /* Feature code (applying "mimic" field) */
559                 feature_type *f_ptr = &f_info[get_feat_mimic(g_ptr)];
560
561                 /* Memorize some "boring" grids */
562                 if (!have_flag(f_ptr->flags, FF_REMEMBER))
563                 {
564                         /* Option -- memorize all torch-lit floors */
565                         if (view_torch_grids &&
566                                 ((g_ptr->info & (CAVE_LITE | CAVE_MNLT)) || player_ptr->see_nocto))
567                         {
568                                 g_ptr->info |= (CAVE_MARK);
569                         }
570
571                         /* Option -- memorize all perma-lit floors */
572                         else if (view_perma_grids && ((g_ptr->info & (CAVE_GLOW | CAVE_MNDK)) == CAVE_GLOW))
573                         {
574                                 g_ptr->info |= (CAVE_MARK);
575                         }
576                 }
577
578                 /* Memorize normal grids */
579                 else if (have_flag(f_ptr->flags, FF_LOS))
580                 {
581                         g_ptr->info |= (CAVE_MARK);
582                 }
583
584                 /* Memorize torch-lit walls */
585                 else if (g_ptr->info & (CAVE_LITE | CAVE_MNLT))
586                 {
587                         g_ptr->info |= (CAVE_MARK);
588                 }
589
590                 /* Memorize walls seen by noctovision of Ninja */
591                 else if (player_ptr->see_nocto)
592                 {
593                         g_ptr->info |= (CAVE_MARK);
594                 }
595
596                 /* Memorize certain non-torch-lit wall grids */
597                 else if (check_local_illumination(player_ptr, y, x))
598                 {
599                         g_ptr->info |= (CAVE_MARK);
600                 }
601         }
602
603         /* Memorize terrain of the grid */
604         g_ptr->info |= (CAVE_KNOWN);
605 }
606
607 /*
608  * Redraw (on the screen) a given MAP location
609  *
610  * This function should only be called on "legal" grids
611  */
612 void lite_spot(player_type *player_ptr, POSITION y, POSITION x)
613 {
614         /* Redraw if on screen */
615         if (panel_contains(y, x) && in_bounds2(player_ptr->current_floor_ptr, y, x))
616         {
617                 TERM_COLOR a;
618                 SYMBOL_CODE c;
619                 TERM_COLOR ta;
620                 SYMBOL_CODE tc;
621
622                 map_info(player_ptr, y, x, &a, &c, &ta, &tc);
623
624                 /* Hack -- fake monochrome */
625                 if (!use_graphics)
626                 {
627                         if (current_world_ptr->timewalk_m_idx) a = TERM_DARK;
628                         else if (IS_INVULN(player_ptr) || player_ptr->timewalk) a = TERM_WHITE;
629                         else if (player_ptr->wraith_form) a = TERM_L_DARK;
630                 }
631
632                 /* Hack -- Queue it */
633                 Term_queue_bigchar(panel_col_of(x), y - panel_row_prt, a, c, ta, tc);
634
635                 /* Update sub-windows */
636                 player_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
637         }
638 }
639
640 /*
641  * Some comments on the grid flags.  -BEN-
642  *
643  *
644  * One of the major bottlenecks in previous versions of Angband was in
645  * the calculation of "line of sight" from the player to various grids,
646  * such as monsters.  This was such a nasty bottleneck that a lot of
647  * silly things were done to reduce the dependancy on "line of sight",
648  * for example, you could not "see" any grids in a lit room until you
649  * actually entered the room, and there were all kinds of bizarre grid
650  * flags to enable this behavior.  This is also why the "call light"
651  * spells always lit an entire room.
652  *
653  * The code below provides functions to calculate the "field of view"
654  * for the player, which, once calculated, provides extremely fast
655  * calculation of "line of sight from the player", and to calculate
656  * the "field of torch lite", which, again, once calculated, provides
657  * extremely fast calculation of "which grids are lit by the player's
658  * lite source".  In addition to marking grids as "GRID_VIEW" and/or
659  * "GRID_LITE", as appropriate, these functions maintain an array for
660  * each of these two flags, each array containing the locations of all
661  * of the grids marked with the appropriate flag, which can be used to
662  * very quickly scan through all of the grids in a given set.
663  *
664  * To allow more "semantically valid" field of view semantics, whenever
665  * the field of view (or the set of torch lit grids) changes, all of the
666  * grids in the field of view (or the set of torch lit grids) are "drawn"
667  * so that changes in the world will become apparent as soon as possible.
668  * This has been optimized so that only grids which actually "change" are
669  * redrawn, using the "temp" array and the "GRID_TEMP" flag to keep track
670  * of the grids which are entering or leaving the relevent set of grids.
671  *
672  * These new methods are so efficient that the old nasty code was removed.
673  *
674  * Note that there is no reason to "update" the "viewable space" unless
675  * the player "moves", or walls/doors are created/destroyed, and there
676  * is no reason to "update" the "torch lit grids" unless the field of
677  * view changes, or the "light radius" changes.  This means that when
678  * the player is resting, or digging, or doing anything that does not
679  * involve movement or changing the state of the dungeon, there is no
680  * need to update the "view" or the "lite" regions, which is nice.
681  *
682  * Note that the calls to the nasty "los()" function have been reduced
683  * to a bare minimum by the use of the new "field of view" calculations.
684  *
685  * I wouldn't be surprised if slight modifications to the "update_view()"
686  * function would allow us to determine "reverse line-of-sight" as well
687  * as "normal line-of-sight", which would allow monsters to use a more
688  * "correct" calculation to determine if they can "see" the player.  For
689  * now, monsters simply "cheat" somewhat and assume that if the player
690  * has "line of sight" to the monster, then the monster can "pretend"
691  * that it has "line of sight" to the player.
692  *
693  *
694  * The "update_lite()" function maintains the "CAVE_LITE" flag for each
695  * grid and maintains an array of all "CAVE_LITE" grids.
696  *
697  * This set of grids is the complete set of all grids which are lit by
698  * the players light source, which allows the "player_can_see_bold()"
699  * function to work very quickly.
700  *
701  * Note that every "CAVE_LITE" grid is also a "CAVE_VIEW" grid, and in
702  * fact, the player (unless blind) can always "see" all grids which are
703  * marked as "CAVE_LITE", unless they are "off screen".
704  *
705  *
706  * The "update_view()" function maintains the "CAVE_VIEW" flag for each
707  * grid and maintains an array of all "CAVE_VIEW" grids.
708  *
709  * This set of grids is the complete set of all grids within line of sight
710  * of the player, allowing the "player_has_los_bold()" macro to work very
711  * quickly.
712  *
713  *
714  * The current "update_view()" algorithm uses the "CAVE_XTRA" flag as a
715  * temporary internal flag to mark those grids which are not only in view,
716  * but which are also "easily" in line of sight of the player.  This flag
717  * is always cleared when we are done.
718  *
719  *
720  * The current "update_lite()" and "update_view()" algorithms use the
721  * "CAVE_TEMP" flag, and the array of grids which are marked as "CAVE_TEMP",
722  * to keep track of which grids were previously marked as "CAVE_LITE" or
723  * "CAVE_VIEW", which allows us to optimize the "screen updates".
724  *
725  * The "CAVE_TEMP" flag, and the array of "CAVE_TEMP" grids, is also used
726  * for various other purposes, such as spreading lite or darkness during
727  * "lite_room()" / "unlite_room()", and for calculating monster flow.
728  *
729  *
730  * Any grid can be marked as "CAVE_GLOW" which means that the grid itself is
731  * in some way permanently lit.  However, for the player to "see" anything
732  * in the grid, as determined by "player_can_see()", the player must not be
733  * blind, the grid must be marked as "CAVE_VIEW", and, in addition, "wall"
734  * grids, even if marked as "perma lit", are only illuminated if they touch
735  * a grid which is not a wall and is marked both "CAVE_GLOW" and "CAVE_VIEW".
736  *
737  *
738  * To simplify various things, a grid may be marked as "CAVE_MARK", meaning
739  * that even if the player cannot "see" the grid, he "knows" the terrain in
740  * that grid.  This is used to "remember" walls/doors/stairs/floors when they
741  * are "seen" or "detected", and also to "memorize" floors, after "wiz_lite()",
742  * or when one of the "memorize floor grids" options induces memorization.
743  *
744  * Objects are "memorized" in a different way, using a special "marked" flag
745  * on the object itself, which is set when an object is observed or detected.
746  *
747  *
748  * A grid may be marked as "CAVE_ROOM" which means that it is part of a "room",
749  * and should be illuminated by "lite room" and "darkness" spells.
750  *
751  *
752  * A grid may be marked as "CAVE_ICKY" which means it is part of a "vault",
753  * and should be unavailable for "teleportation" destinations.
754  *
755  *
756  * The "view_perma_grids" allows the player to "memorize" every perma-lit grid
757  * which is observed, and the "view_torch_grids" allows the player to memorize
758  * every torch-lit grid.  The player will always memorize important walls,
759  * doors, stairs, and other terrain features, as well as any "detected" grids.
760  *
761  * Note that the new "update_view()" method allows, among other things, a room
762  * to be "partially" seen as the player approaches it, with a growing cone of
763  * floor appearing as the player gets closer to the door.  Also, by not turning
764  * on the "memorize perma-lit grids" option, the player will only "see" those
765  * floor grids which are actually in line of sight.
766  *
767  * And my favorite "plus" is that you can now use a special option to draw the
768  * "floors" in the "viewable region" brightly (actually, to draw the *other*
769  * grids dimly), providing a "pretty" effect as the player runs around, and
770  * to efficiently display the "torch lite" in a special color.
771  *
772  *
773  * Some comments on the "update_view()" algorithm...
774  *
775  * The algorithm is very fast, since it spreads "obvious" grids very quickly,
776  * and only has to call "los()" on the borderline cases.  The major axes/diags
777  * even terminate early when they hit walls.  I need to find a quick way
778  * to "terminate" the other scans.
779  *
780  * Note that in the worst case (a big empty area with say 5% scattered walls),
781  * each of the 1500 or so nearby grids is checked once, most of them getting
782  * an "instant" rating, and only a small portion requiring a call to "los()".
783  *
784  * The only time that the algorithm appears to be "noticeably" too slow is
785  * when running, and this is usually only important in town, since the town
786  * provides about the worst scenario possible, with large open regions and
787  * a few scattered obstructions.  There is a special "efficiency" option to
788  * allow the player to reduce his field of view in town, if needed.
789  *
790  * In the "best" case (say, a normal stretch of corridor), the algorithm
791  * makes one check for each viewable grid, and makes no calls to "los()".
792  * So running in corridors is very fast, and if a lot of monsters are
793  * nearby, it is much faster than the old methods.
794  *
795  * Note that resting, most normal commands, and several forms of running,
796  * plus all commands executed near large groups of monsters, are strictly
797  * more efficient with "update_view()" that with the old "compute los() on
798  * demand" method, primarily because once the "field of view" has been
799  * calculated, it does not have to be recalculated until the player moves
800  * (or a wall or door is created or destroyed).
801  *
802  * Note that we no longer have to do as many "los()" checks, since once the
803  * "view" region has been built, very few things cause it to be "changed"
804  * (player movement, and the opening/closing of doors, changes in wall status).
805  * Note that door/wall changes are only relevant when the door/wall itself is
806  * in the "view" region.
807  *
808  * The algorithm seems to only call "los()" from zero to ten times, usually
809  * only when coming down a corridor into a room, or standing in a room, just
810  * misaligned with a corridor.  So if, say, there are five "nearby" monsters,
811  * we will be reducing the calls to "los()".
812  *
813  * I am thinking in terms of an algorithm that "walks" from the central point
814  * out to the maximal "distance", at each point, determining the "view" code
815  * (above).  For each grid not on a major axis or diagonal, the "view" code
816  * depends on the "cave_los_bold()" and "view" of exactly two other grids
817  * (the one along the nearest diagonal, and the one next to that one, see
818  * "update_view_aux()"...).
819  *
820  * We "memorize" the viewable space array, so that at the cost of under 3000
821  * bytes, we reduce the time taken by "forget_view()" to one assignment for
822  * each grid actually in the "viewable space".  And for another 3000 bytes,
823  * we prevent "erase + redraw" ineffiencies via the "seen" set.  These bytes
824  * are also used by other routines, thus reducing the cost to almost nothing.
825  *
826  * A similar thing is done for "forget_lite()" in which case the savings are
827  * much less, but save us from doing bizarre maintenance checking.
828  *
829  * In the worst "normal" case (in the middle of the town), the reachable space
830  * actually reaches to more than half of the largest possible "circle" of view,
831  * or about 800 grids, and in the worse case (in the middle of a dungeon level
832  * where all the walls have been removed), the reachable space actually reaches
833  * the theoretical maximum size of just under 1500 grids.
834  *
835  * Each grid G examines the "state" of two (?) other (adjacent) grids, G1 & G2.
836  * If G1 is lite, G is lite.  Else if G2 is lite, G is half.  Else if G1 and G2
837  * are both half, G is half.  Else G is dark.  It only takes 2 (or 4) bits to
838  * "name" a grid, so (for MAX_RAD of 20) we could use 1600 bytes, and scan the
839  * entire possible space (including initialization) in one step per grid.  If
840  * we do the "clearing" as a separate step (and use an array of "view" grids),
841  * then the clearing will take as many steps as grids that were viewed, and the
842  * algorithm will be able to "stop" scanning at various points.
843  * Oh, and outside of the "torch radius", only "lite" grids need to be scanned.
844  */
845
846  /*
847   * Hack - speed up the update_flow algorithm by only doing
848   * it everytime the player moves out of LOS of the last
849   * "way-point".
850   */
851 static POSITION flow_x = 0;
852 static POSITION flow_y = 0;
853
854 /*
855  * Hack -- fill in the "cost" field of every grid that the player
856  * can "reach" with the number of steps needed to reach that grid.
857  * This also yields the "distance" of the player from every grid.
858  *
859  * In addition, mark the "when" of the grids that can reach
860  * the player with the incremented value of "flow_n".
861  *
862  * Hack -- use the "seen" array as a "circular queue".
863  *
864  * We do not need a priority queue because the cost from grid
865  * to grid is always "one" and we process them in order.
866  */
867 void update_flow(player_type *subject_ptr)
868 {
869         POSITION x, y;
870         DIRECTION d;
871         int flow_head = 1;
872         int flow_tail = 0;
873
874         /* Paranoia -- make sure the array is empty */
875         if (tmp_pos.n) return;
876
877         /* The last way-point is on the map */
878         if (subject_ptr->running && in_bounds(subject_ptr->current_floor_ptr, flow_y, flow_x))
879         {
880                 /* The way point is in sight - do not update.  (Speedup) */
881                 if (subject_ptr->current_floor_ptr->grid_array[flow_y][flow_x].info & CAVE_VIEW) return;
882         }
883
884         /* Erase all of the current flow information */
885         for (y = 0; y < subject_ptr->current_floor_ptr->height; y++)
886         {
887                 for (x = 0; x < subject_ptr->current_floor_ptr->width; x++)
888                 {
889                         subject_ptr->current_floor_ptr->grid_array[y][x].cost = 0;
890                         subject_ptr->current_floor_ptr->grid_array[y][x].dist = 0;
891                 }
892         }
893
894         /* Save player position */
895         flow_y = subject_ptr->y;
896         flow_x = subject_ptr->x;
897
898         /* Add the player's grid to the queue */
899         tmp_pos.y[0] = subject_ptr->y;
900         tmp_pos.x[0] = subject_ptr->x;
901
902         /* Now process the queue */
903         while (flow_head != flow_tail)
904         {
905                 int ty, tx;
906
907                 /* Extract the next entry */
908                 ty = tmp_pos.y[flow_tail];
909                 tx = tmp_pos.x[flow_tail];
910
911                 /* Forget that entry */
912                 if (++flow_tail == TEMP_MAX) flow_tail = 0;
913
914                 /* Add the "children" */
915                 for (d = 0; d < 8; d++)
916                 {
917                         int old_head = flow_head;
918                         byte m = subject_ptr->current_floor_ptr->grid_array[ty][tx].cost + 1;
919                         byte n = subject_ptr->current_floor_ptr->grid_array[ty][tx].dist + 1;
920                         grid_type *g_ptr;
921
922                         /* Child location */
923                         y = ty + ddy_ddd[d];
924                         x = tx + ddx_ddd[d];
925
926                         /* Ignore player's grid */
927                         if (player_bold(subject_ptr, y, x)) continue;
928
929                         g_ptr = &subject_ptr->current_floor_ptr->grid_array[y][x];
930
931                         if (is_closed_door(subject_ptr, g_ptr->feat)) m += 3;
932
933                         /* Ignore "pre-stamped" entries */
934                         if (g_ptr->dist != 0 && g_ptr->dist <= n && g_ptr->cost <= m) continue;
935
936                         /* Ignore "walls" and "rubble" */
937                         if (!cave_have_flag_grid(g_ptr, FF_MOVE) && !is_closed_door(subject_ptr, g_ptr->feat)) continue;
938
939                         /* Save the flow cost */
940                         if (g_ptr->cost == 0 || g_ptr->cost > m) g_ptr->cost = m;
941                         if (g_ptr->dist == 0 || g_ptr->dist > n) g_ptr->dist = n;
942
943                         /* Hack -- limit flow depth */
944                         if (n == MONSTER_FLOW_DEPTH) continue;
945
946                         /* Enqueue that entry */
947                         tmp_pos.y[flow_head] = y;
948                         tmp_pos.x[flow_head] = x;
949
950                         /* Advance the queue */
951                         if (++flow_head == TEMP_MAX) flow_head = 0;
952
953                         /* Hack -- notice overflow by forgetting new entry */
954                         if (flow_head == flow_tail) flow_head = old_head;
955                 }
956         }
957 }
958
959 /*
960  * Take a feature, determine what that feature becomes
961  * through applying the given action.
962  */
963 FEAT_IDX feat_state(player_type *player_ptr, FEAT_IDX feat, int action)
964 {
965         feature_type *f_ptr = &f_info[feat];
966         int i;
967
968         /* Get the new feature */
969         floor_type *floor_ptr = player_ptr->current_floor_ptr;
970         for (i = 0; i < MAX_FEAT_STATES; i++)
971         {
972                 if (f_ptr->state[i].action == action) return conv_dungeon_feat(floor_ptr, f_ptr->state[i].result);
973         }
974
975         if (have_flag(f_ptr->flags, FF_PERMANENT)) return feat;
976
977         return (feature_action_flags[action] & FAF_DESTROY) ? conv_dungeon_feat(floor_ptr, f_ptr->destroyed) : feat;
978 }
979
980 /*
981  * Takes a location and action and changes the feature at that
982  * location through applying the given action.
983  */
984 void cave_alter_feat(player_type *player_ptr, POSITION y, POSITION x, int action)
985 {
986         /* Set old feature */
987         floor_type *floor_ptr = player_ptr->current_floor_ptr;
988         FEAT_IDX oldfeat = floor_ptr->grid_array[y][x].feat;
989
990         /* Get the new feat */
991         FEAT_IDX newfeat = feat_state(player_ptr, oldfeat, action);
992
993         /* No change */
994         if (newfeat == oldfeat) return;
995
996         /* Set the new feature */
997         cave_set_feat(player_ptr, y, x, newfeat);
998
999         if (!(feature_action_flags[action] & FAF_NO_DROP))
1000         {
1001                 feature_type *old_f_ptr = &f_info[oldfeat];
1002                 feature_type *f_ptr = &f_info[newfeat];
1003                 bool found = FALSE;
1004
1005                 /* Handle gold */
1006                 if (have_flag(old_f_ptr->flags, FF_HAS_GOLD) && !have_flag(f_ptr->flags, FF_HAS_GOLD))
1007                 {
1008                         /* Place some gold */
1009                         place_gold(player_ptr, y, x);
1010                         found = TRUE;
1011                 }
1012
1013                 /* Handle item */
1014                 if (have_flag(old_f_ptr->flags, FF_HAS_ITEM) && !have_flag(f_ptr->flags, FF_HAS_ITEM) && (randint0(100) < (15 - floor_ptr->dun_level / 2)))
1015                 {
1016                         /* Place object */
1017                         place_object(player_ptr, y, x, 0L);
1018                         found = TRUE;
1019                 }
1020
1021                 if (found && current_world_ptr->character_dungeon && player_can_see_bold(player_ptr, y, x))
1022                 {
1023                         msg_print(_("何かを発見した!", "You have found something!"));
1024                 }
1025         }
1026
1027         if (feature_action_flags[action] & FAF_CRASH_GLASS)
1028         {
1029                 feature_type *old_f_ptr = &f_info[oldfeat];
1030
1031                 if (have_flag(old_f_ptr->flags, FF_GLASS) && current_world_ptr->character_dungeon)
1032                 {
1033                         project(player_ptr, PROJECT_WHO_GLASS_SHARDS, 1, y, x, MIN(floor_ptr->dun_level, 100) / 4, GF_SHARDS,
1034                                 (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_HIDE | PROJECT_JUMP | PROJECT_NO_HANGEKI), -1);
1035                 }
1036         }
1037 }
1038
1039
1040 /* Remove a mirror */
1041 void remove_mirror(player_type *caster_ptr, POSITION y, POSITION x)
1042 {
1043         grid_type *g_ptr = &caster_ptr->current_floor_ptr->grid_array[y][x];
1044
1045         /* Remove the mirror */
1046         g_ptr->info &= ~(CAVE_OBJECT);
1047         g_ptr->mimic = 0;
1048
1049         if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
1050         {
1051                 g_ptr->info &= ~(CAVE_GLOW);
1052                 if (!view_torch_grids) g_ptr->info &= ~(CAVE_MARK);
1053                 if (g_ptr->m_idx) update_monster(caster_ptr, g_ptr->m_idx, FALSE);
1054
1055                 update_local_illumination(caster_ptr, y, x);
1056         }
1057
1058         note_spot(caster_ptr, y, x);
1059
1060         lite_spot(caster_ptr, y, x);
1061 }
1062
1063
1064 /*
1065  *  Return TRUE if there is a mirror on the grid.
1066  */
1067 bool is_mirror_grid(grid_type *g_ptr)
1068 {
1069         if ((g_ptr->info & CAVE_OBJECT) && have_flag(f_info[g_ptr->mimic].flags, FF_MIRROR))
1070                 return TRUE;
1071         else
1072                 return FALSE;
1073 }
1074
1075
1076 /*
1077  *  Return TRUE if there is a mirror on the grid.
1078  */
1079 bool is_glyph_grid(grid_type *g_ptr)
1080 {
1081         if ((g_ptr->info & CAVE_OBJECT) && have_flag(f_info[g_ptr->mimic].flags, FF_GLYPH))
1082                 return TRUE;
1083         else
1084                 return FALSE;
1085 }
1086
1087
1088 /*
1089  *  Return TRUE if there is a mirror on the grid.
1090  */
1091 bool is_explosive_rune_grid(grid_type *g_ptr)
1092 {
1093         if ((g_ptr->info & CAVE_OBJECT) && have_flag(f_info[g_ptr->mimic].flags, FF_MINOR_GLYPH))
1094                 return TRUE;
1095         else
1096                 return FALSE;
1097 }
1098
1099 /*!
1100 * @brief 指定されたマスがモンスターのテレポート可能先かどうかを判定する。
1101 * @param player_ptr プレーヤーへの参照ポインタ
1102 * @param m_idx モンスターID
1103 * @param y 移動先Y座標
1104 * @param x 移動先X座標
1105 * @param mode オプション
1106 * @return テレポート先として妥当ならばtrue
1107 */
1108 bool cave_monster_teleportable_bold(player_type *player_ptr, MONSTER_IDX m_idx, POSITION y, POSITION x, teleport_flags mode)
1109 {
1110         monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
1111         grid_type    *g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
1112         feature_type *f_ptr = &f_info[g_ptr->feat];
1113
1114         /* Require "teleportable" space */
1115         if (!have_flag(f_ptr->flags, FF_TELEPORTABLE)) return FALSE;
1116
1117         if (g_ptr->m_idx && (g_ptr->m_idx != m_idx)) return FALSE;
1118         if (player_bold(player_ptr, y, x)) return FALSE;
1119
1120         /* Hack -- no teleport onto glyph of warding */
1121         if (is_glyph_grid(g_ptr)) return FALSE;
1122         if (is_explosive_rune_grid(g_ptr)) return FALSE;
1123
1124         if (!(mode & TELEPORT_PASSIVE))
1125         {
1126                 if (!monster_can_cross_terrain(player_ptr, g_ptr->feat, &r_info[m_ptr->r_idx], 0)) return FALSE;
1127         }
1128
1129         return TRUE;
1130 }
1131
1132 /*!
1133 * @brief 指定されたマスにプレイヤーがテレポート可能かどうかを判定する。
1134 * @param player_ptr プレーヤーへの参照ポインタ
1135 * @param y 移動先Y座標
1136 * @param x 移動先X座標
1137 * @param mode オプション
1138 * @return テレポート先として妥当ならばtrue
1139 */
1140 bool cave_player_teleportable_bold(player_type *player_ptr, POSITION y, POSITION x, teleport_flags mode)
1141 {
1142         grid_type    *g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
1143         feature_type *f_ptr = &f_info[g_ptr->feat];
1144
1145         /* Require "teleportable" space */
1146         if (!have_flag(f_ptr->flags, FF_TELEPORTABLE)) return FALSE;
1147
1148         /* No magical teleporting into vaults and such */
1149         if (!(mode & TELEPORT_NONMAGICAL) && (g_ptr->info & CAVE_ICKY)) return FALSE;
1150
1151         if (g_ptr->m_idx && (g_ptr->m_idx != player_ptr->riding)) return FALSE;
1152
1153         /* don't teleport on a trap. */
1154         if (have_flag(f_ptr->flags, FF_HIT_TRAP)) return FALSE;
1155
1156         if (!(mode & TELEPORT_PASSIVE))
1157         {
1158                 if (!player_can_enter(player_ptr, g_ptr->feat, 0)) return FALSE;
1159
1160                 if (have_flag(f_ptr->flags, FF_WATER) && have_flag(f_ptr->flags, FF_DEEP))
1161                 {
1162                         if (!player_ptr->levitation && !player_ptr->can_swim) return FALSE;
1163                 }
1164
1165                 if (have_flag(f_ptr->flags, FF_LAVA) && !player_ptr->immune_fire && !IS_INVULN(player_ptr))
1166                 {
1167                         /* Always forbid deep lava */
1168                         if (have_flag(f_ptr->flags, FF_DEEP)) return FALSE;
1169
1170                         /* Forbid shallow lava when the player don't have levitation */
1171                         if (!player_ptr->levitation) return FALSE;
1172                 }
1173
1174         }
1175
1176         return TRUE;
1177 }
1178
1179 /*!
1180  * @brief 地形は開くものであって、かつ開かれているかを返す /
1181  * Attempt to open the given chest at the given location
1182  * @param feat 地形ID
1183  * @return 開いた地形である場合TRUEを返す /  Return TRUE if the given feature is an open door
1184  */
1185 bool is_open(player_type *player_ptr, FEAT_IDX feat)
1186 {
1187         return have_flag(f_info[feat].flags, FF_CLOSE) && (feat != feat_state(player_ptr, feat, FF_CLOSE));
1188 }
1189
1190 /*!
1191  * @brief プレイヤーが地形踏破可能かを返す
1192  * @param feature 判定したい地形ID
1193  * @param mode 移動に関するオプションフラグ
1194  * @return 移動可能ならばTRUEを返す
1195  */
1196 bool player_can_enter(player_type *creature_ptr, FEAT_IDX feature, BIT_FLAGS16 mode)
1197 {
1198         feature_type *f_ptr = &f_info[feature];
1199
1200         if (creature_ptr->riding) return monster_can_cross_terrain(creature_ptr, feature, &r_info[creature_ptr->current_floor_ptr->m_list[creature_ptr->riding].r_idx], mode | CEM_RIDING);
1201
1202         if (have_flag(f_ptr->flags, FF_PATTERN))
1203         {
1204                 if (!(mode & CEM_P_CAN_ENTER_PATTERN)) return FALSE;
1205         }
1206
1207         if (have_flag(f_ptr->flags, FF_CAN_FLY) && creature_ptr->levitation) return TRUE;
1208         if (have_flag(f_ptr->flags, FF_CAN_SWIM) && creature_ptr->can_swim) return TRUE;
1209         if (have_flag(f_ptr->flags, FF_CAN_PASS) && creature_ptr->pass_wall) return TRUE;
1210
1211         if (!have_flag(f_ptr->flags, FF_MOVE)) return FALSE;
1212
1213         return TRUE;
1214 }
1215
1216
1217 void place_grid(player_type *player_ptr, grid_type *g_ptr, grid_bold_type gb_type)
1218 {
1219         switch (gb_type)
1220         {
1221         case GB_FLOOR:
1222         {
1223                 g_ptr->feat = feat_ground_type[randint0(100)];
1224                 g_ptr->info &= ~(CAVE_MASK);
1225                 g_ptr->info |= CAVE_FLOOR;
1226                 break;
1227         }
1228         case GB_EXTRA:
1229         {
1230                 g_ptr->feat = feat_wall_type[randint0(100)];
1231                 g_ptr->info &= ~(CAVE_MASK);
1232                 g_ptr->info |= CAVE_EXTRA;
1233                 break;
1234         }
1235         case GB_EXTRA_PERM:
1236         {
1237                 // No such grid
1238                 return;
1239         }
1240         case GB_INNER:
1241         {
1242                 g_ptr->feat = feat_wall_inner;
1243                 g_ptr->info &= ~(CAVE_MASK);
1244                 g_ptr->info |= CAVE_INNER;
1245                 break;
1246         }
1247         case GB_INNER_PERM:
1248         {
1249                 g_ptr->feat = feat_permanent;
1250                 g_ptr->info &= ~(CAVE_MASK);
1251                 g_ptr->info |= CAVE_INNER;
1252                 break;
1253         }
1254         case GB_OUTER:
1255         {
1256                 g_ptr->feat = feat_wall_outer;
1257                 g_ptr->info &= ~(CAVE_MASK);
1258                 g_ptr->info |= CAVE_OUTER;
1259                 break;
1260         }
1261         case GB_OUTER_NOPERM:
1262         {
1263                 feature_type *f_ptr = &f_info[feat_wall_outer];
1264                 if (permanent_wall(f_ptr))
1265                 {
1266                         g_ptr->feat = (s16b)feat_state(player_ptr, feat_wall_outer, FF_UNPERM);
1267                 }
1268                 else
1269                 {
1270                         g_ptr->feat = feat_wall_outer;
1271                 }
1272
1273                 g_ptr->info &= ~(CAVE_MASK);
1274                 g_ptr->info |= (CAVE_OUTER | CAVE_VAULT);
1275                 break;
1276         }
1277         case GB_SOLID:
1278         {
1279                 // No such grid
1280                 return;
1281         }
1282         case GB_SOLID_PERM:
1283         {
1284                 g_ptr->feat = feat_permanent;
1285                 g_ptr->info &= ~(CAVE_MASK);
1286                 g_ptr->info |= CAVE_SOLID;
1287                 break;
1288         }
1289         case GB_SOLID_NOPERM:
1290         {
1291                 // No such grid
1292                 return;
1293         }
1294         default:
1295                 return;
1296         }
1297
1298         if (g_ptr->m_idx > 0) delete_monster_idx(player_ptr, g_ptr->m_idx);
1299 }
1300
1301
1302 /*!
1303  * モンスターにより照明が消されている地形か否かを判定する。 / Is this grid "darkened" by monster?
1304  * @param player_ptr プレーヤーへの参照ポインタ
1305  * @param g_ptr グリッドへの参照ポインタ
1306  * @return 照明が消されている地形ならばTRUE
1307  */
1308 bool darkened_grid(player_type *player_ptr, grid_type *g_ptr)
1309 {
1310         return ((g_ptr->info & (CAVE_VIEW | CAVE_LITE | CAVE_MNLT | CAVE_MNDK)) == (CAVE_VIEW | CAVE_MNDK)) &&
1311                 !player_ptr->see_nocto;
1312 }
1313
1314
1315 void place_bold(player_type *player_ptr, POSITION y, POSITION x, grid_bold_type gb_type)
1316 {
1317         floor_type *floor_ptr = player_ptr->current_floor_ptr;
1318         switch (gb_type)
1319         {
1320         case GB_FLOOR:
1321         {
1322                 set_cave_feat(floor_ptr, y, x, feat_ground_type[randint0(100)]);
1323                 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
1324                 add_cave_info(floor_ptr, y, x, CAVE_FLOOR);
1325                 break;
1326         }
1327         case GB_EXTRA:
1328         {
1329                 set_cave_feat(floor_ptr, y, x, feat_wall_type[randint0(100)]);
1330                 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
1331                 add_cave_info(floor_ptr, y, x, CAVE_EXTRA);
1332                 break;
1333         }
1334         case GB_EXTRA_PERM:
1335         {
1336                 set_cave_feat(floor_ptr, y, x, feat_permanent);
1337                 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
1338                 add_cave_info(floor_ptr, y, x, CAVE_EXTRA);
1339                 break;
1340         }
1341         case GB_INNER:
1342         {
1343                 set_cave_feat(floor_ptr, y, x, feat_wall_inner);
1344                 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
1345                 add_cave_info(floor_ptr, y, x, CAVE_INNER);
1346                 break;
1347         }
1348         case GB_INNER_PERM:
1349         {
1350                 set_cave_feat(floor_ptr, y, x, feat_permanent);
1351                 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
1352                 add_cave_info(floor_ptr, y, x, CAVE_INNER);
1353                 break;
1354         }
1355         case GB_OUTER:
1356         {
1357                 set_cave_feat(floor_ptr, y, x, feat_wall_outer);
1358                 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
1359                 add_cave_info(floor_ptr, y, x, CAVE_OUTER);
1360                 break;
1361         }
1362         case GB_OUTER_NOPERM:
1363         {
1364                 feature_type *f_ptr = &f_info[feat_wall_outer];
1365                 if (permanent_wall(f_ptr)) set_cave_feat(floor_ptr, y, x, (s16b)feat_state(player_ptr, feat_wall_outer, FF_UNPERM));
1366                 else set_cave_feat(floor_ptr, y, x, feat_wall_outer);
1367                 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
1368                 add_cave_info(floor_ptr, y, x, (CAVE_OUTER | CAVE_VAULT));
1369                 break;
1370         }
1371         case GB_SOLID:
1372         {
1373                 set_cave_feat(floor_ptr, y, x, feat_wall_solid);
1374                 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
1375                 add_cave_info(floor_ptr, y, x, CAVE_SOLID);
1376                 break;
1377         }
1378         case GB_SOLID_PERM:
1379         {
1380                 feature_type *f_ptr = &f_info[feat_wall_solid];
1381                 if ((floor_ptr->grid_array[y][x].info & CAVE_VAULT) && permanent_wall(f_ptr))
1382                         set_cave_feat(floor_ptr, y, x, feat_state(player_ptr, feat_wall_solid, FF_UNPERM));
1383                 else set_cave_feat(floor_ptr, y, x, feat_wall_solid);
1384                 floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
1385                 add_cave_info(floor_ptr, y, x, CAVE_SOLID);
1386                 break;
1387         }
1388         case GB_SOLID_NOPERM:
1389         {
1390         feature_type *f_ptr = &f_info[feat_wall_solid];
1391         if ((floor_ptr->grid_array[y][x].info & CAVE_VAULT) && permanent_wall(f_ptr))
1392             set_cave_feat(floor_ptr, y, x, feat_state(player_ptr, feat_wall_solid, FF_UNPERM));
1393         else
1394             set_cave_feat(floor_ptr, y, x, feat_wall_solid);
1395         floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
1396         add_cave_info(floor_ptr, y, x, CAVE_SOLID);
1397         delete_monster(player_ptr, y, x);
1398     }
1399         default:
1400                 return;
1401         }
1402
1403         delete_monster(player_ptr, y, x);
1404 }
1405
1406 void set_cave_feat(floor_type *floor_ptr, POSITION y, POSITION x, FEAT_IDX feature_idx)
1407 {
1408     floor_ptr->grid_array[y][x].feat = feature_idx;
1409 }
1410
1411 /*!
1412  * todo intをenumに変更する
1413  */
1414 void add_cave_info(floor_type *floor_ptr, POSITION y, POSITION x, int cave_mask)
1415 {
1416     floor_ptr->grid_array[y][x].info |= cave_mask;
1417 }