OSDN Git Service

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