OSDN Git Service

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