OSDN Git Service

[Refactor] #37353 MONSTER_FLOW_DEPTH を grid.c に移動してコメント付加。
[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 #define feat_locked_door_random(DOOR_TYPE) \
54         (feat_door[(DOOR_TYPE)].num_locked ? \
55          feat_door[(DOOR_TYPE)].locked[randint0(feat_door[(DOOR_TYPE)].num_locked)] : feat_none)
56
57 #define feat_jammed_door_random(DOOR_TYPE) \
58         (feat_door[(DOOR_TYPE)].num_jammed ? \
59          feat_door[(DOOR_TYPE)].jammed[randint0(feat_door[(DOOR_TYPE)].num_jammed)] : feat_none)
60
61 /*!
62  * @brief 地形状態フラグテーブル /
63  * The table of features' actions
64  */
65 static const byte feature_action_flags[FF_FLAG_MAX] =
66 {
67         0, /* LOS */
68         0, /* PROJECT */
69         0, /* MOVE */
70         0, /* PLACE */
71         0, /* DROP */
72         0, /* SECRET */
73         0, /* NOTICE */
74         0, /* REMEMBER */
75         0, /* OPEN */
76         0, /* CLOSE */
77         FAF_CRASH_GLASS, /* BASH */
78         0, /* SPIKE */
79         FAF_DESTROY, /* DISARM */
80         0, /* STORE */
81         FAF_DESTROY | FAF_CRASH_GLASS, /* TUNNEL */
82         0, /* MAY_HAVE_GOLD */
83         0, /* HAS_GOLD */
84         0, /* HAS_ITEM */
85         0, /* DOOR */
86         0, /* TRAP */
87         0, /* STAIRS */
88         0, /* GLYPH */
89         0, /* LESS */
90         0, /* MORE */
91         0, /* RUN */
92         0, /* FLOOR */
93         0, /* WALL */
94         0, /* PERMANENT */
95         0, /* INNER */
96         0, /* OUTER */
97         0, /* SOLID */
98         0, /* HIT_TRAP */
99
100         0, /* BRIDGE */
101         0, /* RIVER */
102         0, /* LAKE */
103         0, /* BRIDGED */
104         0, /* COVERED */
105         0, /* GLOW */
106         0, /* ENSECRET */
107         0, /* WATER */
108         0, /* LAVA */
109         0, /* SHALLOW */
110         0, /* DEEP */
111         0, /* FILLED */
112         FAF_DESTROY | FAF_CRASH_GLASS, /* HURT_ROCK */
113         0, /* HURT_FIRE */
114         0, /* HURT_COLD */
115         0, /* HURT_ACID */
116         0, /* ICE */
117         0, /* ACID */
118         0, /* OIL */
119         0, /* XXX04 */
120         0, /* CAN_CLIMB */
121         0, /* CAN_FLY */
122         0, /* CAN_SWIM */
123         0, /* CAN_PASS */
124         0, /* CAN_OOZE */
125         0, /* CAN_DIG */
126         0, /* HIDE_ITEM */
127         0, /* HIDE_SNEAK */
128         0, /* HIDE_SWIM */
129         0, /* HIDE_DIG */
130         0, /* KILL_HUGE */
131         0, /* KILL_MOVE */
132
133         0, /* PICK_TRAP */
134         0, /* PICK_DOOR */
135         0, /* ALLOC */
136         0, /* CHEST */
137         0, /* DROP_1D2 */
138         0, /* DROP_2D2 */
139         0, /* DROP_GOOD */
140         0, /* DROP_GREAT */
141         0, /* HURT_POIS */
142         0, /* HURT_ELEC */
143         0, /* HURT_WATER */
144         0, /* HURT_BWATER */
145         0, /* USE_FEAT */
146         0, /* GET_FEAT */
147         0, /* GROUND */
148         0, /* OUTSIDE */
149         0, /* EASY_HIDE */
150         0, /* EASY_CLIMB */
151         0, /* MUST_CLIMB */
152         0, /* TREE */
153         0, /* NEED_TREE */
154         0, /* BLOOD */
155         0, /* DUST */
156         0, /* SLIME */
157         0, /* PLANT */
158         0, /* XXX2 */
159         0, /* INSTANT */
160         0, /* EXPLODE */
161         0, /* TIMED */
162         0, /* ERUPT */
163         0, /* STRIKE */
164         0, /* SPREAD */
165
166         0, /* SPECIAL */
167         FAF_DESTROY | FAF_NO_DROP | FAF_CRASH_GLASS, /* HURT_DISI */
168         0, /* QUEST_ENTER */
169         0, /* QUEST_EXIT */
170         0, /* QUEST */
171         0, /* SHAFT */
172         0, /* MOUNTAIN */
173         0, /* BLDG */
174         0, /* MINOR_GLYPH */
175         0, /* PATTERN */
176         0, /* TOWN */
177         0, /* ENTRANCE */
178         0, /* MIRROR */
179         0, /* UNPERM */
180         0, /* TELEPORTABLE */
181         0, /* CONVERT */
182         0, /* GLASS */
183 };
184
185 /*!
186  * @brief 新規フロアに入りたてのプレイヤーをランダムな場所に配置する / Returns random co-ordinates for player/monster/object
187  * @return 配置に成功したらTRUEを返す
188  */
189 bool new_player_spot(void)
190 {
191         POSITION y = 0, x = 0;
192         int max_attempts = 10000;
193
194         grid_type *g_ptr;
195         feature_type *f_ptr;
196
197         /* Place the player */
198         while (max_attempts--)
199         {
200                 /* Pick a legal spot */
201                 y = (POSITION)rand_range(1, current_floor_ptr->height - 2);
202                 x = (POSITION)rand_range(1, current_floor_ptr->width - 2);
203
204                 g_ptr = &current_floor_ptr->grid_array[y][x];
205
206                 /* Must be a "naked" floor grid */
207                 if (g_ptr->m_idx) continue;
208                 if (current_floor_ptr->dun_level)
209                 {
210                         f_ptr = &f_info[g_ptr->feat];
211
212                         if (max_attempts > 5000) /* Rule 1 */
213                         {
214                                 if (!have_flag(f_ptr->flags, FF_FLOOR)) continue;
215                         }
216                         else /* Rule 2 */
217                         {
218                                 if (!have_flag(f_ptr->flags, FF_MOVE)) continue;
219                                 if (have_flag(f_ptr->flags, FF_HIT_TRAP)) continue;
220                         }
221
222                         /* Refuse to start on anti-teleport grids in dungeon */
223                         if (!have_flag(f_ptr->flags, FF_TELEPORTABLE)) continue;
224                 }
225                 if (!player_can_enter(g_ptr->feat, 0)) continue;
226                 if (!in_bounds(y, x)) continue;
227
228                 /* Refuse to start on anti-teleport grids */
229                 if (g_ptr->info & (CAVE_ICKY)) continue;
230
231                 break;
232         }
233
234         if (max_attempts < 1) /* Should be -1, actually if we failed... */
235                 return FALSE;
236
237         /* Save the new player grid */
238         p_ptr->y = y;
239         p_ptr->x = x;
240
241         return TRUE;
242 }
243
244
245
246 /*!
247  * @brief 所定の位置に上り階段か下り階段を配置する / Place an up/down staircase at given location
248  * @param y 配置を試みたいマスのY座標
249  * @param x 配置を試みたいマスのX座標
250  * @return なし
251  */
252 void place_random_stairs(POSITION y, POSITION x)
253 {
254         bool up_stairs = TRUE;
255         bool down_stairs = TRUE;
256         grid_type *g_ptr;
257         g_ptr = &current_floor_ptr->grid_array[y][x];
258         if (!is_floor_grid(g_ptr) || g_ptr->o_idx) return;
259
260         /* Town */
261         if (!current_floor_ptr->dun_level) up_stairs = FALSE;
262
263         /* Ironman */
264         if (ironman_downward) up_stairs = FALSE;
265
266         /* Bottom */
267         if (current_floor_ptr->dun_level >= d_info[p_ptr->dungeon_idx].maxdepth) down_stairs = FALSE;
268
269         /* Quest-level */
270         if (quest_number(current_floor_ptr->dun_level) && (current_floor_ptr->dun_level > 1)) down_stairs = FALSE;
271
272         /* We can't place both */
273         if (down_stairs && up_stairs)
274         {
275                 /* Choose a staircase randomly */
276                 if (randint0(100) < 50) up_stairs = FALSE;
277                 else down_stairs = FALSE;
278         }
279
280         /* Place the stairs */
281         if (up_stairs) place_up_stairs(y, x);
282         else if (down_stairs) place_down_stairs(y, x);
283 }
284
285 /*!
286  * @brief 所定の位置にさまざまな状態や種類のドアを配置する / Place a random type of door at the given location
287  * @param y ドアの配置を試みたいマスのY座標
288  * @param x ドアの配置を試みたいマスのX座標
289  * @param room 部屋に接している場合向けのドア生成か否か
290  * @return なし
291  */
292 void place_random_door(POSITION y, POSITION x, bool room)
293 {
294         int tmp, type;
295         FEAT_IDX feat = feat_none;
296         grid_type *g_ptr = &current_floor_ptr->grid_array[y][x];
297
298         /* Initialize mimic info */
299         g_ptr->mimic = 0;
300
301         if (d_info[p_ptr->dungeon_idx].flags1 & DF1_NO_DOORS)
302         {
303                 place_floor_bold(y, x);
304                 return;
305         }
306
307         type = ((d_info[p_ptr->dungeon_idx].flags1 & DF1_CURTAIN) &&
308                 one_in_((d_info[p_ptr->dungeon_idx].flags1 & DF1_NO_CAVE) ? 16 : 256)) ? DOOR_CURTAIN :
309                 ((d_info[p_ptr->dungeon_idx].flags1 & DF1_GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR);
310
311         /* Choose an object */
312         tmp = randint0(1000);
313
314         /* Open doors (300/1000) */
315         if (tmp < 300)
316         {
317                 /* Create open door */
318                 feat = feat_door[type].open;
319         }
320
321         /* Broken doors (100/1000) */
322         else if (tmp < 400)
323         {
324                 /* Create broken door */
325                 feat = feat_door[type].broken;
326         }
327
328         /* Secret doors (200/1000) */
329         else if (tmp < 600)
330         {
331                 /* Create secret door */
332                 place_closed_door(y, x, type);
333
334                 if (type != DOOR_CURTAIN)
335                 {
336                         /* Hide. If on the edge of room, use outer wall. */
337                         g_ptr->mimic = room ? feat_wall_outer : feat_wall_type[randint0(100)];
338
339                         /* Floor type terrain cannot hide a door */
340                         if (feat_supports_los(g_ptr->mimic) && !feat_supports_los(g_ptr->feat))
341                         {
342                                 if (have_flag(f_info[g_ptr->mimic].flags, FF_MOVE) || have_flag(f_info[g_ptr->mimic].flags, FF_CAN_FLY))
343                                 {
344                                         g_ptr->feat = one_in_(2) ? g_ptr->mimic : feat_ground_type[randint0(100)];
345                                 }
346                                 g_ptr->mimic = 0;
347                         }
348                 }
349         }
350
351         /* Closed, locked, or stuck doors (400/1000) */
352         else place_closed_door(y, x, type);
353
354         if (tmp < 400)
355         {
356                 if (feat != feat_none)
357                 {
358                         set_cave_feat(y, x, feat);
359                 }
360                 else
361                 {
362                         place_floor_bold(y, x);
363                 }
364         }
365
366         delete_monster(y, x);
367 }
368
369 /*!
370  * @brief 所定の位置に各種の閉じたドアを配置する / Place a random type of normal door at the given location.
371  * @param y ドアの配置を試みたいマスのY座標
372  * @param x ドアの配置を試みたいマスのX座標
373  * @param type ドアの地形ID
374  * @return なし
375  */
376 void place_closed_door(POSITION y, POSITION x, int type)
377 {
378         int tmp;
379         FEAT_IDX feat = feat_none;
380
381         if (d_info[p_ptr->dungeon_idx].flags1 & DF1_NO_DOORS)
382         {
383                 place_floor_bold(y, x);
384                 return;
385         }
386
387         /* Choose an object */
388         tmp = randint0(400);
389
390         /* Closed doors (300/400) */
391         if (tmp < 300)
392         {
393                 /* Create closed door */
394                 feat = feat_door[type].closed;
395         }
396
397         /* Locked doors (99/400) */
398         else if (tmp < 399)
399         {
400                 /* Create locked door */
401                 feat = feat_locked_door_random(type);
402         }
403
404         /* Stuck doors (1/400) */
405         else
406         {
407                 /* Create jammed door */
408                 feat = feat_jammed_door_random(type);
409         }
410
411         if (feat != feat_none)
412         {
413                 cave_set_feat(y, x, feat);
414
415                 /* Now it is not floor */
416                 current_floor_ptr->grid_array[y][x].info &= ~(CAVE_MASK);
417         }
418         else
419         {
420                 place_floor_bold(y, x);
421         }
422 }
423
424 /*!
425 * @brief 鍵のかかったドアを配置する
426 * @param y 配置したいフロアのY座標
427 * @param x 配置したいフロアのX座標
428 * @return なし
429 */
430 void place_locked_door(POSITION y, POSITION x)
431 {
432         if (d_info[p_ptr->dungeon_idx].flags1 & DF1_NO_DOORS)
433         {
434                 place_floor_bold(y, x);
435         }
436         else
437         {
438                 set_cave_feat(y, x, feat_locked_door_random((d_info[p_ptr->dungeon_idx].flags1 & DF1_GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR));
439                 current_floor_ptr->grid_array[y][x].info &= ~(CAVE_FLOOR);
440                 delete_monster(y, x);
441         }
442 }
443
444
445 /*!
446 * @brief 隠しドアを配置する
447 * @param y 配置したいフロアのY座標
448 * @param x 配置したいフロアのX座標
449 * @param type DOOR_DEFAULT / DOOR_DOOR / DOOR_GLASS_DOOR / DOOR_CURTAIN のいずれか
450 * @return なし
451 */
452 void place_secret_door(POSITION y, POSITION x, int type)
453 {
454         if (d_info[p_ptr->dungeon_idx].flags1 & DF1_NO_DOORS)
455         {
456                 place_floor_bold(y, x);
457         }
458         else
459         {
460                 grid_type *g_ptr = &current_floor_ptr->grid_array[y][x];
461
462                 if (type == DOOR_DEFAULT)
463                 {
464                         type = ((d_info[p_ptr->dungeon_idx].flags1 & DF1_CURTAIN) &&
465                                 one_in_((d_info[p_ptr->dungeon_idx].flags1 & DF1_NO_CAVE) ? 16 : 256)) ? DOOR_CURTAIN :
466                                 ((d_info[p_ptr->dungeon_idx].flags1 & DF1_GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR);
467                 }
468
469                 /* Create secret door */
470                 place_closed_door(y, x, type);
471
472                 if (type != DOOR_CURTAIN)
473                 {
474                         /* Hide by inner wall because this is used in rooms only */
475                         g_ptr->mimic = feat_wall_inner;
476
477                         /* Floor type terrain cannot hide a door */
478                         if (feat_supports_los(g_ptr->mimic) && !feat_supports_los(g_ptr->feat))
479                         {
480                                 if (have_flag(f_info[g_ptr->mimic].flags, FF_MOVE) || have_flag(f_info[g_ptr->mimic].flags, FF_CAN_FLY))
481                                 {
482                                         g_ptr->feat = one_in_(2) ? g_ptr->mimic : feat_ground_type[randint0(100)];
483                                 }
484                                 g_ptr->mimic = 0;
485                         }
486                 }
487
488                 g_ptr->info &= ~(CAVE_FLOOR);
489                 delete_monster(y, x);
490         }
491 }
492
493 /*
494  * Routine used by the random vault creators to add a door to a location
495  * Note that range checking has to be done in the calling routine.
496  *
497  * The doors must be INSIDE the allocated region.
498  */
499 void add_door(POSITION x, POSITION y)
500 {
501         /* Need to have a wall in the center square */
502         if (!is_outer_bold(y, x)) return;
503
504         /* look at:
505         *  x#x
506         *  .#.
507         *  x#x
508         *
509         *  where x=don't care
510         *  .=floor, #=wall
511         */
512
513         if (is_floor_bold(y - 1, x) && is_floor_bold(y + 1, x) &&
514                 (is_outer_bold(y, x - 1) && is_outer_bold(y, x + 1)))
515         {
516                 /* secret door */
517                 place_secret_door(y, x, DOOR_DEFAULT);
518
519                 /* set boundarys so don't get wide doors */
520                 place_solid_bold(y, x - 1);
521                 place_solid_bold(y, x + 1);
522         }
523
524
525         /* look at:
526         *  x#x
527         *  .#.
528         *  x#x
529         *
530         *  where x = don't care
531         *  .=floor, #=wall
532         */
533         if (is_outer_bold(y - 1, x) && is_outer_bold(y + 1, x) &&
534                 is_floor_bold(y, x - 1) && is_floor_bold(y, x + 1))
535         {
536                 /* secret door */
537                 place_secret_door(y, x, DOOR_DEFAULT);
538
539                 /* set boundarys so don't get wide doors */
540                 place_solid_bold(y - 1, x);
541                 place_solid_bold(y + 1, x);
542         }
543 }
544
545 /*!
546 * @brief 隣接4マスに存在する通路の数を返す / Count the number of "corridor" grids adjacent to the given grid.
547 * @param y1 基準となるマスのY座標
548 * @param x1 基準となるマスのX座標
549 * @return 通路の数
550 * @note Assumes "in_bounds(y1, x1)"
551 * @details
552 * XXX XXX This routine currently only counts actual "empty floor"\n
553 * grids which are not in rooms.  We might want to also count stairs,\n
554 * open doors, closed doors, etc.
555 */
556 static int next_to_corr(POSITION y1, POSITION x1)
557 {
558         int i, k = 0;
559         POSITION y, x;
560
561         grid_type *g_ptr;
562
563         /* Scan adjacent grids */
564         for (i = 0; i < 4; i++)
565         {
566                 y = y1 + ddy_ddd[i];
567                 x = x1 + ddx_ddd[i];
568                 g_ptr = &current_floor_ptr->grid_array[y][x];
569
570                 /* Skip non floors */
571                 if (cave_have_flag_grid(g_ptr, FF_WALL)) continue;
572
573                 /* Skip non "empty floor" grids */
574                 if (!is_floor_grid(g_ptr))
575                         continue;
576
577                 /* Skip grids inside rooms */
578                 if (g_ptr->info & (CAVE_ROOM)) continue;
579
580                 /* Count these grids */
581                 k++;
582         }
583
584         /* Return the number of corridors */
585         return (k);
586 }
587
588 /*!
589 * @brief ドアを設置可能な地形かを返す / Determine if the given location is "between" two walls, and "next to" two corridor spaces.
590 * @param y 判定を行いたいマスのY座標
591 * @param x 判定を行いたいマスのX座標
592 * @return ドアを設置可能ならばTRUEを返す
593 * @note Assumes "in_bounds(y1, x1)"
594 * @details
595 * \n
596 * Assumes "in_bounds(y, x)"\n
597 */
598 static bool possible_doorway(POSITION y, POSITION x)
599 {
600         /* Count the adjacent corridors */
601         if (next_to_corr(y, x) >= 2)
602         {
603                 /* Check Vertical */
604                 if (cave_have_flag_bold(y - 1, x, FF_WALL) &&
605                         cave_have_flag_bold(y + 1, x, FF_WALL))
606                 {
607                         return (TRUE);
608                 }
609
610                 /* Check Horizontal */
611                 if (cave_have_flag_bold(y, x - 1, FF_WALL) &&
612                         cave_have_flag_bold(y, x + 1, FF_WALL))
613                 {
614                         return (TRUE);
615                 }
616         }
617
618         /* No doorway */
619         return (FALSE);
620 }
621
622 /*!
623 * @brief ドアの設置を試みる / Places door at y, x position if at least 2 walls found
624 * @param y 設置を行いたいマスのY座標
625 * @param x 設置を行いたいマスのX座標
626 * @return なし
627 */
628 void try_door(POSITION y, POSITION x)
629 {       if (!in_bounds(y, x)) return;
630
631         /* Ignore walls */
632         if (cave_have_flag_bold(y, x, FF_WALL)) return;
633
634         /* Ignore room grids */
635         if (current_floor_ptr->grid_array[y][x].info & (CAVE_ROOM)) return;
636
637         /* Occasional door (if allowed) */
638         if ((randint0(100) < dun_tun_jct) && possible_doorway(y, x) && !(d_info[p_ptr->dungeon_idx].flags1 & DF1_NO_DOORS))
639         {
640                 /* Place a door */
641                 place_random_door(y, x, FALSE);
642         }
643 }
644
645
646 /*!
647  * @brief 長方形の空洞を生成する / Make an empty square floor, for the middle of rooms
648  * @param x1 長方形の左端X座標(-1)
649  * @param x2 長方形の右端X座標(+1)
650  * @param y1 長方形の上端Y座標(-1)
651  * @param y2 長方形の下端Y座標(+1)
652  * @param light 照明の有無
653  * @return なし
654  */
655 void place_floor(POSITION x1, POSITION x2, POSITION y1, POSITION y2, bool light)
656 {
657         POSITION x, y;
658
659         /* Place a full floor under the room */
660         for (y = y1 - 1; y <= y2 + 1; y++)
661         {
662                 for (x = x1 - 1; x <= x2 + 1; x++)
663                 {
664                         place_floor_bold(y, x);
665                         add_cave_info(y, x, CAVE_ROOM);
666                         if (light) add_cave_info(y, x, CAVE_GLOW);
667                 }
668         }
669 }
670
671
672 /*!
673  * @brief 長方形の部屋を生成する / Make an empty square room, only floor and wall grids
674  * @param x1 長方形の左端X座標(-1)
675  * @param x2 長方形の右端X座標(+1)
676  * @param y1 長方形の上端Y座標(-1)
677  * @param y2 長方形の下端Y座標(+1)
678  * @param light 照明の有無
679  * @return なし
680  */
681 void place_room(POSITION x1, POSITION x2, POSITION y1, POSITION y2, bool light)
682 {
683         POSITION y, x;
684
685         place_floor(x1, x2, y1, y2, light);
686
687         /* Walls around the room */
688         for (y = y1 - 1; y <= y2 + 1; y++)
689         {
690                 place_outer_bold(y, x1 - 1);
691                 place_outer_bold(y, x2 + 1);
692         }
693         for (x = x1 - 1; x <= x2 + 1; x++)
694         {
695                 place_outer_bold(y1 - 1, x);
696                 place_outer_bold(y2 + 1, x);
697         }
698 }
699
700
701 /*!
702  * @brief 特殊な部屋向けに各種アイテムを配置する / Create up to "num" objects near the given coordinates
703  * @param y 配置したい中心マスのY座標
704  * @param x 配置したい中心マスのX座標
705  * @param num 配置したい数
706  * @return なし
707  * @details
708  * Only really called by some of the "vault" routines.
709  */
710 void vault_objects(POSITION y, POSITION x, int num)
711 {
712         int dummy = 0;
713         int i = 0, j = y, k = x;
714
715         grid_type *g_ptr;
716
717
718         /* Attempt to place 'num' objects */
719         for (; num > 0; --num)
720         {
721                 /* Try up to 11 spots looking for empty space */
722                 for (i = 0; i < 11; ++i)
723                 {
724                         /* Pick a random location */
725                         while (dummy < SAFE_MAX_ATTEMPTS)
726                         {
727                                 j = rand_spread(y, 2);
728                                 k = rand_spread(x, 3);
729                                 dummy++;
730                                 if (!in_bounds(j, k)) continue;
731                                 break;
732                         }
733
734                         if (dummy >= SAFE_MAX_ATTEMPTS && cheat_room)
735                         {
736                                 msg_print(_("警告!地下室のアイテムを配置できません!", "Warning! Could not place vault object!"));
737                         }
738
739                         /* Require "clean" floor space */
740                         g_ptr = &current_floor_ptr->grid_array[j][k];
741                         if (!is_floor_grid(g_ptr) || g_ptr->o_idx) continue;
742
743                         if (randint0(100) < 75)
744                         {
745                                 place_object(j, k, 0L);
746                         }
747                         else
748                         {
749                                 place_gold(j, k);
750                         }
751
752                         /* Placement accomplished */
753                         break;
754                 }
755         }
756 }
757
758 /*!
759  * @brief 特殊な部屋向けに各種アイテムを配置する(vault_trapのサブセット) / Place a trap with a given displacement of point
760  * @param y トラップを配置したいマスの中心Y座標
761  * @param x トラップを配置したいマスの中心X座標
762  * @param yd Y方向の配置分散マス数
763  * @param xd X方向の配置分散マス数
764  * @return なし
765  * @details
766  * Only really called by some of the "vault" routines.
767  */
768 void vault_trap_aux(POSITION y, POSITION x, POSITION yd, POSITION xd)
769 {
770         int count = 0, y1 = y, x1 = x;
771         int dummy = 0;
772
773         grid_type *g_ptr;
774
775         /* Place traps */
776         for (count = 0; count <= 5; count++)
777         {
778                 /* Get a location */
779                 while (dummy < SAFE_MAX_ATTEMPTS)
780                 {
781                         y1 = rand_spread(y, yd);
782                         x1 = rand_spread(x, xd);
783                         dummy++;
784                         if (!in_bounds(y1, x1)) continue;
785                         break;
786                 }
787
788                 if (dummy >= SAFE_MAX_ATTEMPTS && cheat_room)
789                 {
790                         msg_print(_("警告!地下室のトラップを配置できません!", "Warning! Could not place vault trap!"));
791                 }
792
793                 /* Require "naked" floor grids */
794                 g_ptr = &current_floor_ptr->grid_array[y1][x1];
795                 if (!is_floor_grid(g_ptr) || g_ptr->o_idx || g_ptr->m_idx) continue;
796
797                 /* Place the trap */
798                 place_trap(y1, x1);
799
800                 break;
801         }
802 }
803
804 /*!
805  * @brief 特殊な部屋向けに各種アイテムを配置する(メインルーチン) / Place some traps with a given displacement of given location
806  * @param y トラップを配置したいマスの中心Y座標
807  * @param x トラップを配置したいマスの中心X座標
808  * @param yd Y方向の配置分散マス数
809  * @param xd X方向の配置分散マス数
810  * @param num 配置したいトラップの数
811  * @return なし
812  * @details
813  * Only really called by some of the "vault" routines.
814  */
815 void vault_traps(POSITION y, POSITION x, POSITION yd, POSITION xd, int num)
816 {
817         int i;
818
819         for (i = 0; i < num; i++)
820         {
821                 vault_trap_aux(y, x, yd, xd);
822         }
823 }
824
825 /*!
826  * @brief 特殊な部屋地形向けにモンスターを配置する / Hack -- Place some sleeping monsters near the given location
827  * @param y1 モンスターを配置したいマスの中心Y座標
828  * @param x1 モンスターを配置したいマスの中心X座標
829  * @param num 配置したいモンスターの数
830  * @return なし
831  * @details
832  * Only really called by some of the "vault" routines.
833  */
834 void vault_monsters(POSITION y1, POSITION x1, int num)
835 {
836         int k, i;
837         POSITION y, x;
838         grid_type *g_ptr;
839
840         /* Try to summon "num" monsters "near" the given location */
841         for (k = 0; k < num; k++)
842         {
843                 /* Try nine locations */
844                 for (i = 0; i < 9; i++)
845                 {
846                         int d = 1;
847
848                         /* Pick a nearby location */
849                         scatter(&y, &x, y1, x1, d, 0);
850
851                         /* Require "empty" floor grids */
852                         g_ptr = &current_floor_ptr->grid_array[y][x];
853                         if (!cave_empty_grid(g_ptr)) continue;
854
855                         /* Place the monster (allow groups) */
856                         current_floor_ptr->monster_level = current_floor_ptr->base_level + 2;
857                         (void)place_monster(y, x, (PM_ALLOW_SLEEP | PM_ALLOW_GROUP));
858                         current_floor_ptr->monster_level = current_floor_ptr->base_level;
859                 }
860         }
861 }
862
863 /*!
864  * @brief 指定のマスが床系地形であるかを返す / Function that sees if a square is a floor.  (Includes range checking.)
865  * @param x チェックするマスのX座標
866  * @param y チェックするマスのY座標
867  * @return 床系地形ならばTRUE
868  */
869 bool get_is_floor(POSITION x, POSITION y)
870 {
871         if (!in_bounds(y, x))
872         {
873                 /* Out of bounds */
874                 return (FALSE);
875         }
876
877         /* Do the real check */
878         if (is_floor_bold(y, x)) return (TRUE);
879
880         return (FALSE);
881 }
882
883 /*!
884  * @brief 指定のマスを床地形に変える / Set a square to be floor.  (Includes range checking.)
885  * @param x 地形を変えたいマスのX座標
886  * @param y 地形を変えたいマスのY座標
887  * @return なし
888  */
889 void set_floor(POSITION x, POSITION y)
890 {
891         if (!in_bounds(y, x))
892         {
893                 /* Out of bounds */
894                 return;
895         }
896
897         if (current_floor_ptr->grid_array[y][x].info & CAVE_ROOM)
898         {
899                 /* A room border don't touch. */
900                 return;
901         }
902
903         /* Set to be floor if is a wall (don't touch lakes). */
904         if (is_extra_bold(y, x))
905                 place_floor_bold(y, x);
906 }
907
908 /*!
909  * @brief マスにフロア端用の永久壁を配置する / Set boundary mimic and add "solid" perma-wall
910  * @param g_ptr 永久壁を配置したいマス構造体の参照ポインタ
911  * @return なし
912  */
913 void place_bound_perm_wall(grid_type *g_ptr)
914 {
915         if (bound_walls_perm)
916         {
917                 /* Clear boundary mimic */
918                 g_ptr->mimic = 0;
919         }
920         else
921         {
922                 feature_type *f_ptr = &f_info[g_ptr->feat];
923
924                 /* Hack -- Decline boundary walls with known treasure  */
925                 if ((have_flag(f_ptr->flags, FF_HAS_GOLD) || have_flag(f_ptr->flags, FF_HAS_ITEM)) &&
926                         !have_flag(f_ptr->flags, FF_SECRET))
927                         g_ptr->feat = feat_state(g_ptr->feat, FF_ENSECRET);
928
929                 /* Set boundary mimic */
930                 g_ptr->mimic = g_ptr->feat;
931         }
932
933         /* Add "solid" perma-wall */
934         place_solid_perm_grid(g_ptr);
935 }
936
937 /*!
938  * @brief マスに看破済みの罠があるかの判定を行う。 / Return TRUE if the given grid is a known trap
939  * @param g_ptr マス構造体の参照ポインタ
940  * @return 看破済みの罠があるならTRUEを返す。
941  */
942 bool is_known_trap(grid_type *g_ptr)
943 {
944         if (!g_ptr->mimic && !cave_have_flag_grid(g_ptr, FF_SECRET) &&
945                 is_trap(g_ptr->feat)) return TRUE;
946         else
947                 return FALSE;
948 }
949
950
951
952 /*!
953  * @brief マスに隠されたドアがあるかの判定を行う。 / Return TRUE if the given grid is a hidden closed door
954  * @param g_ptr マス構造体の参照ポインタ
955  * @return 隠されたドアがあるならTRUEを返す。
956  */
957 bool is_hidden_door(grid_type *g_ptr)
958 {
959         if ((g_ptr->mimic || cave_have_flag_grid(g_ptr, FF_SECRET)) &&
960                 is_closed_door(g_ptr->feat))
961                 return TRUE;
962         else
963                 return FALSE;
964 }
965
966 #define COMPLEX_WALL_ILLUMINATION /*!< 照明状態を壁により影響を受ける、より複雑な判定に切り替えるマクロ */
967
968
969 /*!
970  * @brief 指定された座標のマスが現在照らされているかを返す。 / Check for "local" illumination
971  * @param y y座標
972  * @param x x座標
973  * @return 指定された座標に照明がかかっているならTRUEを返す。。
974  */
975 bool check_local_illumination(POSITION y, POSITION x)
976 {
977         /* Hack -- move towards player */
978         POSITION yy = (y < p_ptr->y) ? (y + 1) : (y > p_ptr->y) ? (y - 1) : y;
979         POSITION xx = (x < p_ptr->x) ? (x + 1) : (x > p_ptr->x) ? (x - 1) : x;
980
981         /* Check for "local" illumination */
982
983 #ifdef COMPLEX_WALL_ILLUMINATION /* COMPLEX_WALL_ILLUMINATION */
984
985         /* Check for "complex" illumination */
986         if ((feat_supports_los(get_feat_mimic(&current_floor_ptr->grid_array[yy][xx])) &&
987                 (current_floor_ptr->grid_array[yy][xx].info & CAVE_GLOW)) ||
988                 (feat_supports_los(get_feat_mimic(&current_floor_ptr->grid_array[y][xx])) &&
989                 (current_floor_ptr->grid_array[y][xx].info & CAVE_GLOW)) ||
990                         (feat_supports_los(get_feat_mimic(&current_floor_ptr->grid_array[yy][x])) &&
991                 (current_floor_ptr->grid_array[yy][x].info & CAVE_GLOW)))
992         {
993                 return TRUE;
994         }
995         else return FALSE;
996
997 #else /* COMPLEX_WALL_ILLUMINATION */
998
999         /* Check for "simple" illumination */
1000         return (current_floor_ptr->grid_array[yy][xx].info & CAVE_GLOW) ? TRUE : FALSE;
1001
1002 #endif /* COMPLEX_WALL_ILLUMINATION */
1003 }
1004
1005
1006 /*! 対象座標のマスの照明状態を更新する際の補助処理マクロ */
1007 #define update_local_illumination_aux(Y, X) \
1008 { \
1009         if (player_has_los_bold((Y), (X))) \
1010         { \
1011                 /* Update the monster */ \
1012                 if (current_floor_ptr->grid_array[(Y)][(X)].m_idx) update_monster(current_floor_ptr->grid_array[(Y)][(X)].m_idx, FALSE); \
1013 \
1014                 /* Notice and redraw */ \
1015                 note_spot((Y), (X)); \
1016                 lite_spot((Y), (X)); \
1017         } \
1018 }
1019
1020 /*!
1021  * @brief 指定された座標の照明状態を更新する / Update "local" illumination
1022  * @param y y座標
1023  * @param x x座標
1024  * @return なし
1025  */
1026 void update_local_illumination(POSITION y, POSITION x)
1027 {
1028         int i;
1029         POSITION yy, xx;
1030
1031         if (!in_bounds(y, x)) return;
1032
1033 #ifdef COMPLEX_WALL_ILLUMINATION /* COMPLEX_WALL_ILLUMINATION */
1034
1035         if ((y != p_ptr->y) && (x != p_ptr->x))
1036         {
1037                 yy = (y < p_ptr->y) ? (y - 1) : (y + 1);
1038                 xx = (x < p_ptr->x) ? (x - 1) : (x + 1);
1039                 update_local_illumination_aux(yy, xx);
1040                 update_local_illumination_aux(y, xx);
1041                 update_local_illumination_aux(yy, x);
1042         }
1043         else if (x != p_ptr->x) /* y == p_ptr->y */
1044         {
1045                 xx = (x < p_ptr->x) ? (x - 1) : (x + 1);
1046                 for (i = -1; i <= 1; i++)
1047                 {
1048                         yy = y + i;
1049                         update_local_illumination_aux(yy, xx);
1050                 }
1051                 yy = y - 1;
1052                 update_local_illumination_aux(yy, x);
1053                 yy = y + 1;
1054                 update_local_illumination_aux(yy, x);
1055         }
1056         else if (y != p_ptr->y) /* x == p_ptr->x */
1057         {
1058                 yy = (y < p_ptr->y) ? (y - 1) : (y + 1);
1059                 for (i = -1; i <= 1; i++)
1060                 {
1061                         xx = x + i;
1062                         update_local_illumination_aux(yy, xx);
1063                 }
1064                 xx = x - 1;
1065                 update_local_illumination_aux(y, xx);
1066                 xx = x + 1;
1067                 update_local_illumination_aux(y, xx);
1068         }
1069         else /* Player's grid */
1070         {
1071                 for (i = 0; i < 8; i++)
1072                 {
1073                         yy = y + ddy_cdd[i];
1074                         xx = x + ddx_cdd[i];
1075                         update_local_illumination_aux(yy, xx);
1076                 }
1077         }
1078
1079 #else /* COMPLEX_WALL_ILLUMINATION */
1080
1081         if ((y != p_ptr->y) && (x != p_ptr->x))
1082         {
1083                 yy = (y < p_ptr->y) ? (y - 1) : (y + 1);
1084                 xx = (x < p_ptr->x) ? (x - 1) : (x + 1);
1085                 update_local_illumination_aux(yy, xx);
1086         }
1087         else if (x != p_ptr->x) /* y == p_ptr->y */
1088         {
1089                 xx = (x < p_ptr->x) ? (x - 1) : (x + 1);
1090                 for (i = -1; i <= 1; i++)
1091                 {
1092                         yy = y + i;
1093                         update_local_illumination_aux(yy, xx);
1094                 }
1095         }
1096         else if (y != p_ptr->y) /* x == p_ptr->x */
1097         {
1098                 yy = (y < p_ptr->y) ? (y - 1) : (y + 1);
1099                 for (i = -1; i <= 1; i++)
1100                 {
1101                         xx = x + i;
1102                         update_local_illumination_aux(yy, xx);
1103                 }
1104         }
1105         else /* Player's grid */
1106         {
1107                 for (i = 0; i < 8; i++)
1108                 {
1109                         yy = y + ddy_cdd[i];
1110                         xx = x + ddx_cdd[i];
1111                         update_local_illumination_aux(yy, xx);
1112                 }
1113         }
1114
1115 #endif /* COMPLEX_WALL_ILLUMINATION */
1116 }
1117
1118
1119 /*!
1120  * @brief 指定された座標をプレイヤーが視覚に収められるかを返す。 / Can the player "see" the given grid in detail?
1121  * @param y y座標
1122  * @param x x座標
1123  * @return 視覚に収められる状態ならTRUEを返す
1124  * @details
1125  * He must have vision, illumination, and line of sight.\n
1126  * \n
1127  * Note -- "CAVE_LITE" is only set if the "torch" has "los()".\n
1128  * So, given "CAVE_LITE", we know that the grid is "fully visible".\n
1129  *\n
1130  * Note that "CAVE_GLOW" makes little sense for a wall, since it would mean\n
1131  * that a wall is visible from any direction.  That would be odd.  Except\n
1132  * under wizard light, which might make sense.  Thus, for walls, we require\n
1133  * not only that they be "CAVE_GLOW", but also, that they be adjacent to a\n
1134  * grid which is not only "CAVE_GLOW", but which is a non-wall, and which is\n
1135  * in line of sight of the player.\n
1136  *\n
1137  * This extra check is expensive, but it provides a more "correct" semantics.\n
1138  *\n
1139  * Note that we should not run this check on walls which are "outer walls" of\n
1140  * the dungeon, or we will induce a memory fault, but actually verifying all\n
1141  * of the locations would be extremely expensive.\n
1142  *\n
1143  * Thus, to speed up the function, we assume that all "perma-walls" which are\n
1144  * "CAVE_GLOW" are "illuminated" from all sides.  This is correct for all cases\n
1145  * except "vaults" and the "buildings" in town.  But the town is a hack anyway,\n
1146  * and the player has more important things on his mind when he is attacking a\n
1147  * monster vault.  It is annoying, but an extremely important optimization.\n
1148  *\n
1149  * Note that "glowing walls" are only considered to be "illuminated" if the\n
1150  * grid which is next to the wall in the direction of the player is also a\n
1151  * "glowing" grid.  This prevents the player from being able to "see" the\n
1152  * walls of illuminated rooms from a corridor outside the room.\n
1153  */
1154 bool player_can_see_bold(POSITION y, POSITION x)
1155 {
1156         grid_type *g_ptr;
1157
1158         /* Blind players see nothing */
1159         if (p_ptr->blind) return FALSE;
1160
1161         g_ptr = &current_floor_ptr->grid_array[y][x];
1162
1163         /* Note that "torch-lite" yields "illumination" */
1164         if (g_ptr->info & (CAVE_LITE | CAVE_MNLT)) return TRUE;
1165
1166         /* Require line of sight to the grid */
1167         if (!player_has_los_bold(y, x)) return FALSE;
1168
1169         /* Noctovision of Ninja */
1170         if (p_ptr->see_nocto) return TRUE;
1171
1172         /* Require "perma-lite" of the grid */
1173         if ((g_ptr->info & (CAVE_GLOW | CAVE_MNDK)) != CAVE_GLOW) return FALSE;
1174
1175         /* Feature code (applying "mimic" field) */
1176         /* Floors are simple */
1177         if (feat_supports_los(get_feat_mimic(g_ptr))) return TRUE;
1178
1179         /* Check for "local" illumination */
1180         return check_local_illumination(y, x);
1181 }
1182
1183 /*!
1184  * @brief 指定された座標をプレイヤー収められていない状態かどうか / Returns true if the player's grid is dark
1185  * @return 視覚に収められていないならTRUEを返す
1186  * @details player_can_see_bold()関数の返り値の否定を返している。
1187  */
1188 bool no_lite(void)
1189 {
1190         return (!player_can_see_bold(p_ptr->y, p_ptr->x));
1191 }
1192
1193
1194 /*!
1195  * @brief 指定された座標が地震や階段生成の対象となるマスかを返す。 / Determine if a given location may be "destroyed"
1196  * @param y y座標
1197  * @param x x座標
1198  * @return 各種の変更が可能ならTRUEを返す。
1199  * @details
1200  * 条件は永久地形でなく、なおかつ該当のマスにアーティファクトが存在しないか、である。英語の旧コメントに反して*破壊*の抑止判定には現在使われていない。
1201  */
1202 bool cave_valid_bold(POSITION y, POSITION x)
1203 {
1204         grid_type *g_ptr = &current_floor_ptr->grid_array[y][x];
1205         OBJECT_IDX this_o_idx, next_o_idx = 0;
1206
1207         /* Forbid perma-grids */
1208         if (cave_perma_grid(g_ptr)) return (FALSE);
1209
1210         /* Check objects */
1211         for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
1212         {
1213                 object_type *o_ptr;
1214                 o_ptr = &current_floor_ptr->o_list[this_o_idx];
1215                 next_o_idx = o_ptr->next_o_idx;
1216
1217                 /* Forbid artifact grids */
1218                 if (object_is_artifact(o_ptr)) return (FALSE);
1219         }
1220
1221         /* Accept */
1222         return (TRUE);
1223 }
1224
1225
1226
1227 /*
1228  * Place an attr/char pair at the given map coordinate, if legal.
1229  */
1230 void print_rel(SYMBOL_CODE c, TERM_COLOR a, TERM_LEN y, TERM_LEN x)
1231 {
1232         /* Only do "legal" locations */
1233         if (panel_contains(y, x))
1234         {
1235                 /* Hack -- fake monochrome */
1236                 if (!use_graphics)
1237                 {
1238                         if (current_world_ptr->timewalk_m_idx) a = TERM_DARK;
1239                         else if (IS_INVULN() || p_ptr->timewalk) a = TERM_WHITE;
1240                         else if (p_ptr->wraith_form) a = TERM_L_DARK;
1241                 }
1242
1243                 /* Draw the char using the attr */
1244                 Term_queue_bigchar(panel_col_of(x), y - panel_row_prt, a, c, 0, 0);
1245         }
1246 }
1247
1248
1249
1250
1251
1252 /*
1253  * Memorize interesting viewable object/features in the given grid
1254  *
1255  * This function should only be called on "legal" grids.
1256  *
1257  * This function will memorize the object and/or feature in the given
1258  * grid, if they are (1) viewable and (2) interesting.  Note that all
1259  * objects are interesting, all terrain features except floors (and
1260  * invisible traps) are interesting, and floors (and invisible traps)
1261  * are interesting sometimes (depending on various options involving
1262  * the illumination of floor grids).
1263  *
1264  * The automatic memorization of all objects and non-floor terrain
1265  * features as soon as they are displayed allows incredible amounts
1266  * of optimization in various places, especially "map_info()".
1267  *
1268  * Note that the memorization of objects is completely separate from
1269  * the memorization of terrain features, preventing annoying floor
1270  * memorization when a detected object is picked up from a dark floor,
1271  * and object memorization when an object is dropped into a floor grid
1272  * which is memorized but out-of-sight.
1273  *
1274  * This function should be called every time the "memorization" of
1275  * a grid (or the object in a grid) is called into question, such
1276  * as when an object is created in a grid, when a terrain feature
1277  * "changes" from "floor" to "non-floor", when any grid becomes
1278  * "illuminated" or "viewable", and when a "floor" grid becomes
1279  * "torch-lit".
1280  *
1281  * Note the relatively efficient use of this function by the various
1282  * "update_view()" and "update_lite()" calls, to allow objects and
1283  * terrain features to be memorized (and drawn) whenever they become
1284  * viewable or illuminated in any way, but not when they "maintain"
1285  * or "lose" their previous viewability or illumination.
1286  *
1287  * Note the butchered "internal" version of "player_can_see_bold()",
1288  * optimized primarily for the most common cases, that is, for the
1289  * non-marked floor grids.
1290  */
1291 void note_spot(POSITION y, POSITION x)
1292 {
1293         grid_type *g_ptr = &current_floor_ptr->grid_array[y][x];
1294         OBJECT_IDX this_o_idx, next_o_idx = 0;
1295
1296         /* Blind players see nothing */
1297         if (p_ptr->blind) return;
1298
1299         /* Analyze non-torch-lit grids */
1300         if (!(g_ptr->info & (CAVE_LITE | CAVE_MNLT)))
1301         {
1302                 /* Require line of sight to the grid */
1303                 if (!(g_ptr->info & (CAVE_VIEW))) return;
1304
1305                 /* Require "perma-lite" of the grid */
1306                 if ((g_ptr->info & (CAVE_GLOW | CAVE_MNDK)) != CAVE_GLOW)
1307                 {
1308                         /* Not Ninja */
1309                         if (!p_ptr->see_nocto) return;
1310                 }
1311         }
1312
1313
1314         /* Hack -- memorize objects */
1315         for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
1316         {
1317                 object_type *o_ptr = &current_floor_ptr->o_list[this_o_idx];
1318                 next_o_idx = o_ptr->next_o_idx;
1319
1320                 /* Memorize objects */
1321                 o_ptr->marked |= OM_FOUND;
1322         }
1323
1324
1325         /* Hack -- memorize grids */
1326         if (!(g_ptr->info & (CAVE_MARK)))
1327         {
1328                 /* Feature code (applying "mimic" field) */
1329                 feature_type *f_ptr = &f_info[get_feat_mimic(g_ptr)];
1330
1331                 /* Memorize some "boring" grids */
1332                 if (!have_flag(f_ptr->flags, FF_REMEMBER))
1333                 {
1334                         /* Option -- memorize all torch-lit floors */
1335                         if (view_torch_grids &&
1336                                 ((g_ptr->info & (CAVE_LITE | CAVE_MNLT)) || p_ptr->see_nocto))
1337                         {
1338                                 g_ptr->info |= (CAVE_MARK);
1339                         }
1340
1341                         /* Option -- memorize all perma-lit floors */
1342                         else if (view_perma_grids && ((g_ptr->info & (CAVE_GLOW | CAVE_MNDK)) == CAVE_GLOW))
1343                         {
1344                                 g_ptr->info |= (CAVE_MARK);
1345                         }
1346                 }
1347
1348                 /* Memorize normal grids */
1349                 else if (have_flag(f_ptr->flags, FF_LOS))
1350                 {
1351                         g_ptr->info |= (CAVE_MARK);
1352                 }
1353
1354                 /* Memorize torch-lit walls */
1355                 else if (g_ptr->info & (CAVE_LITE | CAVE_MNLT))
1356                 {
1357                         g_ptr->info |= (CAVE_MARK);
1358                 }
1359
1360                 /* Memorize walls seen by noctovision of Ninja */
1361                 else if (p_ptr->see_nocto)
1362                 {
1363                         g_ptr->info |= (CAVE_MARK);
1364                 }
1365
1366                 /* Memorize certain non-torch-lit wall grids */
1367                 else if (check_local_illumination(y, x))
1368                 {
1369                         g_ptr->info |= (CAVE_MARK);
1370                 }
1371         }
1372
1373         /* Memorize terrain of the grid */
1374         g_ptr->info |= (CAVE_KNOWN);
1375 }
1376
1377 /*
1378  * Redraw (on the screen) a given MAP location
1379  *
1380  * This function should only be called on "legal" grids
1381  */
1382 void lite_spot(POSITION y, POSITION x)
1383 {
1384         /* Redraw if on screen */
1385         if (panel_contains(y, x) && in_bounds2(y, x))
1386         {
1387                 TERM_COLOR a;
1388                 SYMBOL_CODE c;
1389                 TERM_COLOR ta;
1390                 SYMBOL_CODE tc;
1391
1392                 map_info(y, x, &a, &c, &ta, &tc);
1393
1394                 /* Hack -- fake monochrome */
1395                 if (!use_graphics)
1396                 {
1397                         if (current_world_ptr->timewalk_m_idx) a = TERM_DARK;
1398                         else if (IS_INVULN() || p_ptr->timewalk) a = TERM_WHITE;
1399                         else if (p_ptr->wraith_form) a = TERM_L_DARK;
1400                 }
1401
1402                 /* Hack -- Queue it */
1403                 Term_queue_bigchar(panel_col_of(x), y - panel_row_prt, a, c, ta, tc);
1404
1405                 /* Update sub-windows */
1406                 p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
1407         }
1408 }
1409
1410 /*
1411  * Some comments on the grid flags.  -BEN-
1412  *
1413  *
1414  * One of the major bottlenecks in previous versions of Angband was in
1415  * the calculation of "line of sight" from the player to various grids,
1416  * such as monsters.  This was such a nasty bottleneck that a lot of
1417  * silly things were done to reduce the dependancy on "line of sight",
1418  * for example, you could not "see" any grids in a lit room until you
1419  * actually entered the room, and there were all kinds of bizarre grid
1420  * flags to enable this behavior.  This is also why the "call light"
1421  * spells always lit an entire room.
1422  *
1423  * The code below provides functions to calculate the "field of view"
1424  * for the player, which, once calculated, provides extremely fast
1425  * calculation of "line of sight from the player", and to calculate
1426  * the "field of torch lite", which, again, once calculated, provides
1427  * extremely fast calculation of "which grids are lit by the player's
1428  * lite source".  In addition to marking grids as "GRID_VIEW" and/or
1429  * "GRID_LITE", as appropriate, these functions maintain an array for
1430  * each of these two flags, each array containing the locations of all
1431  * of the grids marked with the appropriate flag, which can be used to
1432  * very quickly scan through all of the grids in a given set.
1433  *
1434  * To allow more "semantically valid" field of view semantics, whenever
1435  * the field of view (or the set of torch lit grids) changes, all of the
1436  * grids in the field of view (or the set of torch lit grids) are "drawn"
1437  * so that changes in the world will become apparent as soon as possible.
1438  * This has been optimized so that only grids which actually "change" are
1439  * redrawn, using the "temp" array and the "GRID_TEMP" flag to keep track
1440  * of the grids which are entering or leaving the relevent set of grids.
1441  *
1442  * These new methods are so efficient that the old nasty code was removed.
1443  *
1444  * Note that there is no reason to "update" the "viewable space" unless
1445  * the player "moves", or walls/doors are created/destroyed, and there
1446  * is no reason to "update" the "torch lit grids" unless the field of
1447  * view changes, or the "light radius" changes.  This means that when
1448  * the player is resting, or digging, or doing anything that does not
1449  * involve movement or changing the state of the dungeon, there is no
1450  * need to update the "view" or the "lite" regions, which is nice.
1451  *
1452  * Note that the calls to the nasty "los()" function have been reduced
1453  * to a bare minimum by the use of the new "field of view" calculations.
1454  *
1455  * I wouldn't be surprised if slight modifications to the "update_view()"
1456  * function would allow us to determine "reverse line-of-sight" as well
1457  * as "normal line-of-sight", which would allow monsters to use a more
1458  * "correct" calculation to determine if they can "see" the player.  For
1459  * now, monsters simply "cheat" somewhat and assume that if the player
1460  * has "line of sight" to the monster, then the monster can "pretend"
1461  * that it has "line of sight" to the player.
1462  *
1463  *
1464  * The "update_lite()" function maintains the "CAVE_LITE" flag for each
1465  * grid and maintains an array of all "CAVE_LITE" grids.
1466  *
1467  * This set of grids is the complete set of all grids which are lit by
1468  * the players light source, which allows the "player_can_see_bold()"
1469  * function to work very quickly.
1470  *
1471  * Note that every "CAVE_LITE" grid is also a "CAVE_VIEW" grid, and in
1472  * fact, the player (unless blind) can always "see" all grids which are
1473  * marked as "CAVE_LITE", unless they are "off screen".
1474  *
1475  *
1476  * The "update_view()" function maintains the "CAVE_VIEW" flag for each
1477  * grid and maintains an array of all "CAVE_VIEW" grids.
1478  *
1479  * This set of grids is the complete set of all grids within line of sight
1480  * of the player, allowing the "player_has_los_bold()" macro to work very
1481  * quickly.
1482  *
1483  *
1484  * The current "update_view()" algorithm uses the "CAVE_XTRA" flag as a
1485  * temporary internal flag to mark those grids which are not only in view,
1486  * but which are also "easily" in line of sight of the player.  This flag
1487  * is always cleared when we are done.
1488  *
1489  *
1490  * The current "update_lite()" and "update_view()" algorithms use the
1491  * "CAVE_TEMP" flag, and the array of grids which are marked as "CAVE_TEMP",
1492  * to keep track of which grids were previously marked as "CAVE_LITE" or
1493  * "CAVE_VIEW", which allows us to optimize the "screen updates".
1494  *
1495  * The "CAVE_TEMP" flag, and the array of "CAVE_TEMP" grids, is also used
1496  * for various other purposes, such as spreading lite or darkness during
1497  * "lite_room()" / "unlite_room()", and for calculating monster flow.
1498  *
1499  *
1500  * Any grid can be marked as "CAVE_GLOW" which means that the grid itself is
1501  * in some way permanently lit.  However, for the player to "see" anything
1502  * in the grid, as determined by "player_can_see()", the player must not be
1503  * blind, the grid must be marked as "CAVE_VIEW", and, in addition, "wall"
1504  * grids, even if marked as "perma lit", are only illuminated if they touch
1505  * a grid which is not a wall and is marked both "CAVE_GLOW" and "CAVE_VIEW".
1506  *
1507  *
1508  * To simplify various things, a grid may be marked as "CAVE_MARK", meaning
1509  * that even if the player cannot "see" the grid, he "knows" the terrain in
1510  * that grid.  This is used to "remember" walls/doors/stairs/floors when they
1511  * are "seen" or "detected", and also to "memorize" floors, after "wiz_lite()",
1512  * or when one of the "memorize floor grids" options induces memorization.
1513  *
1514  * Objects are "memorized" in a different way, using a special "marked" flag
1515  * on the object itself, which is set when an object is observed or detected.
1516  *
1517  *
1518  * A grid may be marked as "CAVE_ROOM" which means that it is part of a "room",
1519  * and should be illuminated by "lite room" and "darkness" spells.
1520  *
1521  *
1522  * A grid may be marked as "CAVE_ICKY" which means it is part of a "vault",
1523  * and should be unavailable for "teleportation" destinations.
1524  *
1525  *
1526  * The "view_perma_grids" allows the player to "memorize" every perma-lit grid
1527  * which is observed, and the "view_torch_grids" allows the player to memorize
1528  * every torch-lit grid.  The player will always memorize important walls,
1529  * doors, stairs, and other terrain features, as well as any "detected" grids.
1530  *
1531  * Note that the new "update_view()" method allows, among other things, a room
1532  * to be "partially" seen as the player approaches it, with a growing cone of
1533  * floor appearing as the player gets closer to the door.  Also, by not turning
1534  * on the "memorize perma-lit grids" option, the player will only "see" those
1535  * floor grids which are actually in line of sight.
1536  *
1537  * And my favorite "plus" is that you can now use a special option to draw the
1538  * "floors" in the "viewable region" brightly (actually, to draw the *other*
1539  * grids dimly), providing a "pretty" effect as the player runs around, and
1540  * to efficiently display the "torch lite" in a special color.
1541  *
1542  *
1543  * Some comments on the "update_view()" algorithm...
1544  *
1545  * The algorithm is very fast, since it spreads "obvious" grids very quickly,
1546  * and only has to call "los()" on the borderline cases.  The major axes/diags
1547  * even terminate early when they hit walls.  I need to find a quick way
1548  * to "terminate" the other scans.
1549  *
1550  * Note that in the worst case (a big empty area with say 5% scattered walls),
1551  * each of the 1500 or so nearby grids is checked once, most of them getting
1552  * an "instant" rating, and only a small portion requiring a call to "los()".
1553  *
1554  * The only time that the algorithm appears to be "noticeably" too slow is
1555  * when running, and this is usually only important in town, since the town
1556  * provides about the worst scenario possible, with large open regions and
1557  * a few scattered obstructions.  There is a special "efficiency" option to
1558  * allow the player to reduce his field of view in town, if needed.
1559  *
1560  * In the "best" case (say, a normal stretch of corridor), the algorithm
1561  * makes one check for each viewable grid, and makes no calls to "los()".
1562  * So running in corridors is very fast, and if a lot of monsters are
1563  * nearby, it is much faster than the old methods.
1564  *
1565  * Note that resting, most normal commands, and several forms of running,
1566  * plus all commands executed near large groups of monsters, are strictly
1567  * more efficient with "update_view()" that with the old "compute los() on
1568  * demand" method, primarily because once the "field of view" has been
1569  * calculated, it does not have to be recalculated until the player moves
1570  * (or a wall or door is created or destroyed).
1571  *
1572  * Note that we no longer have to do as many "los()" checks, since once the
1573  * "view" region has been built, very few things cause it to be "changed"
1574  * (player movement, and the opening/closing of doors, changes in wall status).
1575  * Note that door/wall changes are only relevant when the door/wall itself is
1576  * in the "view" region.
1577  *
1578  * The algorithm seems to only call "los()" from zero to ten times, usually
1579  * only when coming down a corridor into a room, or standing in a room, just
1580  * misaligned with a corridor.  So if, say, there are five "nearby" monsters,
1581  * we will be reducing the calls to "los()".
1582  *
1583  * I am thinking in terms of an algorithm that "walks" from the central point
1584  * out to the maximal "distance", at each point, determining the "view" code
1585  * (above).  For each grid not on a major axis or diagonal, the "view" code
1586  * depends on the "cave_los_bold()" and "view" of exactly two other grids
1587  * (the one along the nearest diagonal, and the one next to that one, see
1588  * "update_view_aux()"...).
1589  *
1590  * We "memorize" the viewable space array, so that at the cost of under 3000
1591  * bytes, we reduce the time taken by "forget_view()" to one assignment for
1592  * each grid actually in the "viewable space".  And for another 3000 bytes,
1593  * we prevent "erase + redraw" ineffiencies via the "seen" set.  These bytes
1594  * are also used by other routines, thus reducing the cost to almost nothing.
1595  *
1596  * A similar thing is done for "forget_lite()" in which case the savings are
1597  * much less, but save us from doing bizarre maintenance checking.
1598  *
1599  * In the worst "normal" case (in the middle of the town), the reachable space
1600  * actually reaches to more than half of the largest possible "circle" of view,
1601  * or about 800 grids, and in the worse case (in the middle of a dungeon level
1602  * where all the walls have been removed), the reachable space actually reaches
1603  * the theoretical maximum size of just under 1500 grids.
1604  *
1605  * Each grid G examines the "state" of two (?) other (adjacent) grids, G1 & G2.
1606  * If G1 is lite, G is lite.  Else if G2 is lite, G is half.  Else if G1 and G2
1607  * are both half, G is half.  Else G is dark.  It only takes 2 (or 4) bits to
1608  * "name" a grid, so (for MAX_RAD of 20) we could use 1600 bytes, and scan the
1609  * entire possible space (including initialization) in one step per grid.  If
1610  * we do the "clearing" as a separate step (and use an array of "view" grids),
1611  * then the clearing will take as many steps as grids that were viewed, and the
1612  * algorithm will be able to "stop" scanning at various points.
1613  * Oh, and outside of the "torch radius", only "lite" grids need to be scanned.
1614  */
1615
1616 /*
1617  * Mega-Hack -- Delayed visual update
1618  * Only used if update_view(), update_lite() or update_mon_lite() was called
1619  */
1620 void delayed_visual_update(void)
1621 {
1622         int i;
1623         POSITION y, x;
1624         grid_type *g_ptr;
1625
1626         /* Update needed grids */
1627         for (i = 0; i < current_floor_ptr->redraw_n; i++)
1628         {
1629                 y = current_floor_ptr->redraw_y[i];
1630                 x = current_floor_ptr->redraw_x[i];
1631                 g_ptr = &current_floor_ptr->grid_array[y][x];
1632
1633                 /* Update only needed grids (prevent multiple updating) */
1634                 if (!(g_ptr->info & CAVE_REDRAW)) continue;
1635
1636                 /* If required, note */
1637                 if (g_ptr->info & CAVE_NOTE) note_spot(y, x);
1638
1639                 lite_spot(y, x);
1640
1641                 /* Hack -- Visual update of monster on this grid */
1642                 if (g_ptr->m_idx) update_monster(g_ptr->m_idx, FALSE);
1643
1644                 /* No longer in the array */
1645                 g_ptr->info &= ~(CAVE_NOTE | CAVE_REDRAW);
1646         }
1647
1648         /* None left */
1649         current_floor_ptr->redraw_n = 0;
1650 }
1651
1652
1653 /*
1654  * Hack -- forget the "flow" information
1655  */
1656 void forget_flow(void)
1657 {
1658         POSITION x, y;
1659
1660         /* Check the entire dungeon */
1661         for (y = 0; y < current_floor_ptr->height; y++)
1662         {
1663                 for (x = 0; x < current_floor_ptr->width; x++)
1664                 {
1665                         /* Forget the old data */
1666                         current_floor_ptr->grid_array[y][x].dist = 0;
1667                         current_floor_ptr->grid_array[y][x].cost = 0;
1668                         current_floor_ptr->grid_array[y][x].when = 0;
1669                 }
1670         }
1671 }
1672
1673
1674 /*
1675  * Hack - speed up the update_flow algorithm by only doing
1676  * it everytime the player moves out of LOS of the last
1677  * "way-point".
1678  */
1679 static POSITION flow_x = 0;
1680 static POSITION flow_y = 0;
1681
1682
1683
1684 /*
1685  * Hack -- fill in the "cost" field of every grid that the player
1686  * can "reach" with the number of steps needed to reach that grid.
1687  * This also yields the "distance" of the player from every grid.
1688  *
1689  * In addition, mark the "when" of the grids that can reach
1690  * the player with the incremented value of "flow_n".
1691  *
1692  * Hack -- use the "seen" array as a "circular queue".
1693  *
1694  * We do not need a priority queue because the cost from grid
1695  * to grid is always "one" and we process them in order.
1696  */
1697 void update_flow(void)
1698 {
1699         POSITION x, y;
1700         DIRECTION d;
1701         int flow_head = 1;
1702         int flow_tail = 0;
1703
1704         /* Paranoia -- make sure the array is empty */
1705         if (tmp_pos.n) return;
1706
1707         /* The last way-point is on the map */
1708         if (p_ptr->running && in_bounds(flow_y, flow_x))
1709         {
1710                 /* The way point is in sight - do not update.  (Speedup) */
1711                 if (current_floor_ptr->grid_array[flow_y][flow_x].info & CAVE_VIEW) return;
1712         }
1713
1714         /* Erase all of the current flow information */
1715         for (y = 0; y < current_floor_ptr->height; y++)
1716         {
1717                 for (x = 0; x < current_floor_ptr->width; x++)
1718                 {
1719                         current_floor_ptr->grid_array[y][x].cost = 0;
1720                         current_floor_ptr->grid_array[y][x].dist = 0;
1721                 }
1722         }
1723
1724         /* Save player position */
1725         flow_y = p_ptr->y;
1726         flow_x = p_ptr->x;
1727
1728         /* Add the player's grid to the queue */
1729         tmp_pos.y[0] = p_ptr->y;
1730         tmp_pos.x[0] = p_ptr->x;
1731
1732         /* Now process the queue */
1733         while (flow_head != flow_tail)
1734         {
1735                 int ty, tx;
1736
1737                 /* Extract the next entry */
1738                 ty = tmp_pos.y[flow_tail];
1739                 tx = tmp_pos.x[flow_tail];
1740
1741                 /* Forget that entry */
1742                 if (++flow_tail == TEMP_MAX) flow_tail = 0;
1743
1744                 /* Add the "children" */
1745                 for (d = 0; d < 8; d++)
1746                 {
1747                         int old_head = flow_head;
1748                         byte_hack m = current_floor_ptr->grid_array[ty][tx].cost + 1;
1749                         byte_hack n = current_floor_ptr->grid_array[ty][tx].dist + 1;
1750                         grid_type *g_ptr;
1751
1752                         /* Child location */
1753                         y = ty + ddy_ddd[d];
1754                         x = tx + ddx_ddd[d];
1755
1756                         /* Ignore player's grid */
1757                         if (player_bold(y, x)) continue;
1758
1759                         g_ptr = &current_floor_ptr->grid_array[y][x];
1760
1761                         if (is_closed_door(g_ptr->feat)) m += 3;
1762
1763                         /* Ignore "pre-stamped" entries */
1764                         if (g_ptr->dist != 0 && g_ptr->dist <= n && g_ptr->cost <= m) continue;
1765
1766                         /* Ignore "walls" and "rubble" */
1767                         if (!cave_have_flag_grid(g_ptr, FF_MOVE) && !is_closed_door(g_ptr->feat)) continue;
1768
1769                         /* Save the flow cost */
1770                         if (g_ptr->cost == 0 || g_ptr->cost > m) g_ptr->cost = m;
1771                         if (g_ptr->dist == 0 || g_ptr->dist > n) g_ptr->dist = n;
1772
1773                         /* Hack -- limit flow depth */
1774                         if (n == MONSTER_FLOW_DEPTH) continue;
1775
1776                         /* Enqueue that entry */
1777                         tmp_pos.y[flow_head] = y;
1778                         tmp_pos.x[flow_head] = x;
1779
1780                         /* Advance the queue */
1781                         if (++flow_head == TEMP_MAX) flow_head = 0;
1782
1783                         /* Hack -- notice overflow by forgetting new entry */
1784                         if (flow_head == flow_tail) flow_head = old_head;
1785                 }
1786         }
1787 }
1788
1789
1790 static int scent_when = 0;
1791
1792 /*
1793  * Characters leave scent trails for perceptive monsters to track.
1794  *
1795  * Smell is rather more limited than sound.  Many creatures cannot use
1796  * it at all, it doesn't extend very far outwards from the character's
1797  * current position, and monsters can use it to home in the character,
1798  * but not to run away from him.
1799  *
1800  * Smell is valued according to age.  When a character takes his current_world_ptr->game_turn,
1801  * scent is aged by one, and new scent of the current age is laid down.
1802  * Speedy characters leave more scent, true, but it also ages faster,
1803  * which makes it harder to hunt them down.
1804  *
1805  * Whenever the age count loops, most of the scent trail is erased and
1806  * the age of the remainder is recalculated.
1807  */
1808 void update_smell(void)
1809 {
1810         POSITION i, j;
1811         POSITION y, x;
1812
1813         /* Create a table that controls the spread of scent */
1814         const int scent_adjust[5][5] =
1815         {
1816                 { -1, 0, 0, 0,-1 },
1817                 {  0, 1, 1, 1, 0 },
1818                 {  0, 1, 2, 1, 0 },
1819                 {  0, 1, 1, 1, 0 },
1820                 { -1, 0, 0, 0,-1 },
1821         };
1822
1823         /* Loop the age and adjust scent values when necessary */
1824         if (++scent_when == 254)
1825         {
1826                 /* Scan the entire dungeon */
1827                 for (y = 0; y < current_floor_ptr->height; y++)
1828                 {
1829                         for (x = 0; x < current_floor_ptr->width; x++)
1830                         {
1831                                 int w = current_floor_ptr->grid_array[y][x].when;
1832                                 current_floor_ptr->grid_array[y][x].when = (w > 128) ? (w - 128) : 0;
1833                         }
1834                 }
1835
1836                 /* Restart */
1837                 scent_when = 126;
1838         }
1839
1840
1841         /* Lay down new scent */
1842         for (i = 0; i < 5; i++)
1843         {
1844                 for (j = 0; j < 5; j++)
1845                 {
1846                         grid_type *g_ptr;
1847
1848                         /* Translate table to map grids */
1849                         y = i + p_ptr->y - 2;
1850                         x = j + p_ptr->x - 2;
1851
1852                         /* Check Bounds */
1853                         if (!in_bounds(y, x)) continue;
1854
1855                         g_ptr = &current_floor_ptr->grid_array[y][x];
1856
1857                         /* Walls, water, and lava cannot hold scent. */
1858                         if (!cave_have_flag_grid(g_ptr, FF_MOVE) && !is_closed_door(g_ptr->feat)) continue;
1859
1860                         /* Grid must not be blocked by walls from the character */
1861                         if (!player_has_los_bold(y, x)) continue;
1862
1863                         /* Note grids that are too far away */
1864                         if (scent_adjust[i][j] == -1) continue;
1865
1866                         /* Mark the grid with new scent */
1867                         g_ptr->when = scent_when + scent_adjust[i][j];
1868                 }
1869         }
1870 }
1871
1872
1873
1874 /*
1875  * Change the "feat" flag for a grid, and notice/redraw the grid
1876  */
1877 void cave_set_feat(POSITION y, POSITION x, FEAT_IDX feat)
1878 {
1879         grid_type *g_ptr = &current_floor_ptr->grid_array[y][x];
1880         feature_type *f_ptr = &f_info[feat];
1881         bool old_los, old_mirror;
1882
1883         if (!current_world_ptr->character_dungeon)
1884         {
1885                 /* Clear mimic type */
1886                 g_ptr->mimic = 0;
1887
1888                 /* Change the feature */
1889                 g_ptr->feat = feat;
1890
1891                 /* Hack -- glow the GLOW terrain */
1892                 if (have_flag(f_ptr->flags, FF_GLOW) && !(d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS))
1893                 {
1894                         DIRECTION i;
1895                         POSITION yy, xx;
1896
1897                         for (i = 0; i < 9; i++)
1898                         {
1899                                 yy = y + ddy_ddd[i];
1900                                 xx = x + ddx_ddd[i];
1901                                 if (!in_bounds2(yy, xx)) continue;
1902                                 current_floor_ptr->grid_array[yy][xx].info |= CAVE_GLOW;
1903                         }
1904                 }
1905
1906                 return;
1907         }
1908
1909         old_los = cave_have_flag_bold(y, x, FF_LOS);
1910         old_mirror = is_mirror_grid(g_ptr);
1911
1912         /* Clear mimic type */
1913         g_ptr->mimic = 0;
1914
1915         /* Change the feature */
1916         g_ptr->feat = feat;
1917
1918         /* Remove flag for mirror/glyph */
1919         g_ptr->info &= ~(CAVE_OBJECT);
1920
1921         if (old_mirror && (d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS))
1922         {
1923                 g_ptr->info &= ~(CAVE_GLOW);
1924                 if (!view_torch_grids) g_ptr->info &= ~(CAVE_MARK);
1925
1926                 update_local_illumination(y, x);
1927         }
1928
1929         /* Check for change to boring grid */
1930         if (!have_flag(f_ptr->flags, FF_REMEMBER)) g_ptr->info &= ~(CAVE_MARK);
1931         if (g_ptr->m_idx) update_monster(g_ptr->m_idx, FALSE);
1932
1933         note_spot(y, x);
1934         lite_spot(y, x);
1935
1936         /* Check if los has changed */
1937         if (old_los ^ have_flag(f_ptr->flags, FF_LOS))
1938         {
1939
1940 #ifdef COMPLEX_WALL_ILLUMINATION /* COMPLEX_WALL_ILLUMINATION */
1941
1942                 update_local_illumination(y, x);
1943
1944 #endif /* COMPLEX_WALL_ILLUMINATION */
1945
1946                 /* Update the visuals */
1947                 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE | PU_MONSTERS);
1948         }
1949
1950         /* Hack -- glow the GLOW terrain */
1951         if (have_flag(f_ptr->flags, FF_GLOW) && !(d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS))
1952         {
1953                 DIRECTION i;
1954                 POSITION yy, xx;
1955                 grid_type *cc_ptr;
1956
1957                 for (i = 0; i < 9; i++)
1958                 {
1959                         yy = y + ddy_ddd[i];
1960                         xx = x + ddx_ddd[i];
1961                         if (!in_bounds2(yy, xx)) continue;
1962                         cc_ptr = &current_floor_ptr->grid_array[yy][xx];
1963                         cc_ptr->info |= CAVE_GLOW;
1964
1965                         if (player_has_los_grid(cc_ptr))
1966                         {
1967                                 if (cc_ptr->m_idx) update_monster(cc_ptr->m_idx, FALSE);
1968
1969                                 note_spot(yy, xx);
1970
1971                                 lite_spot(yy, xx);
1972                         }
1973
1974                         update_local_illumination(yy, xx);
1975                 }
1976
1977                 if (p_ptr->special_defense & NINJA_S_STEALTH)
1978                 {
1979                         if (current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].info & CAVE_GLOW) set_superstealth(FALSE);
1980                 }
1981         }
1982 }
1983
1984 FEAT_IDX conv_dungeon_feat(FEAT_IDX newfeat)
1985 {
1986         feature_type *f_ptr = &f_info[newfeat];
1987
1988         if (have_flag(f_ptr->flags, FF_CONVERT))
1989         {
1990                 switch (f_ptr->subtype)
1991                 {
1992                 case CONVERT_TYPE_FLOOR:
1993                         return feat_ground_type[randint0(100)];
1994                 case CONVERT_TYPE_WALL:
1995                         return feat_wall_type[randint0(100)];
1996                 case CONVERT_TYPE_INNER:
1997                         return feat_wall_inner;
1998                 case CONVERT_TYPE_OUTER:
1999                         return feat_wall_outer;
2000                 case CONVERT_TYPE_SOLID:
2001                         return feat_wall_solid;
2002                 case CONVERT_TYPE_STREAM1:
2003                         return d_info[p_ptr->dungeon_idx].stream1;
2004                 case CONVERT_TYPE_STREAM2:
2005                         return d_info[p_ptr->dungeon_idx].stream2;
2006                 default:
2007                         return newfeat;
2008                 }
2009         }
2010         else return newfeat;
2011 }
2012
2013
2014 /*
2015  * Take a feature, determine what that feature becomes
2016  * through applying the given action.
2017  */
2018 FEAT_IDX feat_state(FEAT_IDX feat, int action)
2019 {
2020         feature_type *f_ptr = &f_info[feat];
2021         int i;
2022
2023         /* Get the new feature */
2024         for (i = 0; i < MAX_FEAT_STATES; i++)
2025         {
2026                 if (f_ptr->state[i].action == action) return conv_dungeon_feat(f_ptr->state[i].result);
2027         }
2028
2029         if (have_flag(f_ptr->flags, FF_PERMANENT)) return feat;
2030
2031         return (feature_action_flags[action] & FAF_DESTROY) ? conv_dungeon_feat(f_ptr->destroyed) : feat;
2032 }
2033
2034 /*
2035  * Takes a location and action and changes the feature at that
2036  * location through applying the given action.
2037  */
2038 void cave_alter_feat(POSITION y, POSITION x, int action)
2039 {
2040         /* Set old feature */
2041         FEAT_IDX oldfeat = current_floor_ptr->grid_array[y][x].feat;
2042
2043         /* Get the new feat */
2044         FEAT_IDX newfeat = feat_state(oldfeat, action);
2045
2046         /* No change */
2047         if (newfeat == oldfeat) return;
2048
2049         /* Set the new feature */
2050         cave_set_feat(y, x, newfeat);
2051
2052         if (!(feature_action_flags[action] & FAF_NO_DROP))
2053         {
2054                 feature_type *old_f_ptr = &f_info[oldfeat];
2055                 feature_type *f_ptr = &f_info[newfeat];
2056                 bool found = FALSE;
2057
2058                 /* Handle gold */
2059                 if (have_flag(old_f_ptr->flags, FF_HAS_GOLD) && !have_flag(f_ptr->flags, FF_HAS_GOLD))
2060                 {
2061                         /* Place some gold */
2062                         place_gold(y, x);
2063                         found = TRUE;
2064                 }
2065
2066                 /* Handle item */
2067                 if (have_flag(old_f_ptr->flags, FF_HAS_ITEM) && !have_flag(f_ptr->flags, FF_HAS_ITEM) && (randint0(100) < (15 - current_floor_ptr->dun_level / 2)))
2068                 {
2069                         /* Place object */
2070                         place_object(y, x, 0L);
2071                         found = TRUE;
2072                 }
2073
2074                 if (found && current_world_ptr->character_dungeon && player_can_see_bold(y, x))
2075                 {
2076                         msg_print(_("何かを発見した!", "You have found something!"));
2077                 }
2078         }
2079
2080         if (feature_action_flags[action] & FAF_CRASH_GLASS)
2081         {
2082                 feature_type *old_f_ptr = &f_info[oldfeat];
2083
2084                 if (have_flag(old_f_ptr->flags, FF_GLASS) && current_world_ptr->character_dungeon)
2085                 {
2086                         project(PROJECT_WHO_GLASS_SHARDS, 1, y, x, MIN(current_floor_ptr->dun_level, 100) / 4, GF_SHARDS,
2087                                 (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_HIDE | PROJECT_JUMP | PROJECT_NO_HANGEKI), -1);
2088                 }
2089         }
2090 }
2091
2092
2093 /* Remove a mirror */
2094 void remove_mirror(POSITION y, POSITION x)
2095 {
2096         grid_type *g_ptr = &current_floor_ptr->grid_array[y][x];
2097
2098         /* Remove the mirror */
2099         g_ptr->info &= ~(CAVE_OBJECT);
2100         g_ptr->mimic = 0;
2101
2102         if (d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
2103         {
2104                 g_ptr->info &= ~(CAVE_GLOW);
2105                 if (!view_torch_grids) g_ptr->info &= ~(CAVE_MARK);
2106                 if (g_ptr->m_idx) update_monster(g_ptr->m_idx, FALSE);
2107
2108                 update_local_illumination(y, x);
2109         }
2110
2111         note_spot(y, x);
2112
2113         lite_spot(y, x);
2114 }
2115
2116
2117 /*
2118  *  Return TRUE if there is a mirror on the grid.
2119  */
2120 bool is_mirror_grid(grid_type *g_ptr)
2121 {
2122         if ((g_ptr->info & CAVE_OBJECT) && have_flag(f_info[g_ptr->mimic].flags, FF_MIRROR))
2123                 return TRUE;
2124         else
2125                 return FALSE;
2126 }
2127
2128
2129 /*
2130  *  Return TRUE if there is a mirror on the grid.
2131  */
2132 bool is_glyph_grid(grid_type *g_ptr)
2133 {
2134         if ((g_ptr->info & CAVE_OBJECT) && have_flag(f_info[g_ptr->mimic].flags, FF_GLYPH))
2135                 return TRUE;
2136         else
2137                 return FALSE;
2138 }
2139
2140
2141 /*
2142  *  Return TRUE if there is a mirror on the grid.
2143  */
2144 bool is_explosive_rune_grid(grid_type *g_ptr)
2145 {
2146         if ((g_ptr->info & CAVE_OBJECT) && have_flag(f_info[g_ptr->mimic].flags, FF_MINOR_GLYPH))
2147                 return TRUE;
2148         else
2149                 return FALSE;
2150 }
2151
2152 /*!
2153 * @brief 指定されたマスがモンスターのテレポート可能先かどうかを判定する。
2154 * @param m_idx モンスターID
2155 * @param y 移動先Y座標
2156 * @param x 移動先X座標
2157 * @param mode オプション
2158 * @return テレポート先として妥当ならばtrue
2159 */
2160 bool cave_monster_teleportable_bold(MONSTER_IDX m_idx, POSITION y, POSITION x, BIT_FLAGS mode)
2161 {
2162         monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
2163         grid_type    *g_ptr = &current_floor_ptr->grid_array[y][x];
2164         feature_type *f_ptr = &f_info[g_ptr->feat];
2165
2166         /* Require "teleportable" space */
2167         if (!have_flag(f_ptr->flags, FF_TELEPORTABLE)) return FALSE;
2168
2169         if (g_ptr->m_idx && (g_ptr->m_idx != m_idx)) return FALSE;
2170         if (player_bold(y, x)) return FALSE;
2171
2172         /* Hack -- no teleport onto glyph of warding */
2173         if (is_glyph_grid(g_ptr)) return FALSE;
2174         if (is_explosive_rune_grid(g_ptr)) return FALSE;
2175
2176         if (!(mode & TELEPORT_PASSIVE))
2177         {
2178                 if (!monster_can_cross_terrain(g_ptr->feat, &r_info[m_ptr->r_idx], 0)) return FALSE;
2179         }
2180
2181         return TRUE;
2182 }
2183
2184 /*!
2185 * @brief 指定されたマスにプレイヤーがテレポート可能かどうかを判定する。
2186 * @param y 移動先Y座標
2187 * @param x 移動先X座標
2188 * @param mode オプション
2189 * @return テレポート先として妥当ならばtrue
2190 */
2191 bool cave_player_teleportable_bold(POSITION y, POSITION x, BIT_FLAGS mode)
2192 {
2193         grid_type    *g_ptr = &current_floor_ptr->grid_array[y][x];
2194         feature_type *f_ptr = &f_info[g_ptr->feat];
2195
2196         /* Require "teleportable" space */
2197         if (!have_flag(f_ptr->flags, FF_TELEPORTABLE)) return FALSE;
2198
2199         /* No magical teleporting into vaults and such */
2200         if (!(mode & TELEPORT_NONMAGICAL) && (g_ptr->info & CAVE_ICKY)) return FALSE;
2201
2202         if (g_ptr->m_idx && (g_ptr->m_idx != p_ptr->riding)) return FALSE;
2203
2204         /* don't teleport on a trap. */
2205         if (have_flag(f_ptr->flags, FF_HIT_TRAP)) return FALSE;
2206
2207         if (!(mode & TELEPORT_PASSIVE))
2208         {
2209                 if (!player_can_enter(g_ptr->feat, 0)) return FALSE;
2210
2211                 if (have_flag(f_ptr->flags, FF_WATER) && have_flag(f_ptr->flags, FF_DEEP))
2212                 {
2213                         if (!p_ptr->levitation && !p_ptr->can_swim) return FALSE;
2214                 }
2215
2216                 if (have_flag(f_ptr->flags, FF_LAVA) && !p_ptr->immune_fire && !IS_INVULN())
2217                 {
2218                         /* Always forbid deep lava */
2219                         if (have_flag(f_ptr->flags, FF_DEEP)) return FALSE;
2220
2221                         /* Forbid shallow lava when the player don't have levitation */
2222                         if (!p_ptr->levitation) return FALSE;
2223                 }
2224
2225         }
2226
2227         return TRUE;
2228 }
2229
2230 /*!
2231  * @brief 地形は開くものであって、かつ開かれているかを返す /
2232  * Attempt to open the given chest at the given location
2233  * @param feat 地形ID
2234  * @return 開いた地形である場合TRUEを返す /  Return TRUE if the given feature is an open door
2235  */
2236 bool is_open(FEAT_IDX feat)
2237 {
2238         return have_flag(f_info[feat].flags, FF_CLOSE) && (feat != feat_state(feat, FF_CLOSE));
2239 }
2240
2241 /*!
2242  * @brief プレイヤーが地形踏破可能かを返す
2243  * @param feature 判定したい地形ID
2244  * @param mode 移動に関するオプションフラグ
2245  * @return 移動可能ならばTRUEを返す
2246  */
2247 bool player_can_enter(FEAT_IDX feature, BIT_FLAGS16 mode)
2248 {
2249         feature_type *f_ptr = &f_info[feature];
2250
2251         if (p_ptr->riding) return monster_can_cross_terrain(feature, &r_info[current_floor_ptr->m_list[p_ptr->riding].r_idx], mode | CEM_RIDING);
2252
2253         if (have_flag(f_ptr->flags, FF_PATTERN))
2254         {
2255                 if (!(mode & CEM_P_CAN_ENTER_PATTERN)) return FALSE;
2256         }
2257
2258         if (have_flag(f_ptr->flags, FF_CAN_FLY) && p_ptr->levitation) return TRUE;
2259         if (have_flag(f_ptr->flags, FF_CAN_SWIM) && p_ptr->can_swim) return TRUE;
2260         if (have_flag(f_ptr->flags, FF_CAN_PASS) && p_ptr->pass_wall) return TRUE;
2261
2262         if (!have_flag(f_ptr->flags, FF_MOVE)) return FALSE;
2263
2264         return TRUE;
2265 }
2266