OSDN Git Service

[Refactor] #38997 project() に player_type * 引数を追加. / Add player_type * argument to...
[hengband/hengband.git] / src / floor.c
1 #include "angband.h"
2 #include "floor.h"
3 #include "floor-save.h"
4 #include "grid.h"
5 #include "dungeon.h"
6 #include "rooms.h"
7 #include "quest.h"
8 #include "object-hook.h"
9 #include "world.h"
10 #include "player-effects.h"
11 #include "object.h"
12 #include "object-hook.h"
13 #include "artifact.h"
14 #include "objectkind.h"
15
16 /*
17  * The array of floor [MAX_WID][MAX_HGT].
18  * Not completely allocated, that would be inefficient
19  * Not completely hardcoded, that would overflow memory
20  */
21 floor_type floor_info;
22
23 /*
24  * The array of saved floors
25  */
26 saved_floor_type saved_floors[MAX_SAVED_FLOORS];
27
28 /*!
29 * @brief 鍵のかかったドアを配置する
30 * @param y 配置したいフロアのY座標
31 * @param x 配置したいフロアのX座標
32 * @return なし
33 */
34 void place_locked_door(floor_type *floor_ptr, POSITION y, POSITION x)
35 {
36         if (d_info[floor_ptr->dungeon_idx].flags1 & DF1_NO_DOORS)
37         {
38                 place_floor_bold(floor_ptr, y, x);
39         }
40         else
41         {
42                 set_cave_feat(floor_ptr, y, x, feat_locked_door_random((d_info[p_ptr->dungeon_idx].flags1 & DF1_GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR));
43                 floor_ptr->grid_array[y][x].info &= ~(CAVE_FLOOR);
44                 delete_monster(y, x);
45         }
46 }
47
48
49 /*!
50 * @brief 隠しドアを配置する
51 * @param y 配置したいフロアのY座標
52 * @param x 配置したいフロアのX座標
53 * @param type DOOR_DEFAULT / DOOR_DOOR / DOOR_GLASS_DOOR / DOOR_CURTAIN のいずれか
54 * @return なし
55 */
56 void place_secret_door(floor_type *floor_ptr, POSITION y, POSITION x, int type)
57 {
58         if (d_info[floor_ptr->dungeon_idx].flags1 & DF1_NO_DOORS)
59         {
60                 place_floor_bold(floor_ptr, y, x);
61         }
62         else
63         {
64                 grid_type *g_ptr = &floor_ptr->grid_array[y][x];
65
66                 if (type == DOOR_DEFAULT)
67                 {
68                         type = ((d_info[floor_ptr->dungeon_idx].flags1 & DF1_CURTAIN) &&
69                                 one_in_((d_info[floor_ptr->dungeon_idx].flags1 & DF1_NO_CAVE) ? 16 : 256)) ? DOOR_CURTAIN :
70                                 ((d_info[floor_ptr->dungeon_idx].flags1 & DF1_GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR);
71                 }
72
73                 /* Create secret door */
74                 place_closed_door(y, x, type);
75
76                 if (type != DOOR_CURTAIN)
77                 {
78                         /* Hide by inner wall because this is used in rooms only */
79                         g_ptr->mimic = feat_wall_inner;
80
81                         /* Floor type terrain cannot hide a door */
82                         if (feat_supports_los(g_ptr->mimic) && !feat_supports_los(g_ptr->feat))
83                         {
84                                 if (have_flag(f_info[g_ptr->mimic].flags, FF_MOVE) || have_flag(f_info[g_ptr->mimic].flags, FF_CAN_FLY))
85                                 {
86                                         g_ptr->feat = one_in_(2) ? g_ptr->mimic : feat_ground_type[randint0(100)];
87                                 }
88                                 g_ptr->mimic = 0;
89                         }
90                 }
91
92                 g_ptr->info &= ~(CAVE_FLOOR);
93                 delete_monster(y, x);
94         }
95 }
96
97 static int scent_when = 0;
98
99 /*
100  * Characters leave scent trails for perceptive monsters to track.
101  *
102  * Smell is rather more limited than sound.  Many creatures cannot use
103  * it at all, it doesn't extend very far outwards from the character's
104  * current position, and monsters can use it to home in the character,
105  * but not to run away from him.
106  *
107  * Smell is valued according to age.  When a character takes his turn,
108  * scent is aged by one, and new scent of the current age is laid down.
109  * Speedy characters leave more scent, true, but it also ages faster,
110  * which makes it harder to hunt them down.
111  *
112  * Whenever the age count loops, most of the scent trail is erased and
113  * the age of the remainder is recalculated.
114  */
115 void update_smell(floor_type *floor_ptr, player_type *subject_ptr)
116 {
117         POSITION i, j;
118         POSITION y, x;
119
120         /* Create a table that controls the spread of scent */
121         const int scent_adjust[5][5] =
122         {
123                 { -1, 0, 0, 0,-1 },
124                 {  0, 1, 1, 1, 0 },
125                 {  0, 1, 2, 1, 0 },
126                 {  0, 1, 1, 1, 0 },
127                 { -1, 0, 0, 0,-1 },
128         };
129
130         /* Loop the age and adjust scent values when necessary */
131         if (++scent_when == 254)
132         {
133                 /* Scan the entire dungeon */
134                 for (y = 0; y < floor_ptr->height; y++)
135                 {
136                         for (x = 0; x < floor_ptr->width; x++)
137                         {
138                                 int w = floor_ptr->grid_array[y][x].when;
139                                 floor_ptr->grid_array[y][x].when = (w > 128) ? (w - 128) : 0;
140                         }
141                 }
142
143                 /* Restart */
144                 scent_when = 126;
145         }
146
147
148         /* Lay down new scent */
149         for (i = 0; i < 5; i++)
150         {
151                 for (j = 0; j < 5; j++)
152                 {
153                         grid_type *g_ptr;
154
155                         /* Translate table to map grids */
156                         y = i + subject_ptr->y - 2;
157                         x = j + subject_ptr->x - 2;
158
159                         /* Check Bounds */
160                         if (!in_bounds(floor_ptr, y, x)) continue;
161
162                         g_ptr = &floor_ptr->grid_array[y][x];
163
164                         /* Walls, water, and lava cannot hold scent. */
165                         if (!cave_have_flag_grid(g_ptr, FF_MOVE) && !is_closed_door(g_ptr->feat)) continue;
166
167                         /* Grid must not be blocked by walls from the character */
168                         if (!player_has_los_bold(subject_ptr, y, x)) continue;
169
170                         /* Note grids that are too far away */
171                         if (scent_adjust[i][j] == -1) continue;
172
173                         /* Mark the grid with new scent */
174                         g_ptr->when = scent_when + scent_adjust[i][j];
175                 }
176         }
177 }
178
179
180 /*
181  * Hack -- forget the "flow" information
182  */
183 void forget_flow(floor_type *floor_ptr)
184 {
185         POSITION x, y;
186
187         /* Check the entire dungeon */
188         for (y = 0; y < floor_ptr->height; y++)
189         {
190                 for (x = 0; x < floor_ptr->width; x++)
191                 {
192                         /* Forget the old data */
193                         floor_ptr->grid_array[y][x].dist = 0;
194                         floor_ptr->grid_array[y][x].cost = 0;
195                         floor_ptr->grid_array[y][x].when = 0;
196                 }
197         }
198 }
199
200 /*
201  * Routine used by the random vault creators to add a door to a location
202  * Note that range checking has to be done in the calling routine.
203  *
204  * The doors must be INSIDE the allocated region.
205  */
206 void add_door(floor_type* floor_ptr, POSITION x, POSITION y)
207 {
208         /* Need to have a wall in the center square */
209         if (!is_outer_bold(floor_ptr, y, x)) return;
210
211         /* look at:
212         *  x#x
213         *  .#.
214         *  x#x
215         *
216         *  where x=don't care
217         *  .=floor, #=wall
218         */
219
220         if (is_floor_bold(floor_ptr, y - 1, x) && is_floor_bold(floor_ptr, y + 1, x) &&
221                 (is_outer_bold(floor_ptr, y, x - 1) && is_outer_bold(floor_ptr, y, x + 1)))
222         {
223                 /* secret door */
224                 place_secret_door(floor_ptr, y, x, DOOR_DEFAULT);
225
226                 /* set boundarys so don't get wide doors */
227                 place_solid_bold(y, x - 1);
228                 place_solid_bold(y, x + 1);
229         }
230
231
232         /* look at:
233         *  x#x
234         *  .#.
235         *  x#x
236         *
237         *  where x = don't care
238         *  .=floor, #=wall
239         */
240         if (is_outer_bold(floor_ptr, y - 1, x) && is_outer_bold(floor_ptr, y + 1, x) &&
241                 is_floor_bold(floor_ptr, y, x - 1) && is_floor_bold(floor_ptr, y, x + 1))
242         {
243                 /* secret door */
244                 place_secret_door(floor_ptr, y, x, DOOR_DEFAULT);
245
246                 /* set boundarys so don't get wide doors */
247                 place_solid_bold(y - 1, x);
248                 place_solid_bold(y + 1, x);
249         }
250 }
251
252 /*!
253  * @brief 所定の位置に上り階段か下り階段を配置する / Place an up/down staircase at given location
254  * @param y 配置を試みたいマスのY座標
255  * @param x 配置を試みたいマスのX座標
256  * @return なし
257  */
258 void place_random_stairs(floor_type *floor_ptr, POSITION y, POSITION x)
259 {
260         bool up_stairs = TRUE;
261         bool down_stairs = TRUE;
262         grid_type *g_ptr;
263         g_ptr = &floor_ptr->grid_array[y][x];
264         if (!is_floor_grid(g_ptr) || g_ptr->o_idx) return;
265
266         if (!floor_ptr->dun_level) up_stairs = FALSE;
267         if (ironman_downward) up_stairs = FALSE;
268         if (floor_ptr->dun_level >= d_info[p_ptr->dungeon_idx].maxdepth) down_stairs = FALSE;
269         if (quest_number(floor_ptr->dun_level) && (floor_ptr->dun_level > 1)) down_stairs = FALSE;
270
271         /* We can't place both */
272         if (down_stairs && up_stairs)
273         {
274                 /* Choose a staircase randomly */
275                 if (randint0(100) < 50) up_stairs = FALSE;
276                 else down_stairs = FALSE;
277         }
278
279         /* Place the stairs */
280         if (up_stairs) set_cave_feat(floor_ptr, y, x, feat_up_stair);
281         else if (down_stairs) set_cave_feat(floor_ptr, y, x, feat_down_stair);
282 }
283
284 /*!
285  * @brief LOS(Line Of Sight / 視線が通っているか)の判定を行う。
286  * @param y1 始点のy座標
287  * @param x1 始点のx座標
288  * @param y2 終点のy座標
289  * @param x2 終点のx座標
290  * @return LOSが通っているならTRUEを返す。
291  * @details
292  * A simple, fast, integer-based line-of-sight algorithm.  By Joseph Hall,\n
293  * 4116 Brewster Drive, Raleigh NC 27606.  Email to jnh@ecemwl.ncsu.edu.\n
294  *\n
295  * Returns TRUE if a line of sight can be traced from (x1,y1) to (x2,y2).\n
296  *\n
297  * The LOS begins at the center of the tile (x1,y1) and ends at the center of\n
298  * the tile (x2,y2).  If los() is to return TRUE, all of the tiles this line\n
299  * passes through must be floor tiles, except for (x1,y1) and (x2,y2).\n
300  *\n
301  * We assume that the "mathematical corner" of a non-floor tile does not\n
302  * block line of sight.\n
303  *\n
304  * Because this function uses (short) ints for all calculations, overflow may\n
305  * occur if dx and dy exceed 90.\n
306  *\n
307  * Once all the degenerate cases are eliminated, the values "qx", "qy", and\n
308  * "m" are multiplied by a scale factor "f1 = abs(dx * dy * 2)", so that\n
309  * we can use integer arithmetic.\n
310  *\n
311  * We travel from start to finish along the longer axis, starting at the border\n
312  * between the first and second tiles, where the y offset = .5 * slope, taking\n
313  * into account the scale factor.  See below.\n
314  *\n
315  * Also note that this function and the "move towards target" code do NOT\n
316  * share the same properties.  Thus, you can see someone, target them, and\n
317  * then fire a bolt at them, but the bolt may hit a wall, not them.  However\n,
318  * by clever choice of target locations, you can sometimes throw a "curve".\n
319  *\n
320  * Note that "line of sight" is not "reflexive" in all cases.\n
321  *\n
322  * Use the "projectable()" routine to test "spell/missile line of sight".\n
323  *\n
324  * Use the "update_view()" function to determine player line-of-sight.\n
325  */
326 bool los(floor_type *floor_ptr, POSITION y1, POSITION x1, POSITION y2, POSITION x2)
327 {
328         /* Delta */
329         POSITION dx, dy;
330
331         /* Absolute */
332         POSITION ax, ay;
333
334         /* Signs */
335         POSITION sx, sy;
336
337         /* Fractions */
338         POSITION qx, qy;
339
340         /* Scanners */
341         POSITION tx, ty;
342
343         /* Scale factors */
344         POSITION f1, f2;
345
346         /* Slope, or 1/Slope, of LOS */
347         POSITION m;
348
349
350         /* Extract the offset */
351         dy = y2 - y1;
352         dx = x2 - x1;
353
354         /* Extract the absolute offset */
355         ay = ABS(dy);
356         ax = ABS(dx);
357
358
359         /* Handle adjacent (or identical) grids */
360         if ((ax < 2) && (ay < 2)) return TRUE;
361
362
363         /* Paranoia -- require "safe" origin */
364         /* if (!in_bounds(floor_ptr, y1, x1)) return FALSE; */
365         /* if (!in_bounds(floor_ptr, y2, x2)) return FALSE; */
366
367
368         /* Directly South/North */
369         if (!dx)
370         {
371                 /* South -- check for walls */
372                 if (dy > 0)
373                 {
374                         for (ty = y1 + 1; ty < y2; ty++)
375                         {
376                                 if (!cave_los_bold(floor_ptr, ty, x1)) return FALSE;
377                         }
378                 }
379
380                 /* North -- check for walls */
381                 else
382                 {
383                         for (ty = y1 - 1; ty > y2; ty--)
384                         {
385                                 if (!cave_los_bold(floor_ptr, ty, x1)) return FALSE;
386                         }
387                 }
388
389                 /* Assume los */
390                 return TRUE;
391         }
392
393         /* Directly East/West */
394         if (!dy)
395         {
396                 /* East -- check for walls */
397                 if (dx > 0)
398                 {
399                         for (tx = x1 + 1; tx < x2; tx++)
400                         {
401                                 if (!cave_los_bold(floor_ptr, y1, tx)) return FALSE;
402                         }
403                 }
404
405                 /* West -- check for walls */
406                 else
407                 {
408                         for (tx = x1 - 1; tx > x2; tx--)
409                         {
410                                 if (!cave_los_bold(floor_ptr, y1, tx)) return FALSE;
411                         }
412                 }
413
414                 /* Assume los */
415                 return TRUE;
416         }
417
418
419         /* Extract some signs */
420         sx = (dx < 0) ? -1 : 1;
421         sy = (dy < 0) ? -1 : 1;
422
423
424         /* Vertical "knights" */
425         if (ax == 1)
426         {
427                 if (ay == 2)
428                 {
429                         if (cave_los_bold(floor_ptr, y1 + sy, x1)) return TRUE;
430                 }
431         }
432
433         /* Horizontal "knights" */
434         else if (ay == 1)
435         {
436                 if (ax == 2)
437                 {
438                         if (cave_los_bold(floor_ptr, y1, x1 + sx)) return TRUE;
439                 }
440         }
441
442
443         /* Calculate scale factor div 2 */
444         f2 = (ax * ay);
445
446         /* Calculate scale factor */
447         f1 = f2 << 1;
448
449
450         /* Travel horizontally */
451         if (ax >= ay)
452         {
453                 /* Let m = dy / dx * 2 * (dy * dx) = 2 * dy * dy */
454                 qy = ay * ay;
455                 m = qy << 1;
456
457                 tx = x1 + sx;
458
459                 /* Consider the special case where slope == 1. */
460                 if (qy == f2)
461                 {
462                         ty = y1 + sy;
463                         qy -= f1;
464                 }
465                 else
466                 {
467                         ty = y1;
468                 }
469
470                 /* Note (below) the case (qy == f2), where */
471                 /* the LOS exactly meets the corner of a tile. */
472                 while (x2 - tx)
473                 {
474                         if (!cave_los_bold(floor_ptr, ty, tx)) return FALSE;
475
476                         qy += m;
477
478                         if (qy < f2)
479                         {
480                                 tx += sx;
481                         }
482                         else if (qy > f2)
483                         {
484                                 ty += sy;
485                                 if (!cave_los_bold(floor_ptr, ty, tx)) return FALSE;
486                                 qy -= f1;
487                                 tx += sx;
488                         }
489                         else
490                         {
491                                 ty += sy;
492                                 qy -= f1;
493                                 tx += sx;
494                         }
495                 }
496         }
497
498         /* Travel vertically */
499         else
500         {
501                 /* Let m = dx / dy * 2 * (dx * dy) = 2 * dx * dx */
502                 qx = ax * ax;
503                 m = qx << 1;
504
505                 ty = y1 + sy;
506
507                 if (qx == f2)
508                 {
509                         tx = x1 + sx;
510                         qx -= f1;
511                 }
512                 else
513                 {
514                         tx = x1;
515                 }
516
517                 /* Note (below) the case (qx == f2), where */
518                 /* the LOS exactly meets the corner of a tile. */
519                 while (y2 - ty)
520                 {
521                         if (!cave_los_bold(floor_ptr, ty, tx)) return FALSE;
522
523                         qx += m;
524
525                         if (qx < f2)
526                         {
527                                 ty += sy;
528                         }
529                         else if (qx > f2)
530                         {
531                                 tx += sx;
532                                 if (!cave_los_bold(floor_ptr, ty, tx)) return FALSE;
533                                 qx -= f1;
534                                 ty += sy;
535                         }
536                         else
537                         {
538                                 tx += sx;
539                                 qx -= f1;
540                                 ty += sy;
541                         }
542                 }
543         }
544
545         /* Assume los */
546         return TRUE;
547 }
548
549
550 /*
551  * Determine if a bolt spell cast from (y1,x1) to (y2,x2) will arrive
552  * at the final destination, assuming no monster gets in the way.
553  *
554  * This is slightly (but significantly) different from "los(y1,x1,y2,x2)".
555  */
556 bool projectable(floor_type *floor_ptr, POSITION y1, POSITION x1, POSITION y2, POSITION x2)
557 {
558         POSITION y, x;
559
560         int grid_n = 0;
561         u16b grid_g[512];
562
563         /* Check the projection path */
564         grid_n = project_path(grid_g, (project_length ? project_length : MAX_RANGE), y1, x1, y2, x2, 0);
565
566         /* Identical grid */
567         if (!grid_n) return TRUE;
568
569         /* Final grid */
570         y = GRID_Y(grid_g[grid_n - 1]);
571         x = GRID_X(grid_g[grid_n - 1]);
572
573         /* May not end in an unrequested grid */
574         if ((y != y2) || (x != x2)) return (FALSE);
575
576         /* Assume okay */
577         return (TRUE);
578 }
579
580
581 /*!
582  * @brief 特殊な部屋地形向けにモンスターを配置する / Hack -- Place some sleeping monsters near the given location
583  * @param y1 モンスターを配置したいマスの中心Y座標
584  * @param x1 モンスターを配置したいマスの中心X座標
585  * @param num 配置したいモンスターの数
586  * @return なし
587  * @details
588  * Only really called by some of the "vault" routines.
589  */
590 void vault_monsters(floor_type *floor_ptr, POSITION y1, POSITION x1, int num)
591 {
592         int k, i;
593         POSITION y, x;
594         grid_type *g_ptr;
595
596         /* Try to summon "num" monsters "near" the given location */
597         for (k = 0; k < num; k++)
598         {
599                 /* Try nine locations */
600                 for (i = 0; i < 9; i++)
601                 {
602                         int d = 1;
603
604                         /* Pick a nearby location */
605                         scatter(&y, &x, y1, x1, d, 0);
606
607                         /* Require "empty" floor grids */
608                         g_ptr = &floor_ptr->grid_array[y][x];
609                         if (!cave_empty_grid(g_ptr)) continue;
610
611                         /* Place the monster (allow groups) */
612                         floor_ptr->monster_level = floor_ptr->base_level + 2;
613                         (void)place_monster(y, x, (PM_ALLOW_SLEEP | PM_ALLOW_GROUP));
614                         floor_ptr->monster_level = floor_ptr->base_level;
615                 }
616         }
617 }
618
619
620 /*!
621  * @brief 指定された座標が地震や階段生成の対象となるマスかを返す。 / Determine if a given location may be "destroyed"
622  * @param y y座標
623  * @param x x座標
624  * @return 各種の変更が可能ならTRUEを返す。
625  * @details
626  * 条件は永久地形でなく、なおかつ該当のマスにアーティファクトが存在しないか、である。英語の旧コメントに反して*破壊*の抑止判定には現在使われていない。
627  */
628 bool cave_valid_bold(floor_type *floor_ptr, POSITION y, POSITION x)
629 {
630         grid_type *g_ptr = &floor_ptr->grid_array[y][x];
631         OBJECT_IDX this_o_idx, next_o_idx = 0;
632
633         /* Forbid perma-grids */
634         if (cave_perma_grid(g_ptr)) return (FALSE);
635
636         /* Check objects */
637         for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
638         {
639                 object_type *o_ptr;
640                 o_ptr = &floor_ptr->o_list[this_o_idx];
641                 next_o_idx = o_ptr->next_o_idx;
642
643                 /* Forbid artifact grids */
644                 if (object_is_artifact(o_ptr)) return (FALSE);
645         }
646
647         /* Accept */
648         return (TRUE);
649 }
650
651 /*
652  * Change the "feat" flag for a grid, and notice/redraw the grid
653  */
654 void cave_set_feat(floor_type *floor_ptr, POSITION y, POSITION x, FEAT_IDX feat)
655 {
656         grid_type *g_ptr = &floor_ptr->grid_array[y][x];
657         feature_type *f_ptr = &f_info[feat];
658         bool old_los, old_mirror;
659
660         if (!current_world_ptr->character_dungeon)
661         {
662                 /* Clear mimic type */
663                 g_ptr->mimic = 0;
664
665                 /* Change the feature */
666                 g_ptr->feat = feat;
667
668                 /* Hack -- glow the GLOW terrain */
669                 if (have_flag(f_ptr->flags, FF_GLOW) && !(d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS))
670                 {
671                         DIRECTION i;
672                         POSITION yy, xx;
673
674                         for (i = 0; i < 9; i++)
675                         {
676                                 yy = y + ddy_ddd[i];
677                                 xx = x + ddx_ddd[i];
678                                 if (!in_bounds2(floor_ptr, yy, xx)) continue;
679                                 floor_ptr->grid_array[yy][xx].info |= CAVE_GLOW;
680                         }
681                 }
682
683                 return;
684         }
685
686         old_los = cave_have_flag_bold(y, x, FF_LOS);
687         old_mirror = is_mirror_grid(g_ptr);
688
689         /* Clear mimic type */
690         g_ptr->mimic = 0;
691
692         /* Change the feature */
693         g_ptr->feat = feat;
694
695         /* Remove flag for mirror/glyph */
696         g_ptr->info &= ~(CAVE_OBJECT);
697
698         if (old_mirror && (d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS))
699         {
700                 g_ptr->info &= ~(CAVE_GLOW);
701                 if (!view_torch_grids) g_ptr->info &= ~(CAVE_MARK);
702
703                 update_local_illumination(p_ptr, y, x);
704         }
705
706         /* Check for change to boring grid */
707         if (!have_flag(f_ptr->flags, FF_REMEMBER)) g_ptr->info &= ~(CAVE_MARK);
708         if (g_ptr->m_idx) update_monster(p_ptr, g_ptr->m_idx, FALSE);
709
710         note_spot(y, x);
711         lite_spot(y, x);
712
713         /* Check if los has changed */
714         if (old_los ^ have_flag(f_ptr->flags, FF_LOS))
715         {
716
717 #ifdef COMPLEX_WALL_ILLUMINATION /* COMPLEX_WALL_ILLUMINATION */
718
719                 update_local_illumination(p_ptr, y, x);
720
721 #endif /* COMPLEX_WALL_ILLUMINATION */
722
723                 /* Update the visuals */
724                 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE | PU_MONSTERS);
725         }
726
727         /* Hack -- glow the GLOW terrain */
728         if (have_flag(f_ptr->flags, FF_GLOW) && !(d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS))
729         {
730                 DIRECTION i;
731                 POSITION yy, xx;
732                 grid_type *cc_ptr;
733
734                 for (i = 0; i < 9; i++)
735                 {
736                         yy = y + ddy_ddd[i];
737                         xx = x + ddx_ddd[i];
738                         if (!in_bounds2(floor_ptr, yy, xx)) continue;
739                         cc_ptr = &floor_ptr->grid_array[yy][xx];
740                         cc_ptr->info |= CAVE_GLOW;
741
742                         if (player_has_los_grid(cc_ptr))
743                         {
744                                 if (cc_ptr->m_idx) update_monster(p_ptr, cc_ptr->m_idx, FALSE);
745                                 note_spot(yy, xx);
746                                 lite_spot(yy, xx);
747                         }
748
749                         update_local_illumination(p_ptr, yy, xx);
750                 }
751
752                 if (p_ptr->special_defense & NINJA_S_STEALTH)
753                 {
754                         if (floor_ptr->grid_array[p_ptr->y][p_ptr->x].info & CAVE_GLOW) set_superstealth(p_ptr, FALSE);
755                 }
756         }
757 }
758
759
760 /*!
761  * @brief 所定の位置にさまざまな状態や種類のドアを配置する / Place a random type of door at the given location
762  * @param y ドアの配置を試みたいマスのY座標
763  * @param x ドアの配置を試みたいマスのX座標
764  * @param room 部屋に接している場合向けのドア生成か否か
765  * @return なし
766  */
767 void place_random_door(floor_type *floor_ptr, POSITION y, POSITION x, bool room)
768 {
769         int tmp, type;
770         FEAT_IDX feat = feat_none;
771         grid_type *g_ptr = &floor_ptr->grid_array[y][x];
772
773         /* Initialize mimic info */
774         g_ptr->mimic = 0;
775
776         if (d_info[floor_ptr->dungeon_idx].flags1 & DF1_NO_DOORS)
777         {
778                 place_floor_bold(floor_ptr, y, x);
779                 return;
780         }
781
782         type = ((d_info[floor_ptr->dungeon_idx].flags1 & DF1_CURTAIN) &&
783                 one_in_((d_info[floor_ptr->dungeon_idx].flags1 & DF1_NO_CAVE) ? 16 : 256)) ? DOOR_CURTAIN :
784                 ((d_info[floor_ptr->dungeon_idx].flags1 & DF1_GLASS_DOOR) ? DOOR_GLASS_DOOR : DOOR_DOOR);
785
786         /* Choose an object */
787         tmp = randint0(1000);
788
789         /* Open doors (300/1000) */
790         if (tmp < 300)
791         {
792                 /* Create open door */
793                 feat = feat_door[type].open;
794         }
795
796         /* Broken doors (100/1000) */
797         else if (tmp < 400)
798         {
799                 /* Create broken door */
800                 feat = feat_door[type].broken;
801         }
802
803         /* Secret doors (200/1000) */
804         else if (tmp < 600)
805         {
806                 /* Create secret door */
807                 place_closed_door(y, x, type);
808
809                 if (type != DOOR_CURTAIN)
810                 {
811                         /* Hide. If on the edge of room, use outer wall. */
812                         g_ptr->mimic = room ? feat_wall_outer : feat_wall_type[randint0(100)];
813
814                         /* Floor type terrain cannot hide a door */
815                         if (feat_supports_los(g_ptr->mimic) && !feat_supports_los(g_ptr->feat))
816                         {
817                                 if (have_flag(f_info[g_ptr->mimic].flags, FF_MOVE) || have_flag(f_info[g_ptr->mimic].flags, FF_CAN_FLY))
818                                 {
819                                         g_ptr->feat = one_in_(2) ? g_ptr->mimic : feat_ground_type[randint0(100)];
820                                 }
821                                 g_ptr->mimic = 0;
822                         }
823                 }
824         }
825
826         /* Closed, locked, or stuck doors (400/1000) */
827         else place_closed_door(y, x, type);
828
829         if (tmp < 400)
830         {
831                 if (feat != feat_none)
832                 {
833                         set_cave_feat(floor_ptr, y, x, feat);
834                 }
835                 else
836                 {
837                         place_floor_bold(floor_ptr, y, x);
838                 }
839         }
840
841         delete_monster(y, x);
842 }
843
844
845
846 /*!
847  * @brief グローバルオブジェクト配列を初期化する /
848  * Delete all the items when player leaves the level
849  * @note we do NOT visually reflect these (irrelevant) changes
850  * @details
851  * Hack -- we clear the "g_ptr->o_idx" field for every grid,
852  * and the "m_ptr->next_o_idx" field for every monster, since
853  * we know we are clearing every object.  Technically, we only
854  * clear those fields for grids/monsters containing objects,
855  * and we clear it once for every such object.
856  * @return なし
857  */
858 void wipe_o_list(floor_type *floor_ptr)
859 {
860         int i;
861
862         /* Delete the existing objects */
863         for (i = 1; i < floor_ptr->o_max; i++)
864         {
865                 object_type *o_ptr = &floor_ptr->o_list[i];
866
867                 if (!OBJECT_IS_VALID(o_ptr)) continue;
868
869                 /* Mega-Hack -- preserve artifacts */
870                 if (!current_world_ptr->character_dungeon || preserve_mode)
871                 {
872                         /* Hack -- Preserve unknown artifacts */
873                         if (object_is_fixed_artifact(o_ptr) && !object_is_known(o_ptr))
874                         {
875                                 /* Mega-Hack -- Preserve the artifact */
876                                 a_info[o_ptr->name1].cur_num = 0;
877                         }
878                 }
879
880                 if (OBJECT_IS_HELD_MONSTER(o_ptr))
881                 {
882                         monster_type *m_ptr;
883                         m_ptr = &floor_ptr->m_list[o_ptr->held_m_idx];
884
885                         /* Hack -- see above */
886                         m_ptr->hold_o_idx = 0;
887                 }
888
889                 /* Dungeon */
890                 else
891                 {
892                         grid_type *g_ptr;
893
894                         /* Access location */
895                         POSITION y = o_ptr->iy;
896                         POSITION x = o_ptr->ix;
897
898                         /* Access grid */
899                         g_ptr = &floor_ptr->grid_array[y][x];
900
901                         /* Hack -- see above */
902                         g_ptr->o_idx = 0;
903                 }
904                 object_wipe(o_ptr);
905         }
906
907         /* Reset "floor_ptr->o_max" */
908         floor_ptr->o_max = 1;
909
910         /* Reset "floor_ptr->o_cnt" */
911         floor_ptr->o_cnt = 0;
912 }
913