OSDN Git Service

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