OSDN Git Service

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