OSDN Git Service

Add Doxygen comment to cave.c.
[hengband/hengband.git] / src / cave.c
1 /*!
2  * @file cave.c
3  * @brief ¥À¥ó¥¸¥ç¥ó¤Î´ðÁÃÉôʬ¼ÂÁõ(¼ç¤Ë¥Þ¥¹¤Î¼ÂÁõ) / low level dungeon routines -BEN-
4  * @date 2013/12/30
5  * @author
6  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke\n
7  *\n
8  * This software may be copied and distributed for educational, research,\n
9  * and not for profit purposes provided that this copyright and statement\n
10  * are included in all such copies.  Other copyrights may also apply.\n
11  * \n
12  * Support for Adam Bolt's tileset, lighting and transparency effects\n
13  * by Robert Ruehlmann (rr9@angband.org)\n
14  * \n
15  * 2013 Deskull Doxygen¸þ¤±¤Î¥³¥á¥ó¥ÈÀ°Íý\n
16  */
17
18
19 #include "angband.h"
20
21 static byte display_autopick; /*!< ¼«Æ°½¦¤¤¾õÂÖ¤ÎÀßÄê¥Õ¥é¥° */
22 static int match_autopick;
23 static object_type *autopick_obj; /*!< ³Æ¼ï¼«Æ°½¦¤¤½èÍý»þ¤Ë»È¤¦¥ª¥Ö¥¸¥§¥¯¥È¥Ý¥¤¥ó¥¿ */
24 static int feat_priority; /*!< ¥Þ¥Ã¥×½Ì¾®É½¼¨»þ¤Ëɽ¼¨¤¹¤Ù¤­ÃÏ·Á¤ÎÍ¥ÀèÅÙ¤òÊݴɤ¹¤ë */
25
26 /*!
27  * @brief 2ÅÀ´Ö¤Îµ÷Î¥¤ò¥Ë¥å¡¼¥È¥ó¡¦¥é¥×¥½¥óË¡¤Ç»»½Ð¤¹¤ë / Distance between two points via Newton-Raphson technique
28  * @param y1 1ÅÀÌܤÎyºÂɸ
29  * @param x1 1ÅÀÌܤÎxºÂɸ
30  * @param y2 2ÅÀÌܤÎyºÂɸ
31  * @param x2 2ÅÀÌܤÎxºÂɸ
32  * @return 2ÅÀ´Ö¤Îµ÷Î¥
33  */
34 int distance (int y1, int x1, int y2, int x2)
35 {
36         int dy = (y1 > y2) ? (y1 - y2) : (y2 - y1);
37         int dx = (x1 > x2) ? (x1 - x2) : (x2 - x1);
38
39         /* Squared distance */
40         int target = (dy * dy) + (dx * dx);
41
42         /* Approximate distance: hypot(dy,dx) = max(dy,dx) + min(dy,dx) / 2 */
43         int d = (dy > dx) ? (dy + (dx>>1)) : (dx + (dy>>1));
44
45         int err;
46
47         /* Simple case */
48         if (!dy || !dx) return d;
49
50         while (1)
51         {
52                 /* Approximate error */
53                 err = (target - d * d) / (2 * d);
54
55                 /* No error - we are done */
56                 if (!err) break;
57
58                 /* Adjust distance */
59                 d += err;
60         }
61
62         return d;
63 }
64
65 /*!
66  * @brief ÃÏ·Á¤¬æ«»ý¤Á¤Ç¤¢¤ë¤«¤ÎȽÄê¤ò¹Ô¤¦¡£ / Return TRUE if the given feature is a trap
67  * @param feat ÃÏ·Á¾ðÊó¤ÎID
68  * @return æ«»ý¤Á¤ÎÃÏ·Á¤Ê¤é¤ÐTRUE¤òÊÖ¤¹¡£
69  */
70 bool is_trap(int feat)
71 {
72         return have_flag(f_info[feat].flags, FF_TRAP);
73 }
74
75
76 /*
77  * Return TRUE if the given grid is a known trap
78  */
79 bool is_known_trap(cave_type *c_ptr)
80 {
81         if (!c_ptr->mimic && !cave_have_flag_grid(c_ptr, FF_SECRET) &&
82             is_trap(c_ptr->feat)) return TRUE;
83         else
84                 return FALSE;
85 }
86
87
88 /*
89  * Return TRUE if the given grid is a closed door
90  */
91 bool is_closed_door(int feat)
92 {
93         feature_type *f_ptr = &f_info[feat];
94
95         return (have_flag(f_ptr->flags, FF_OPEN) || have_flag(f_ptr->flags, FF_BASH)) &&
96                !have_flag(f_ptr->flags, FF_MOVE);
97 }
98
99
100 /*
101  * Return TRUE if the given grid is a hidden closed door
102  */
103 bool is_hidden_door(cave_type *c_ptr)
104 {
105         if ((c_ptr->mimic || cave_have_flag_grid(c_ptr, FF_SECRET)) &&
106             is_closed_door(c_ptr->feat))
107                 return TRUE;
108         else
109                 return FALSE;
110 }
111
112
113 /*
114  * A simple, fast, integer-based line-of-sight algorithm.  By Joseph Hall,
115  * 4116 Brewster Drive, Raleigh NC 27606.  Email to jnh@ecemwl.ncsu.edu.
116  *
117  * Returns TRUE if a line of sight can be traced from (x1,y1) to (x2,y2).
118  *
119  * The LOS begins at the center of the tile (x1,y1) and ends at the center of
120  * the tile (x2,y2).  If los() is to return TRUE, all of the tiles this line
121  * passes through must be floor tiles, except for (x1,y1) and (x2,y2).
122  *
123  * We assume that the "mathematical corner" of a non-floor tile does not
124  * block line of sight.
125  *
126  * Because this function uses (short) ints for all calculations, overflow may
127  * occur if dx and dy exceed 90.
128  *
129  * Once all the degenerate cases are eliminated, the values "qx", "qy", and
130  * "m" are multiplied by a scale factor "f1 = abs(dx * dy * 2)", so that
131  * we can use integer arithmetic.
132  *
133  * We travel from start to finish along the longer axis, starting at the border
134  * between the first and second tiles, where the y offset = .5 * slope, taking
135  * into account the scale factor.  See below.
136  *
137  * Also note that this function and the "move towards target" code do NOT
138  * share the same properties.  Thus, you can see someone, target them, and
139  * then fire a bolt at them, but the bolt may hit a wall, not them.  However,
140  * by clever choice of target locations, you can sometimes throw a "curve".
141  *
142  * Note that "line of sight" is not "reflexive" in all cases.
143  *
144  * Use the "projectable()" routine to test "spell/missile line of sight".
145  *
146  * Use the "update_view()" function to determine player line-of-sight.
147  */
148 bool los(int y1, int x1, int y2, int x2)
149 {
150         /* Delta */
151         int dx, dy;
152
153         /* Absolute */
154         int ax, ay;
155
156         /* Signs */
157         int sx, sy;
158
159         /* Fractions */
160         int qx, qy;
161
162         /* Scanners */
163         int tx, ty;
164
165         /* Scale factors */
166         int f1, f2;
167
168         /* Slope, or 1/Slope, of LOS */
169         int m;
170
171
172         /* Extract the offset */
173         dy = y2 - y1;
174         dx = x2 - x1;
175
176         /* Extract the absolute offset */
177         ay = ABS(dy);
178         ax = ABS(dx);
179
180
181         /* Handle adjacent (or identical) grids */
182         if ((ax < 2) && (ay < 2)) return TRUE;
183
184
185         /* Paranoia -- require "safe" origin */
186         /* if (!in_bounds(y1, x1)) return FALSE; */
187         /* if (!in_bounds(y2, x2)) return FALSE; */
188
189
190         /* Directly South/North */
191         if (!dx)
192         {
193                 /* South -- check for walls */
194                 if (dy > 0)
195                 {
196                         for (ty = y1 + 1; ty < y2; ty++)
197                         {
198                                 if (!cave_los_bold(ty, x1)) return FALSE;
199                         }
200                 }
201
202                 /* North -- check for walls */
203                 else
204                 {
205                         for (ty = y1 - 1; ty > y2; ty--)
206                         {
207                                 if (!cave_los_bold(ty, x1)) return FALSE;
208                         }
209                 }
210
211                 /* Assume los */
212                 return TRUE;
213         }
214
215         /* Directly East/West */
216         if (!dy)
217         {
218                 /* East -- check for walls */
219                 if (dx > 0)
220                 {
221                         for (tx = x1 + 1; tx < x2; tx++)
222                         {
223                                 if (!cave_los_bold(y1, tx)) return FALSE;
224                         }
225                 }
226
227                 /* West -- check for walls */
228                 else
229                 {
230                         for (tx = x1 - 1; tx > x2; tx--)
231                         {
232                                 if (!cave_los_bold(y1, tx)) return FALSE;
233                         }
234                 }
235
236                 /* Assume los */
237                 return TRUE;
238         }
239
240
241         /* Extract some signs */
242         sx = (dx < 0) ? -1 : 1;
243         sy = (dy < 0) ? -1 : 1;
244
245
246         /* Vertical "knights" */
247         if (ax == 1)
248         {
249                 if (ay == 2)
250                 {
251                         if (cave_los_bold(y1 + sy, x1)) return TRUE;
252                 }
253         }
254
255         /* Horizontal "knights" */
256         else if (ay == 1)
257         {
258                 if (ax == 2)
259                 {
260                         if (cave_los_bold(y1, x1 + sx)) return TRUE;
261                 }
262         }
263
264
265         /* Calculate scale factor div 2 */
266         f2 = (ax * ay);
267
268         /* Calculate scale factor */
269         f1 = f2 << 1;
270
271
272         /* Travel horizontally */
273         if (ax >= ay)
274         {
275                 /* Let m = dy / dx * 2 * (dy * dx) = 2 * dy * dy */
276                 qy = ay * ay;
277                 m = qy << 1;
278
279                 tx = x1 + sx;
280
281                 /* Consider the special case where slope == 1. */
282                 if (qy == f2)
283                 {
284                         ty = y1 + sy;
285                         qy -= f1;
286                 }
287                 else
288                 {
289                         ty = y1;
290                 }
291
292                 /* Note (below) the case (qy == f2), where */
293                 /* the LOS exactly meets the corner of a tile. */
294                 while (x2 - tx)
295                 {
296                         if (!cave_los_bold(ty, tx)) return FALSE;
297
298                         qy += m;
299
300                         if (qy < f2)
301                         {
302                                 tx += sx;
303                         }
304                         else if (qy > f2)
305                         {
306                                 ty += sy;
307                                 if (!cave_los_bold(ty, tx)) return FALSE;
308                                 qy -= f1;
309                                 tx += sx;
310                         }
311                         else
312                         {
313                                 ty += sy;
314                                 qy -= f1;
315                                 tx += sx;
316                         }
317                 }
318         }
319
320         /* Travel vertically */
321         else
322         {
323                 /* Let m = dx / dy * 2 * (dx * dy) = 2 * dx * dx */
324                 qx = ax * ax;
325                 m = qx << 1;
326
327                 ty = y1 + sy;
328
329                 if (qx == f2)
330                 {
331                         tx = x1 + sx;
332                         qx -= f1;
333                 }
334                 else
335                 {
336                         tx = x1;
337                 }
338
339                 /* Note (below) the case (qx == f2), where */
340                 /* the LOS exactly meets the corner of a tile. */
341                 while (y2 - ty)
342                 {
343                         if (!cave_los_bold(ty, tx)) return FALSE;
344
345                         qx += m;
346
347                         if (qx < f2)
348                         {
349                                 ty += sy;
350                         }
351                         else if (qx > f2)
352                         {
353                                 tx += sx;
354                                 if (!cave_los_bold(ty, tx)) return FALSE;
355                                 qx -= f1;
356                                 ty += sy;
357                         }
358                         else
359                         {
360                                 tx += sx;
361                                 qx -= f1;
362                                 ty += sy;
363                         }
364                 }
365         }
366
367         /* Assume los */
368         return TRUE;
369 }
370
371
372
373
374
375
376 #define COMPLEX_WALL_ILLUMINATION
377
378 /*
379  * Check for "local" illumination
380  */
381 static bool check_local_illumination(int y, int x)
382 {
383         /* Hack -- move towards player */
384         int yy = (y < py) ? (y + 1) : (y > py) ? (y - 1) : y;
385         int xx = (x < px) ? (x + 1) : (x > px) ? (x - 1) : x;
386
387         /* Check for "local" illumination */
388
389 #ifdef COMPLEX_WALL_ILLUMINATION /* COMPLEX_WALL_ILLUMINATION */
390
391         /* Check for "complex" illumination */
392         if ((feat_supports_los(get_feat_mimic(&cave[yy][xx])) &&
393              (cave[yy][xx].info & CAVE_GLOW)) ||
394             (feat_supports_los(get_feat_mimic(&cave[y][xx])) &&
395              (cave[y][xx].info & CAVE_GLOW)) ||
396             (feat_supports_los(get_feat_mimic(&cave[yy][x])) &&
397              (cave[yy][x].info & CAVE_GLOW)))
398         {
399                 return TRUE;
400         }
401         else return FALSE;
402
403 #else /* COMPLEX_WALL_ILLUMINATION */
404
405         /* Check for "simple" illumination */
406         return (cave[yy][xx].info & CAVE_GLOW) ? TRUE : FALSE;
407
408 #endif /* COMPLEX_WALL_ILLUMINATION */
409 }
410
411
412 #define update_local_illumination_aux(Y, X) \
413 { \
414         if (player_has_los_bold((Y), (X))) \
415         { \
416                 /* Update the monster */ \
417                 if (cave[(Y)][(X)].m_idx) update_mon(cave[(Y)][(X)].m_idx, FALSE); \
418 \
419                 /* Notice and redraw */ \
420                 note_spot((Y), (X)); \
421                 lite_spot((Y), (X)); \
422         } \
423 }
424
425
426 /*
427  * Update "local" illumination
428  */
429 void update_local_illumination(int y, int x)
430 {
431         int i, yy, xx;
432
433         if (!in_bounds(y, x)) return;
434
435 #ifdef COMPLEX_WALL_ILLUMINATION /* COMPLEX_WALL_ILLUMINATION */
436
437         if ((y != py) && (x != px))
438         {
439                 yy = (y < py) ? (y - 1) : (y + 1);
440                 xx = (x < px) ? (x - 1) : (x + 1);
441                 update_local_illumination_aux(yy, xx);
442                 update_local_illumination_aux(y, xx);
443                 update_local_illumination_aux(yy, x);
444         }
445         else if (x != px) /* y == py */
446         {
447                 xx = (x < px) ? (x - 1) : (x + 1);
448                 for (i = -1; i <= 1; i++)
449                 {
450                         yy = y + i;
451                         update_local_illumination_aux(yy, xx);
452                 }
453                 yy = y - 1;
454                 update_local_illumination_aux(yy, x);
455                 yy = y + 1;
456                 update_local_illumination_aux(yy, x);
457         }
458         else if (y != py) /* x == px */
459         {
460                 yy = (y < py) ? (y - 1) : (y + 1);
461                 for (i = -1; i <= 1; i++)
462                 {
463                         xx = x + i;
464                         update_local_illumination_aux(yy, xx);
465                 }
466                 xx = x - 1;
467                 update_local_illumination_aux(y, xx);
468                 xx = x + 1;
469                 update_local_illumination_aux(y, xx);
470         }
471         else /* Player's grid */
472         {
473                 for (i = 0; i < 8; i++)
474                 {
475                         yy = y + ddy_cdd[i];
476                         xx = x + ddx_cdd[i];
477                         update_local_illumination_aux(yy, xx);
478                 }
479         }
480
481 #else /* COMPLEX_WALL_ILLUMINATION */
482
483         if ((y != py) && (x != px))
484         {
485                 yy = (y < py) ? (y - 1) : (y + 1);
486                 xx = (x < px) ? (x - 1) : (x + 1);
487                 update_local_illumination_aux(yy, xx);
488         }
489         else if (x != px) /* y == py */
490         {
491                 xx = (x < px) ? (x - 1) : (x + 1);
492                 for (i = -1; i <= 1; i++)
493                 {
494                         yy = y + i;
495                         update_local_illumination_aux(yy, xx);
496                 }
497         }
498         else if (y != py) /* x == px */
499         {
500                 yy = (y < py) ? (y - 1) : (y + 1);
501                 for (i = -1; i <= 1; i++)
502                 {
503                         xx = x + i;
504                         update_local_illumination_aux(yy, xx);
505                 }
506         }
507         else /* Player's grid */
508         {
509                 for (i = 0; i < 8; i++)
510                 {
511                         yy = y + ddy_cdd[i];
512                         xx = x + ddx_cdd[i];
513                         update_local_illumination_aux(yy, xx);
514                 }
515         }
516
517 #endif /* COMPLEX_WALL_ILLUMINATION */
518 }
519
520
521 /*
522  * Can the player "see" the given grid in detail?
523  *
524  * He must have vision, illumination, and line of sight.
525  *
526  * Note -- "CAVE_LITE" is only set if the "torch" has "los()".
527  * So, given "CAVE_LITE", we know that the grid is "fully visible".
528  *
529  * Note that "CAVE_GLOW" makes little sense for a wall, since it would mean
530  * that a wall is visible from any direction.  That would be odd.  Except
531  * under wizard light, which might make sense.  Thus, for walls, we require
532  * not only that they be "CAVE_GLOW", but also, that they be adjacent to a
533  * grid which is not only "CAVE_GLOW", but which is a non-wall, and which is
534  * in line of sight of the player.
535  *
536  * This extra check is expensive, but it provides a more "correct" semantics.
537  *
538  * Note that we should not run this check on walls which are "outer walls" of
539  * the dungeon, or we will induce a memory fault, but actually verifying all
540  * of the locations would be extremely expensive.
541  *
542  * Thus, to speed up the function, we assume that all "perma-walls" which are
543  * "CAVE_GLOW" are "illuminated" from all sides.  This is correct for all cases
544  * except "vaults" and the "buildings" in town.  But the town is a hack anyway,
545  * and the player has more important things on his mind when he is attacking a
546  * monster vault.  It is annoying, but an extremely important optimization.
547  *
548  * Note that "glowing walls" are only considered to be "illuminated" if the
549  * grid which is next to the wall in the direction of the player is also a
550  * "glowing" grid.  This prevents the player from being able to "see" the
551  * walls of illuminated rooms from a corridor outside the room.
552  */
553 bool player_can_see_bold(int y, int x)
554 {
555         cave_type *c_ptr;
556
557         /* Blind players see nothing */
558         if (p_ptr->blind) return FALSE;
559
560         /* Access the cave grid */
561         c_ptr = &cave[y][x];
562
563         /* Note that "torch-lite" yields "illumination" */
564         if (c_ptr->info & (CAVE_LITE | CAVE_MNLT)) return TRUE;
565
566         /* Require line of sight to the grid */
567         if (!player_has_los_bold(y, x)) return FALSE;
568
569         /* Noctovision of Ninja */
570         if (p_ptr->see_nocto) return TRUE;
571
572         /* Require "perma-lite" of the grid */
573         if ((c_ptr->info & (CAVE_GLOW | CAVE_MNDK)) != CAVE_GLOW) return FALSE;
574
575         /* Feature code (applying "mimic" field) */
576         /* Floors are simple */
577         if (feat_supports_los(get_feat_mimic(c_ptr))) return TRUE;
578
579         /* Check for "local" illumination */
580         return check_local_illumination(y, x);
581 }
582
583
584
585 /*
586  * Returns true if the player's grid is dark
587  */
588 bool no_lite(void)
589 {
590         return (!player_can_see_bold(py, px));
591 }
592
593
594
595
596 /*
597  * Determine if a given location may be "destroyed"
598  *
599  * Used by destruction spells, and for placing stairs, etc.
600  */
601 bool cave_valid_bold(int y, int x)
602 {
603         cave_type *c_ptr = &cave[y][x];
604
605         s16b this_o_idx, next_o_idx = 0;
606
607
608         /* Forbid perma-grids */
609         if (cave_perma_grid(c_ptr)) return (FALSE);
610
611         /* Check objects */
612         for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
613         {
614                 object_type *o_ptr;
615
616                 /* Acquire object */
617                 o_ptr = &o_list[this_o_idx];
618
619                 /* Acquire next object */
620                 next_o_idx = o_ptr->next_o_idx;
621
622                 /* Forbid artifact grids */
623                 if (object_is_artifact(o_ptr)) return (FALSE);
624         }
625
626         /* Accept */
627         return (TRUE);
628 }
629
630
631
632
633 /*
634  * Hack -- Legal monster codes
635  */
636 static char image_monster_hack[] = \
637 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
638
639 /*
640  * Hack -- Legal object codes
641  */
642 static char image_object_hack[] = "?/|\\\"!$()_-=[]{},~";
643
644 /*
645  * Mega-Hack -- Hallucinatory monster
646  */
647 static void image_monster(byte *ap, char *cp)
648 {
649         /* Random symbol from set above */
650         if (use_graphics)
651         {
652                 monster_race *r_ptr = &r_info[randint1(max_r_idx - 1)];
653
654                 *cp = r_ptr->x_char;
655                 *ap = r_ptr->x_attr;
656         }
657         else
658         /* Text mode */
659         {
660                 *cp = (one_in_(25) ?
661                        image_object_hack[randint0(sizeof(image_object_hack) - 1)] :
662                        image_monster_hack[randint0(sizeof(image_monster_hack) - 1)]);
663
664                 /* Random color */
665                 *ap = randint1(15);
666         }
667 }
668
669
670 /*
671  * Mega-Hack -- Hallucinatory object
672  */
673 static void image_object(byte *ap, char *cp)
674 {
675         if (use_graphics)
676         {
677                 object_kind *k_ptr = &k_info[randint1(max_k_idx-1)];
678
679                 *cp = k_ptr->x_char;
680                 *ap = k_ptr->x_attr;
681         }
682         else
683         {
684                 int n = sizeof(image_object_hack) - 1;
685
686                 *cp = image_object_hack[randint0(n)];
687
688                 /* Random color */
689                 *ap = randint1(15);
690         }
691 }
692
693
694
695 /*
696  * Hack -- Random hallucination
697  */
698 static void image_random(byte *ap, char *cp)
699 {
700         /* Normally, assume monsters */
701         if (randint0(100) < 75)
702         {
703                 image_monster(ap, cp);
704         }
705
706         /* Otherwise, assume objects */
707         else
708         {
709                 image_object(ap, cp);
710         }
711 }
712
713 /*
714  * This array lists the effects of "brightness" on various "base" colours.
715  *
716  * This is used to do dynamic lighting effects in ascii :-)
717  * At the moment, only the various "floor" tiles are affected.
718  *
719  * The layout of the array is [x][0] = light and [x][1] = dark.
720  */
721
722 static byte lighting_colours[16][2] =
723 {
724         /* TERM_DARK */
725         {TERM_L_DARK, TERM_DARK},
726
727         /* TERM_WHITE */
728         {TERM_YELLOW, TERM_SLATE},
729
730         /* TERM_SLATE */
731         {TERM_WHITE, TERM_L_DARK},
732
733         /* TERM_ORANGE */
734         {TERM_L_UMBER, TERM_UMBER},
735
736         /* TERM_RED */
737         {TERM_RED, TERM_RED},
738
739         /* TERM_GREEN */
740         {TERM_L_GREEN, TERM_GREEN},
741
742         /* TERM_BLUE */
743         {TERM_BLUE, TERM_BLUE},
744
745         /* TERM_UMBER */
746         {TERM_L_UMBER, TERM_RED},
747
748         /* TERM_L_DARK */
749         {TERM_SLATE, TERM_L_DARK},
750
751         /* TERM_L_WHITE */
752         {TERM_WHITE, TERM_SLATE},
753
754         /* TERM_VIOLET */
755         {TERM_L_RED, TERM_BLUE},
756
757         /* TERM_YELLOW */
758         {TERM_YELLOW, TERM_ORANGE},
759
760         /* TERM_L_RED */
761         {TERM_L_RED, TERM_L_RED},
762
763         /* TERM_L_GREEN */
764         {TERM_L_GREEN, TERM_GREEN},
765
766         /* TERM_L_BLUE */
767         {TERM_L_BLUE, TERM_L_BLUE},
768
769         /* TERM_L_UMBER */
770         {TERM_L_UMBER, TERM_UMBER}
771 };
772
773
774 /*
775  * Apply "default" feature lighting effects
776  */
777 void apply_default_feat_lighting(byte f_attr[F_LIT_MAX], byte f_char[F_LIT_MAX])
778 {
779         byte s_attr = f_attr[F_LIT_STANDARD];
780         byte s_char = f_char[F_LIT_STANDARD];
781         int i;
782
783         if (is_ascii_graphics(s_attr)) /* For ASCII */
784         {
785                 f_attr[F_LIT_LITE] = lighting_colours[s_attr & 0x0f][0];
786                 f_attr[F_LIT_DARK] = lighting_colours[s_attr & 0x0f][1];
787                 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++) f_char[i] = s_char;
788         }
789         else /* For tile graphics */
790         {
791                 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++) f_attr[i] = s_attr;
792                 f_char[F_LIT_LITE] = s_char + 2;
793                 f_char[F_LIT_DARK] = s_char + 1;
794         }
795 }
796
797
798 /* Is this grid "darkened" by monster? */
799 #define darkened_grid(C) \
800         ((((C)->info & (CAVE_VIEW | CAVE_LITE | CAVE_MNLT | CAVE_MNDK)) == (CAVE_VIEW | CAVE_MNDK)) && \
801         !p_ptr->see_nocto)
802
803
804 /*
805  * Extract the attr/char to display at the given (legal) map location
806  *
807  * Basically, we "paint" the chosen attr/char in several passes, starting
808  * with any known "terrain features" (defaulting to darkness), then adding
809  * any known "objects", and finally, adding any known "monsters".  This
810  * is not the fastest method but since most of the calls to this function
811  * are made for grids with no monsters or objects, it is fast enough.
812  *
813  * Note that this function, if used on the grid containing the "player",
814  * will return the attr/char of the grid underneath the player, and not
815  * the actual player attr/char itself, allowing a lot of optimization
816  * in various "display" functions.
817  *
818  * Note that the "zero" entry in the feature/object/monster arrays are
819  * used to provide "special" attr/char codes, with "monster zero" being
820  * used for the player attr/char, "object zero" being used for the "stack"
821  * attr/char, and "feature zero" being used for the "nothing" attr/char,
822  * though this function makes use of only "feature zero".
823  *
824  * Note that monsters can have some "special" flags, including "ATTR_MULTI",
825  * which means their color changes, and "ATTR_CLEAR", which means they take
826  * the color of whatever is under them, and "CHAR_CLEAR", which means that
827  * they take the symbol of whatever is under them.  Technically, the flag
828  * "CHAR_MULTI" is supposed to indicate that a monster looks strange when
829  * examined, but this flag is currently ignored.
830  *
831  * Currently, we do nothing with multi-hued objects, because there are
832  * not any.  If there were, they would have to set "shimmer_objects"
833  * when they were created, and then new "shimmer" code in "dungeon.c"
834  * would have to be created handle the "shimmer" effect, and the code
835  * in "cave.c" would have to be updated to create the shimmer effect.
836  *
837  * Note the effects of hallucination.  Objects always appear as random
838  * "objects", monsters as random "monsters", and normal grids occasionally
839  * appear as random "monsters" or "objects", but note that these random
840  * "monsters" and "objects" are really just "colored ascii symbols".
841  *
842  * Note that "floors" and "invisible traps" (and "zero" features) are
843  * drawn as "floors" using a special check for optimization purposes,
844  * and these are the only features which get drawn using the special
845  * lighting effects activated by "view_special_lite".
846  *
847  * Note the use of the "mimic" field in the "terrain feature" processing,
848  * which allows any feature to "pretend" to be another feature.  This is
849  * used to "hide" secret doors, and to make all "doors" appear the same,
850  * and all "walls" appear the same, and "hidden" treasure stay hidden.
851  * It is possible to use this field to make a feature "look" like a floor,
852  * but the "special lighting effects" for floors will not be used.
853  *
854  * Note the use of the new "terrain feature" information.  Note that the
855  * assumption that all interesting "objects" and "terrain features" are
856  * memorized allows extremely optimized processing below.  Note the use
857  * of separate flags on objects to mark them as memorized allows a grid
858  * to have memorized "terrain" without granting knowledge of any object
859  * which may appear in that grid.
860  *
861  * Note the efficient code used to determine if a "floor" grid is
862  * "memorized" or "viewable" by the player, where the test for the
863  * grid being "viewable" is based on the facts that (1) the grid
864  * must be "lit" (torch-lit or perma-lit), (2) the grid must be in
865  * line of sight, and (3) the player must not be blind, and uses the
866  * assumption that all torch-lit grids are in line of sight.
867  *
868  * Note that floors (and invisible traps) are the only grids which are
869  * not memorized when seen, so only these grids need to check to see if
870  * the grid is "viewable" to the player (if it is not memorized).  Since
871  * most non-memorized grids are in fact walls, this induces *massive*
872  * efficiency, at the cost of *forcing* the memorization of non-floor
873  * grids when they are first seen.  Note that "invisible traps" are
874  * always treated exactly like "floors", which prevents "cheating".
875  *
876  * Note the "special lighting effects" which can be activated for floor
877  * grids using the "view_special_lite" option (for "white" floor grids),
878  * causing certain grids to be displayed using special colors.  If the
879  * player is "blind", we will use "dark gray", else if the grid is lit
880  * by the torch, and the "view_yellow_lite" option is set, we will use
881  * "yellow", else if the grid is "dark", we will use "dark gray", else
882  * if the grid is not "viewable", and the "view_bright_lite" option is
883  * set, and the we will use "slate" (gray).  We will use "white" for all
884  * other cases, in particular, for illuminated viewable floor grids.
885  *
886  * Note the "special lighting effects" which can be activated for wall
887  * grids using the "view_granite_lite" option (for "white" wall grids),
888  * causing certain grids to be displayed using special colors.  If the
889  * player is "blind", we will use "dark gray", else if the grid is lit
890  * by the torch, and the "view_yellow_lite" option is set, we will use
891  * "yellow", else if the "view_bright_lite" option is set, and the grid
892  * is not "viewable", or is "dark", or is glowing, but not when viewed
893  * from the player's current location, we will use "slate" (gray).  We
894  * will use "white" for all other cases, in particular, for correctly
895  * illuminated viewable wall grids.
896  *
897  * Note that, when "view_granite_lite" is set, we use an inline version
898  * of the "player_can_see_bold()" function to check the "viewability" of
899  * grids when the "view_bright_lite" option is set, and we do NOT use
900  * any special colors for "dark" wall grids, since this would allow the
901  * player to notice the walls of illuminated rooms from a hallway that
902  * happened to run beside the room.  The alternative, by the way, would
903  * be to prevent the generation of hallways next to rooms, but this
904  * would still allow problems when digging towards a room.
905  *
906  * Note that bizarre things must be done when the "attr" and/or "char"
907  * codes have the "high-bit" set, since these values are used to encode
908  * various "special" pictures in some versions, and certain situations,
909  * such as "multi-hued" or "clear" monsters, cause the attr/char codes
910  * to be "scrambled" in various ways.
911  *
912  * Note that eventually we may use the "&" symbol for embedded treasure,
913  * and use the "*" symbol to indicate multiple objects, though this will
914  * have to wait for Angband 2.8.0 or later.  Note that currently, this
915  * is not important, since only one object or terrain feature is allowed
916  * in each grid.  If needed, "k_info[0]" will hold the "stack" attr/char.
917  *
918  * Note the assumption that doing "x_ptr = &x_info[x]" plus a few of
919  * "x_ptr->xxx", is quicker than "x_info[x].xxx", if this is incorrect
920  * then a whole lot of code should be changed...  XXX XXX
921  */
922 void map_info(int y, int x, byte *ap, char *cp, byte *tap, char *tcp)
923 {
924         /* Get the cave */
925         cave_type *c_ptr = &cave[y][x];
926
927         s16b this_o_idx, next_o_idx = 0;
928
929         /* Feature code (applying "mimic" field) */
930         s16b feat = get_feat_mimic(c_ptr);
931
932         /* Access floor */
933         feature_type *f_ptr = &f_info[feat];
934
935         byte a;
936         byte c;
937
938         /* Boring grids (floors, etc) */
939         if (!have_flag(f_ptr->flags, FF_REMEMBER))
940         {
941                 /*
942                  * Handle Memorized or visible floor
943                  *
944                  * No visual when blinded.
945                  *   (to prevent strange effects on darkness breath)
946                  * otherwise,
947                  * - Can see grids with CAVE_MARK.
948                  * - Can see grids with CAVE_LITE or CAVE_MNLT.
949                  *   (Such grids also have CAVE_VIEW)
950                  * - Can see grids with CAVE_VIEW unless darkened by monsters.
951                  */
952                 if (!p_ptr->blind &&
953                     ((c_ptr->info & (CAVE_MARK | CAVE_LITE | CAVE_MNLT)) ||
954                      ((c_ptr->info & CAVE_VIEW) && (((c_ptr->info & (CAVE_GLOW | CAVE_MNDK)) == CAVE_GLOW) || p_ptr->see_nocto))))
955                 {
956                         /* Normal attr/char */
957                         a = f_ptr->x_attr[F_LIT_STANDARD];
958                         c = f_ptr->x_char[F_LIT_STANDARD];
959
960                         if (p_ptr->wild_mode)
961                         {
962                                 /* Special lighting effects */
963                                 /* Handle "night" */
964                                 if (view_special_lite && !is_daytime())
965                                 {
966                                         /* Use a darkened colour/tile */
967                                         a = f_ptr->x_attr[F_LIT_DARK];
968                                         c = f_ptr->x_char[F_LIT_DARK];
969                                 }
970                         }
971
972                         /* Mega-Hack -- Handle "in-sight" and "darkened" grids */
973                         else if (darkened_grid(c_ptr))
974                         {
975                                 /* Unsafe cave grid -- idea borrowed from Unangband */
976                                 feat = (view_unsafe_grids && (c_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
977
978                                 /* Access darkness */
979                                 f_ptr = &f_info[feat];
980
981                                 /* Char and attr of darkness */
982                                 a = f_ptr->x_attr[F_LIT_STANDARD];
983                                 c = f_ptr->x_char[F_LIT_STANDARD];
984                         }
985
986                         /* Special lighting effects */
987                         else if (view_special_lite)
988                         {
989                                 /* Handle "torch-lit" grids */
990                                 if (c_ptr->info & (CAVE_LITE | CAVE_MNLT))
991                                 {
992                                         /* Torch lite */
993                                         if (view_yellow_lite)
994                                         {
995                                                 /* Use a brightly lit colour/tile */
996                                                 a = f_ptr->x_attr[F_LIT_LITE];
997                                                 c = f_ptr->x_char[F_LIT_LITE];
998                                         }
999                                 }
1000
1001                                 /* Handle "dark" grids */
1002                                 else if ((c_ptr->info & (CAVE_GLOW | CAVE_MNDK)) != CAVE_GLOW)
1003                                 {
1004                                         /* Use a darkened colour/tile */
1005                                         a = f_ptr->x_attr[F_LIT_DARK];
1006                                         c = f_ptr->x_char[F_LIT_DARK];
1007                                 }
1008
1009                                 /* Handle "out-of-sight" grids */
1010                                 else if (!(c_ptr->info & CAVE_VIEW))
1011                                 {
1012                                         /* Special flag */
1013                                         if (view_bright_lite)
1014                                         {
1015                                                 /* Use a darkened colour/tile */
1016                                                 a = f_ptr->x_attr[F_LIT_DARK];
1017                                                 c = f_ptr->x_char[F_LIT_DARK];
1018                                         }
1019                                 }
1020                         }
1021                 }
1022
1023                 /* Unknown */
1024                 else
1025                 {
1026                         /* Unsafe cave grid -- idea borrowed from Unangband */
1027                         feat = (view_unsafe_grids && (c_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
1028
1029                         /* Access darkness */
1030                         f_ptr = &f_info[feat];
1031
1032                         /* Normal attr/char */
1033                         a = f_ptr->x_attr[F_LIT_STANDARD];
1034                         c = f_ptr->x_char[F_LIT_STANDARD];
1035                 }
1036         }
1037
1038         /* Interesting grids (non-floors) */
1039         else
1040         {
1041                 /* Memorized grids */
1042                 if (c_ptr->info & CAVE_MARK)
1043                 {
1044                         /* Normal attr/char */
1045                         a = f_ptr->x_attr[F_LIT_STANDARD];
1046                         c = f_ptr->x_char[F_LIT_STANDARD];
1047
1048                         if (p_ptr->wild_mode)
1049                         {
1050                                 /* Special lighting effects */
1051                                 /* Handle "blind" or "night" */
1052                                 if (view_granite_lite && (p_ptr->blind || !is_daytime()))
1053                                 {
1054                                         /* Use a darkened colour/tile */
1055                                         a = f_ptr->x_attr[F_LIT_DARK];
1056                                         c = f_ptr->x_char[F_LIT_DARK];
1057                                 }
1058                         }
1059
1060                         /* Mega-Hack -- Handle "in-sight" and "darkened" grids */
1061                         else if (darkened_grid(c_ptr) && !p_ptr->blind)
1062                         {
1063                                 if (have_flag(f_ptr->flags, FF_LOS) && have_flag(f_ptr->flags, FF_PROJECT))
1064                                 {
1065                                         /* Unsafe cave grid -- idea borrowed from Unangband */
1066                                         feat = (view_unsafe_grids && (c_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
1067
1068                                         /* Access darkness */
1069                                         f_ptr = &f_info[feat];
1070
1071                                         /* Char and attr of darkness */
1072                                         a = f_ptr->x_attr[F_LIT_STANDARD];
1073                                         c = f_ptr->x_char[F_LIT_STANDARD];
1074                                 }
1075                                 else if (view_granite_lite && view_bright_lite)
1076                                 {
1077                                         /* Use a darkened colour/tile */
1078                                         a = f_ptr->x_attr[F_LIT_DARK];
1079                                         c = f_ptr->x_char[F_LIT_DARK];
1080                                 }
1081                         }
1082
1083                         /* Special lighting effects */
1084                         else if (view_granite_lite)
1085                         {
1086                                 /* Handle "blind" */
1087                                 if (p_ptr->blind)
1088                                 {
1089                                         /* Use a darkened colour/tile */
1090                                         a = f_ptr->x_attr[F_LIT_DARK];
1091                                         c = f_ptr->x_char[F_LIT_DARK];
1092                                 }
1093
1094                                 /* Handle "torch-lit" grids */
1095                                 else if (c_ptr->info & (CAVE_LITE | CAVE_MNLT))
1096                                 {
1097                                         /* Torch lite */
1098                                         if (view_yellow_lite)
1099                                         {
1100                                                 /* Use a brightly lit colour/tile */
1101                                                 a = f_ptr->x_attr[F_LIT_LITE];
1102                                                 c = f_ptr->x_char[F_LIT_LITE];
1103                                         }
1104                                 }
1105
1106                                 /* Handle "view_bright_lite" */
1107                                 else if (view_bright_lite)
1108                                 {
1109                                         /* Not viewable */
1110                                         if (!(c_ptr->info & CAVE_VIEW))
1111                                         {
1112                                                 /* Use a darkened colour/tile */
1113                                                 a = f_ptr->x_attr[F_LIT_DARK];
1114                                                 c = f_ptr->x_char[F_LIT_DARK];
1115                                         }
1116
1117                                         /* Not glowing */
1118                                         else if ((c_ptr->info & (CAVE_GLOW | CAVE_MNDK)) != CAVE_GLOW)
1119                                         {
1120                                                 /* Use a darkened colour/tile */
1121                                                 a = f_ptr->x_attr[F_LIT_DARK];
1122                                                 c = f_ptr->x_char[F_LIT_DARK];
1123                                         }
1124
1125                                         /* Not glowing correctly */
1126                                         else if (!have_flag(f_ptr->flags, FF_LOS) && !check_local_illumination(y, x))
1127                                         {
1128                                                 /* Use a darkened colour/tile */
1129                                                 a = f_ptr->x_attr[F_LIT_DARK];
1130                                                 c = f_ptr->x_char[F_LIT_DARK];
1131                                         }
1132                                 }
1133                         }
1134                 }
1135
1136                 /* Unknown */
1137                 else
1138                 {
1139                         /* Unsafe cave grid -- idea borrowed from Unangband */
1140                         feat = (view_unsafe_grids && (c_ptr->info & CAVE_UNSAFE)) ? feat_undetected : feat_none;
1141
1142                         /* Access feature */
1143                         f_ptr = &f_info[feat];
1144
1145                         /* Normal attr/char */
1146                         a = f_ptr->x_attr[F_LIT_STANDARD];
1147                         c = f_ptr->x_char[F_LIT_STANDARD];
1148                 }
1149         }
1150
1151         if (feat_priority == -1) feat_priority = f_ptr->priority;
1152
1153         /* Save the terrain info for the transparency effects */
1154         (*tap) = a;
1155         (*tcp) = c;
1156
1157         /* Save the info */
1158         (*ap) = a;
1159         (*cp) = c;
1160
1161         /* Hack -- rare random hallucination, except on outer dungeon walls */
1162         if (p_ptr->image)
1163         {
1164                 if (one_in_(256))
1165                 {
1166                         /* Hallucinate */
1167                         image_random(ap, cp);
1168                 }
1169         }
1170
1171         /* Objects */
1172         for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
1173         {
1174                 object_type *o_ptr;
1175
1176                 /* Acquire object */
1177                 o_ptr = &o_list[this_o_idx];
1178
1179                 /* Acquire next object */
1180                 next_o_idx = o_ptr->next_o_idx;
1181
1182                 /* Memorized objects */
1183                 if (o_ptr->marked & OM_FOUND)
1184                 {
1185                         if (display_autopick)
1186                         {
1187                                 byte act;
1188
1189                                 match_autopick = is_autopick(o_ptr);
1190                                 if(match_autopick == -1)
1191                                         continue;
1192
1193                                 act = autopick_list[match_autopick].action;
1194
1195                                 if ((act & DO_DISPLAY) && (act & display_autopick))
1196                                 {
1197                                         autopick_obj = o_ptr;
1198                                 }
1199                                 else
1200                                 {
1201                                         match_autopick = -1;
1202                                         continue;
1203                                 }
1204                         }
1205                         /* Normal char */
1206                         (*cp) = object_char(o_ptr);
1207
1208                         /* Normal attr */
1209                         (*ap) = object_attr(o_ptr);
1210
1211                         feat_priority = 20;
1212
1213                         /* Hack -- hallucination */
1214                         if (p_ptr->image) image_object(ap, cp);
1215
1216                         /* Done */
1217                         break;
1218                 }
1219         }
1220
1221
1222         /* Handle monsters */
1223         if (c_ptr->m_idx && display_autopick == 0 )
1224         {
1225                 monster_type *m_ptr = &m_list[c_ptr->m_idx];
1226
1227                 /* Visible monster */
1228                 if (m_ptr->ml)
1229                 {
1230                         monster_race *r_ptr = &r_info[m_ptr->ap_r_idx];
1231
1232                         feat_priority = 30;
1233
1234                         /* Hallucination */
1235                         if (p_ptr->image)
1236                         {
1237                                 /*
1238                                  * Monsters with both CHAR_CLEAR and ATTR_CLEAR
1239                                  * flags are always unseen.
1240                                  */
1241                                 if ((r_ptr->flags1 & (RF1_CHAR_CLEAR | RF1_ATTR_CLEAR)) == (RF1_CHAR_CLEAR | RF1_ATTR_CLEAR))
1242                                 {
1243                                         /* Do nothing */
1244                                 }
1245                                 else
1246                                 {
1247                                         /* Hallucinatory monster */
1248                                         image_monster(ap, cp);
1249                                 }
1250                         }
1251                         else
1252                         {
1253                                 /* Monster attr/char */
1254                                 a = r_ptr->x_attr;
1255                                 c = r_ptr->x_char;
1256
1257                                 /* Normal monsters */
1258                                 if (!(r_ptr->flags1 & (RF1_CHAR_CLEAR | RF1_SHAPECHANGER | RF1_ATTR_CLEAR
1259                                                            | RF1_ATTR_MULTI | RF1_ATTR_SEMIRAND)))
1260                                 {
1261                                         /* Desired monster attr/char */
1262                                         *ap = a;
1263                                         *cp = c;
1264                                 }
1265
1266                                 /*
1267                                  * Monsters with both CHAR_CLEAR and ATTR_CLEAR
1268                                  * flags are always unseen.
1269                                  */
1270                                 else if ((r_ptr->flags1 & (RF1_CHAR_CLEAR | RF1_ATTR_CLEAR)) == (RF1_CHAR_CLEAR | RF1_ATTR_CLEAR))
1271                                 {
1272                                         /* Do nothing */
1273                                 }
1274
1275                                 else
1276                                 {
1277                                         /***  Monster's attr  ***/
1278                                         if ((r_ptr->flags1 & RF1_ATTR_CLEAR) && (*ap != TERM_DARK) && !use_graphics)
1279                                         {
1280                                                 /* Clear-attr */
1281                                                 /* Do nothing */
1282                                         }
1283                                         else if ((r_ptr->flags1 & RF1_ATTR_MULTI) && !use_graphics)
1284                                         {
1285                                                 /* Multi-hued attr */
1286                                                 if (r_ptr->flags2 & RF2_ATTR_ANY) *ap = randint1(15);
1287                                                 else switch (randint1(7))
1288                                                 {
1289                                                 case 1: *ap = TERM_RED;     break;
1290                                                 case 2: *ap = TERM_L_RED;   break;
1291                                                 case 3: *ap = TERM_WHITE;   break;
1292                                                 case 4: *ap = TERM_L_GREEN; break;
1293                                                 case 5: *ap = TERM_BLUE;    break;
1294                                                 case 6: *ap = TERM_L_DARK;  break;
1295                                                 case 7: *ap = TERM_GREEN;   break;
1296                                                 }
1297                                         }
1298                                         else if ((r_ptr->flags1 & RF1_ATTR_SEMIRAND) && !use_graphics)
1299                                         {
1300                                                 /* Use semi-random attr (usually mimics' colors vary) */
1301                                                 *ap = c_ptr->m_idx % 15 + 1;
1302                                         }
1303                                         else
1304                                         {
1305                                                 /* Normal case */
1306                                                 *ap = a;
1307                                         }
1308
1309                                         /***  Monster's char  ***/
1310                                         if ((r_ptr->flags1 & RF1_CHAR_CLEAR) && (*cp != ' ') && !use_graphics)
1311                                         {
1312                                                 /* Clear-char */
1313                                                 /* Do nothing */
1314                                         }
1315                                         else if (r_ptr->flags1 & RF1_SHAPECHANGER)
1316                                         {
1317                                                 if (use_graphics)
1318                                                 {
1319                                                         monster_race *tmp_r_ptr = &r_info[randint1(max_r_idx - 1)];
1320                                                         *cp = tmp_r_ptr->x_char;
1321                                                         *ap = tmp_r_ptr->x_attr;
1322                                                 }
1323                                                 else
1324                                                 {
1325                                                         *cp = (one_in_(25) ?
1326                                                                image_object_hack[randint0(sizeof(image_object_hack) - 1)] :
1327                                                                image_monster_hack[randint0(sizeof(image_monster_hack) - 1)]);
1328                                                 }
1329                                         }
1330                                         else
1331                                         {
1332                                                 /* Normal case */
1333                                                 *cp = c;
1334                                         }
1335                                 }
1336                         }
1337                 }
1338         }
1339
1340         /* Handle "player" */
1341         if (player_bold(y, x))
1342         {
1343                 monster_race *r_ptr = &r_info[0];
1344
1345                 /* Get the "player" attr */
1346                 *ap = r_ptr->x_attr;
1347
1348                 /* Get the "player" char */
1349                 *cp = r_ptr->x_char;
1350
1351                 feat_priority = 31;
1352         }
1353 }
1354
1355
1356 /*
1357  * Calculate panel colum of a location in the map
1358  */
1359 static int panel_col_of(int col)
1360 {
1361         col -= panel_col_min;
1362         if (use_bigtile) col *= 2;
1363         return col + 13; 
1364 }
1365
1366
1367 /*
1368  * Moves the cursor to a given MAP (y,x) location
1369  */
1370 void move_cursor_relative(int row, int col)
1371 {
1372         /* Real co-ords convert to screen positions */
1373         row -= panel_row_prt;
1374
1375         /* Go there */
1376         Term_gotoxy(panel_col_of(col), row);
1377 }
1378
1379
1380
1381 /*
1382  * Place an attr/char pair at the given map coordinate, if legal.
1383  */
1384 void print_rel(char c, byte a, int y, int x)
1385 {
1386         /* Only do "legal" locations */
1387         if (panel_contains(y, x))
1388         {
1389                 /* Hack -- fake monochrome */
1390                 if (!use_graphics)
1391                 {
1392                         if (world_monster) a = TERM_DARK;
1393                         else if (IS_INVULN() || world_player) a = TERM_WHITE;
1394                         else if (p_ptr->wraith_form) a = TERM_L_DARK;
1395                 }
1396
1397                 /* Draw the char using the attr */
1398                 Term_queue_bigchar(panel_col_of(x), y-panel_row_prt, a, c, 0, 0);
1399         }
1400 }
1401
1402
1403
1404
1405
1406 /*
1407  * Memorize interesting viewable object/features in the given grid
1408  *
1409  * This function should only be called on "legal" grids.
1410  *
1411  * This function will memorize the object and/or feature in the given
1412  * grid, if they are (1) viewable and (2) interesting.  Note that all
1413  * objects are interesting, all terrain features except floors (and
1414  * invisible traps) are interesting, and floors (and invisible traps)
1415  * are interesting sometimes (depending on various options involving
1416  * the illumination of floor grids).
1417  *
1418  * The automatic memorization of all objects and non-floor terrain
1419  * features as soon as they are displayed allows incredible amounts
1420  * of optimization in various places, especially "map_info()".
1421  *
1422  * Note that the memorization of objects is completely separate from
1423  * the memorization of terrain features, preventing annoying floor
1424  * memorization when a detected object is picked up from a dark floor,
1425  * and object memorization when an object is dropped into a floor grid
1426  * which is memorized but out-of-sight.
1427  *
1428  * This function should be called every time the "memorization" of
1429  * a grid (or the object in a grid) is called into question, such
1430  * as when an object is created in a grid, when a terrain feature
1431  * "changes" from "floor" to "non-floor", when any grid becomes
1432  * "illuminated" or "viewable", and when a "floor" grid becomes
1433  * "torch-lit".
1434  *
1435  * Note the relatively efficient use of this function by the various
1436  * "update_view()" and "update_lite()" calls, to allow objects and
1437  * terrain features to be memorized (and drawn) whenever they become
1438  * viewable or illuminated in any way, but not when they "maintain"
1439  * or "lose" their previous viewability or illumination.
1440  *
1441  * Note the butchered "internal" version of "player_can_see_bold()",
1442  * optimized primarily for the most common cases, that is, for the
1443  * non-marked floor grids.
1444  */
1445 void note_spot(int y, int x)
1446 {
1447         cave_type *c_ptr = &cave[y][x];
1448
1449         s16b this_o_idx, next_o_idx = 0;
1450
1451
1452         /* Blind players see nothing */
1453         if (p_ptr->blind) return;
1454
1455         /* Analyze non-torch-lit grids */
1456         if (!(c_ptr->info & (CAVE_LITE | CAVE_MNLT)))
1457         {
1458                 /* Require line of sight to the grid */
1459                 if (!(c_ptr->info & (CAVE_VIEW))) return;
1460
1461                 /* Require "perma-lite" of the grid */
1462                 if ((c_ptr->info & (CAVE_GLOW | CAVE_MNDK)) != CAVE_GLOW)
1463                 {
1464                         /* Not Ninja */
1465                         if (!p_ptr->see_nocto) return;
1466                 }
1467         }
1468
1469
1470         /* Hack -- memorize objects */
1471         for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
1472         {
1473                 object_type *o_ptr = &o_list[this_o_idx];
1474
1475                 /* Acquire next object */
1476                 next_o_idx = o_ptr->next_o_idx;
1477
1478                 /* Memorize objects */
1479                 o_ptr->marked |= OM_FOUND;
1480         }
1481
1482
1483         /* Hack -- memorize grids */
1484         if (!(c_ptr->info & (CAVE_MARK)))
1485         {
1486                 /* Feature code (applying "mimic" field) */
1487                 feature_type *f_ptr = &f_info[get_feat_mimic(c_ptr)];
1488
1489                 /* Memorize some "boring" grids */
1490                 if (!have_flag(f_ptr->flags, FF_REMEMBER))
1491                 {
1492                         /* Option -- memorize all torch-lit floors */
1493                         if (view_torch_grids &&
1494                             ((c_ptr->info & (CAVE_LITE | CAVE_MNLT)) || p_ptr->see_nocto))
1495                         {
1496                                 /* Memorize */
1497                                 c_ptr->info |= (CAVE_MARK);
1498                         }
1499
1500                         /* Option -- memorize all perma-lit floors */
1501                         else if (view_perma_grids && ((c_ptr->info & (CAVE_GLOW | CAVE_MNDK)) == CAVE_GLOW))
1502                         {
1503                                 /* Memorize */
1504                                 c_ptr->info |= (CAVE_MARK);
1505                         }
1506                 }
1507
1508                 /* Memorize normal grids */
1509                 else if (have_flag(f_ptr->flags, FF_LOS))
1510                 {
1511                         /* Memorize */
1512                         c_ptr->info |= (CAVE_MARK);
1513                 }
1514
1515                 /* Memorize torch-lit walls */
1516                 else if (c_ptr->info & (CAVE_LITE | CAVE_MNLT))
1517                 {
1518                         /* Memorize */
1519                         c_ptr->info |= (CAVE_MARK);
1520                 }
1521
1522                 /* Memorize walls seen by noctovision of Ninja */
1523                 else if (p_ptr->see_nocto)
1524                 {
1525                         /* Memorize */
1526                         c_ptr->info |= (CAVE_MARK);
1527                 }
1528
1529                 /* Memorize certain non-torch-lit wall grids */
1530                 else if (check_local_illumination(y, x))
1531                 {
1532                         /* Memorize */
1533                         c_ptr->info |= (CAVE_MARK);
1534                 }
1535         }
1536
1537         /* Memorize terrain of the grid */
1538         c_ptr->info |= (CAVE_KNOWN);
1539 }
1540
1541
1542 void display_dungeon(void)
1543 {
1544         int x, y;
1545         byte a;
1546         char c;
1547
1548         byte ta;
1549         char tc;
1550
1551         for (x = px - Term->wid / 2 + 1; x <= px + Term->wid / 2; x++)
1552         {
1553                 for (y = py - Term->hgt / 2 + 1; y <= py + Term->hgt / 2; y++)
1554                 {
1555                         if (in_bounds2(y, x))
1556                         {
1557
1558                                 /* Examine the grid */
1559                                 map_info(y, x, &a, &c, &ta, &tc);
1560
1561                                 /* Hack -- fake monochrome */
1562                                 if (!use_graphics)
1563                                 {
1564                                         if (world_monster) a = TERM_DARK;
1565                                         else if (IS_INVULN() || world_player) a = TERM_WHITE;
1566                                         else if (p_ptr->wraith_form) a = TERM_L_DARK;
1567                                 }
1568
1569                                 /* Hack -- Queue it */
1570                                 Term_queue_char(x - px + Term->wid / 2 - 1, y - py + Term->hgt / 2 - 1, a, c, ta, tc);
1571                         }
1572                         else
1573                         {
1574                                 /* Clear out-of-bound tiles */
1575
1576                                 /* Access darkness */
1577                                 feature_type *f_ptr = &f_info[feat_none];
1578
1579                                 /* Normal attr */
1580                                 a = f_ptr->x_attr[F_LIT_STANDARD];
1581
1582                                 /* Normal char */
1583                                 c = f_ptr->x_char[F_LIT_STANDARD];
1584
1585                                 /* Hack -- Queue it */
1586                                 Term_queue_char(x - px + Term->wid / 2 - 1, y - py + Term->hgt / 2 - 1, a, c, ta, tc);
1587                         }
1588                 }
1589         }
1590 }
1591
1592
1593 /*
1594  * Redraw (on the screen) a given MAP location
1595  *
1596  * This function should only be called on "legal" grids
1597  */
1598 void lite_spot(int y, int x)
1599 {
1600         /* Redraw if on screen */
1601         if (panel_contains(y, x) && in_bounds2(y, x))
1602         {
1603                 byte a;
1604                 char c;
1605
1606                 byte ta;
1607                 char tc;
1608
1609                 /* Examine the grid */
1610                 map_info(y, x, &a, &c, &ta, &tc);
1611
1612                 /* Hack -- fake monochrome */
1613                 if (!use_graphics)
1614                 {
1615                         if (world_monster) a = TERM_DARK;
1616                         else if (IS_INVULN() || world_player) a = TERM_WHITE;
1617                         else if (p_ptr->wraith_form) a = TERM_L_DARK;
1618                 }
1619
1620                 /* Hack -- Queue it */
1621                 Term_queue_bigchar(panel_col_of(x), y-panel_row_prt, a, c, ta, tc);
1622
1623                 /* Update sub-windows */
1624                 p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
1625         }
1626 }
1627
1628
1629 /*
1630  * Prints the map of the dungeon
1631  *
1632  * Note that, for efficiency, we contain an "optimized" version
1633  * of both "lite_spot()" and "print_rel()", and that we use the
1634  * "lite_spot()" function to display the player grid, if needed.
1635  */
1636 void prt_map(void)
1637 {
1638         int     x, y;
1639         int     v;
1640
1641         /* map bounds */
1642         s16b xmin, xmax, ymin, ymax;
1643
1644         int wid, hgt;
1645
1646         /* Get size */
1647         Term_get_size(&wid, &hgt);
1648
1649         /* Remove map offset */
1650         wid -= COL_MAP + 2;
1651         hgt -= ROW_MAP + 2;
1652
1653         /* Access the cursor state */
1654         (void)Term_get_cursor(&v);
1655
1656         /* Hide the cursor */
1657         (void)Term_set_cursor(0);
1658
1659         /* Get bounds */
1660         xmin = (0 < panel_col_min) ? panel_col_min : 0;
1661         xmax = (cur_wid - 1 > panel_col_max) ? panel_col_max : cur_wid - 1;
1662         ymin = (0 < panel_row_min) ? panel_row_min : 0;
1663         ymax = (cur_hgt - 1 > panel_row_max) ? panel_row_max : cur_hgt - 1;
1664
1665         /* Bottom section of screen */
1666         for (y = 1; y <= ymin - panel_row_prt; y++)
1667         {
1668                 /* Erase the section */
1669                 Term_erase(COL_MAP, y, wid);
1670         }
1671
1672         /* Top section of screen */
1673         for (y = ymax - panel_row_prt; y <= hgt; y++)
1674         {
1675                 /* Erase the section */
1676                 Term_erase(COL_MAP, y, wid);
1677         }
1678
1679         /* Dump the map */
1680         for (y = ymin; y <= ymax; y++)
1681         {
1682                 /* Scan the columns of row "y" */
1683                 for (x = xmin; x <= xmax; x++)
1684                 {
1685                         byte a;
1686                         char c;
1687
1688                         byte ta;
1689                         char tc;
1690
1691                         /* Determine what is there */
1692                         map_info(y, x, &a, &c, &ta, &tc);
1693
1694                         /* Hack -- fake monochrome */
1695                         if (!use_graphics)
1696                         {
1697                                 if (world_monster) a = TERM_DARK;
1698                                 else if (IS_INVULN() || world_player) a = TERM_WHITE;
1699                                 else if (p_ptr->wraith_form) a = TERM_L_DARK;
1700                         }
1701
1702                         /* Efficiency -- Redraw that grid of the map */
1703                         Term_queue_bigchar(panel_col_of(x), y-panel_row_prt, a, c, ta, tc);
1704                 }
1705         }
1706
1707         /* Display player */
1708         lite_spot(py, px);
1709
1710         /* Restore the cursor */
1711         (void)Term_set_cursor(v);
1712 }
1713
1714
1715
1716 /*
1717  * print project path
1718  */
1719 void prt_path(int y, int x)
1720 {
1721         int i;
1722         int path_n;
1723         u16b path_g[512];
1724         int default_color = TERM_SLATE;
1725
1726         if (!display_path) return;
1727         if (-1 == project_length)
1728                 return;
1729
1730         /* Get projection path */
1731         path_n = project_path(path_g, (project_length ? project_length : MAX_RANGE), py, px, y, x, PROJECT_PATH|PROJECT_THRU);
1732
1733         /* Redraw map */
1734         p_ptr->redraw |= (PR_MAP);
1735
1736         /* Redraw stuff */
1737         redraw_stuff();
1738
1739         /* Draw path */
1740         for (i = 0; i < path_n; i++)
1741         {
1742                 int ny = GRID_Y(path_g[i]);
1743                 int nx = GRID_X(path_g[i]);
1744                 cave_type *c_ptr = &cave[ny][nx];
1745
1746                 if (panel_contains(ny, nx))
1747                 {
1748                         byte a = default_color;
1749                         char c;
1750
1751                         byte ta;
1752                         char tc;
1753
1754                         if (c_ptr->m_idx && m_list[c_ptr->m_idx].ml)
1755                         {
1756                                 /* Determine what is there */
1757                                 map_info(ny, nx, &a, &c, &ta, &tc);
1758
1759                                 if (!is_ascii_graphics(a))
1760                                         a = default_color;
1761                                 else if (c == '.' && (a == TERM_WHITE || a == TERM_L_WHITE))
1762                                         a = default_color;
1763                                 else if (a == default_color)
1764                                         a = TERM_WHITE;
1765                         }
1766
1767                         if (!use_graphics)
1768                         {
1769                                 if (world_monster) a = TERM_DARK;
1770                                 else if (IS_INVULN() || world_player) a = TERM_WHITE;
1771                                 else if (p_ptr->wraith_form) a = TERM_L_DARK;
1772                         }
1773
1774                         c = '*';
1775
1776                         /* Hack -- Queue it */
1777                         Term_queue_bigchar(panel_col_of(nx), ny-panel_row_prt, a, c, ta, tc);
1778                 }
1779
1780                 /* Known Wall */
1781                 if ((c_ptr->info & CAVE_MARK) && !cave_have_flag_grid(c_ptr, FF_PROJECT)) break;
1782
1783                 /* Change color */
1784                 if (nx == x && ny == y) default_color = TERM_L_DARK;
1785         }
1786 }
1787
1788
1789 static cptr simplify_list[][2] =
1790 {
1791 #ifdef JP
1792         {"¤ÎËâË¡½ñ", ""},
1793         {NULL, NULL}
1794 #else
1795         {"^Ring of ",   "="},
1796         {"^Amulet of ", "\""},
1797         {"^Scroll of ", "?"},
1798         {"^Scroll titled ", "?"},
1799         {"^Wand of "  , "-"},
1800         {"^Rod of "   , "-"},
1801         {"^Staff of " , "_"},
1802         {"^Potion of ", "!"},
1803         {" Spellbook ",""},
1804         {"^Book of ",   ""},
1805         {" Magic [",   "["},
1806         {" Book [",    "["},
1807         {" Arts [",    "["},
1808         {"^Set of ",    ""},
1809         {"^Pair of ",   ""},
1810         {NULL, NULL}
1811 #endif
1812 };
1813
1814 static void display_shortened_item_name(object_type *o_ptr, int y)
1815 {
1816         char buf[MAX_NLEN];
1817         char *c = buf;
1818         int len = 0;
1819         byte attr;
1820
1821         object_desc(buf, o_ptr, (OD_NO_FLAVOR | OD_OMIT_PREFIX | OD_NAME_ONLY));
1822         attr = tval_to_attr[o_ptr->tval % 128];
1823
1824         if (p_ptr->image)
1825         {
1826                 attr = TERM_WHITE;
1827 #ifdef JP
1828                 strcpy(buf, "²¿¤«´ñ̯¤Êʪ");
1829 #else
1830                 strcpy(buf, "something strange");
1831 #endif
1832         }
1833
1834         for (c = buf; *c; c++)
1835         {
1836                 int i;
1837                 for (i = 0; simplify_list[i][1]; i++)
1838                 {
1839                         cptr org_w = simplify_list[i][0];
1840
1841                         if (*org_w == '^')
1842                         {
1843                                 if (c == buf)
1844                                         org_w++;
1845                                 else
1846                                         continue;
1847                         }
1848
1849                         if (!strncmp(c, org_w, strlen(org_w)))
1850                         {
1851                                 char *s = c;
1852                                 cptr tmp = simplify_list[i][1];
1853                                 while (*tmp)
1854                                         *s++ = *tmp++;
1855                                 tmp = c + strlen(org_w);
1856                                 while (*tmp)
1857                                         *s++ = *tmp++;
1858                                 *s = '\0';
1859                         }
1860                 }
1861         }
1862
1863         c = buf;
1864         len = 0;
1865         /* È¾³Ñ 12 Ê¸»úʬ¤ÇÀÚ¤ë */
1866         while(*c)
1867         {
1868 #ifdef JP
1869                 if(iskanji(*c))
1870                 {
1871                         if(len + 2 > 12) break;
1872                         c+=2;
1873                         len+=2;
1874                 }
1875                 else
1876 #endif
1877                 {
1878                         if(len + 1 > 12) break;
1879                         c++;
1880                         len++;
1881                 }
1882         }
1883         *c='\0';
1884         Term_putstr(0, y, 12, attr, buf);
1885 }
1886
1887 /*
1888  * Display a "small-scale" map of the dungeon in the active Term
1889  */
1890 void display_map(int *cy, int *cx)
1891 {
1892         int i, j, x, y;
1893
1894         byte ta;
1895         char tc;
1896
1897         byte tp;
1898
1899         byte **bigma;
1900         char **bigmc;
1901         byte **bigmp;
1902
1903         byte **ma;
1904         char **mc;
1905         byte **mp;
1906
1907         /* Save lighting effects */
1908         bool old_view_special_lite = view_special_lite;
1909         bool old_view_granite_lite = view_granite_lite;
1910
1911         int hgt, wid, yrat, xrat;
1912
1913         int **match_autopick_yx;
1914         object_type ***object_autopick_yx;
1915
1916         /* Get size */
1917         Term_get_size(&wid, &hgt);
1918         hgt -= 2;
1919         wid -= 14;
1920         if (use_bigtile) wid /= 2;
1921
1922         yrat = (cur_hgt + hgt - 1) / hgt;
1923         xrat = (cur_wid + wid - 1) / wid;
1924
1925         /* Disable lighting effects */
1926         view_special_lite = FALSE;
1927         view_granite_lite = FALSE;
1928
1929         /* Allocate the maps */
1930         C_MAKE(ma, (hgt + 2), byte_ptr);
1931         C_MAKE(mc, (hgt + 2), char_ptr);
1932         C_MAKE(mp, (hgt + 2), byte_ptr);
1933         C_MAKE(match_autopick_yx, (hgt + 2), sint_ptr);
1934         C_MAKE(object_autopick_yx, (hgt + 2), object_type **);
1935
1936         /* Allocate and wipe each line map */
1937         for (y = 0; y < (hgt + 2); y++)
1938         {
1939                 /* Allocate one row each array */
1940                 C_MAKE(ma[y], (wid + 2), byte);
1941                 C_MAKE(mc[y], (wid + 2), char);
1942                 C_MAKE(mp[y], (wid + 2), byte);
1943                 C_MAKE(match_autopick_yx[y], (wid + 2), int);
1944                 C_MAKE(object_autopick_yx[y], (wid + 2), object_type *);
1945
1946                 for (x = 0; x < wid + 2; ++x)
1947                 {
1948                         match_autopick_yx[y][x] = -1;
1949                         object_autopick_yx[y][x] = NULL;
1950
1951                         /* Nothing here */
1952                         ma[y][x] = TERM_WHITE;
1953                         mc[y][x] = ' ';
1954
1955                         /* No priority */
1956                         mp[y][x] = 0;
1957                 }
1958         }
1959
1960         /* Allocate the maps */
1961         C_MAKE(bigma, (cur_hgt + 2), byte_ptr);
1962         C_MAKE(bigmc, (cur_hgt + 2), char_ptr);
1963         C_MAKE(bigmp, (cur_hgt + 2), byte_ptr);
1964
1965         /* Allocate and wipe each line map */
1966         for (y = 0; y < (cur_hgt + 2); y++)
1967         {
1968                 /* Allocate one row each array */
1969                 C_MAKE(bigma[y], (cur_wid + 2), byte);
1970                 C_MAKE(bigmc[y], (cur_wid + 2), char);
1971                 C_MAKE(bigmp[y], (cur_wid + 2), byte);
1972
1973                 for (x = 0; x < cur_wid + 2; ++x)
1974                 {
1975                         /* Nothing here */
1976                         bigma[y][x] = TERM_WHITE;
1977                         bigmc[y][x] = ' ';
1978
1979                         /* No priority */
1980                         bigmp[y][x] = 0;
1981                 }
1982         }
1983
1984         /* Fill in the map */
1985         for (i = 0; i < cur_wid; ++i)
1986         {
1987                 for (j = 0; j < cur_hgt; ++j)
1988                 {
1989                         /* Location */
1990                         x = i / xrat + 1;
1991                         y = j / yrat + 1;
1992
1993                         match_autopick=-1;
1994                         autopick_obj=NULL;
1995                         feat_priority = -1;
1996
1997                         /* Extract the current attr/char at that map location */
1998                         map_info(j, i, &ta, &tc, &ta, &tc);
1999
2000                         /* Extract the priority */
2001                         tp = feat_priority;
2002
2003                         if(match_autopick!=-1
2004                            && (match_autopick_yx[y][x] == -1
2005                                || match_autopick_yx[y][x] > match_autopick))
2006                         {
2007                                 match_autopick_yx[y][x] = match_autopick;
2008                                 object_autopick_yx[y][x] = autopick_obj;
2009                                 tp = 0x7f;
2010                         }
2011
2012                         /* Save the char, attr and priority */
2013                         bigmc[j+1][i+1] = tc;
2014                         bigma[j+1][i+1] = ta;
2015                         bigmp[j+1][i+1] = tp;
2016                 }
2017         }
2018
2019         for (j = 0; j < cur_hgt; ++j)
2020         {
2021                 for (i = 0; i < cur_wid; ++i)
2022                 {
2023                         /* Location */
2024                         x = i / xrat + 1;
2025                         y = j / yrat + 1;
2026
2027                         tc = bigmc[j+1][i+1];
2028                         ta = bigma[j+1][i+1];
2029                         tp = bigmp[j+1][i+1];
2030
2031                         /* rare feature has more priority */
2032                         if (mp[y][x] == tp)
2033                         {
2034                                 int t;
2035                                 int cnt = 0;
2036
2037                                 for (t = 0; t < 8; t++)
2038                                 {
2039                                         if (tc == bigmc[j+1+ddy_cdd[t]][i+1+ddx_cdd[t]] &&
2040                                             ta == bigma[j+1+ddy_cdd[t]][i+1+ddx_cdd[t]])
2041                                                 cnt++;
2042                                 }
2043                                 if (cnt <= 4)
2044                                         tp++;
2045                         }
2046
2047                         /* Save "best" */
2048                         if (mp[y][x] < tp)
2049                         {
2050                                 /* Save the char, attr and priority */
2051                                 mc[y][x] = tc;
2052                                 ma[y][x] = ta;
2053                                 mp[y][x] = tp;
2054                         }
2055                 }
2056         }
2057
2058
2059         /* Corners */
2060         x = wid + 1;
2061         y = hgt + 1;
2062
2063         /* Draw the corners */
2064         mc[0][0] = mc[0][x] = mc[y][0] = mc[y][x] = '+';
2065
2066         /* Draw the horizontal edges */
2067         for (x = 1; x <= wid; x++) mc[0][x] = mc[y][x] = '-';
2068
2069         /* Draw the vertical edges */
2070         for (y = 1; y <= hgt; y++) mc[y][0] = mc[y][x] = '|';
2071
2072
2073         /* Display each map line in order */
2074         for (y = 0; y < hgt + 2; ++y)
2075         {
2076                 /* Start a new line */
2077                 Term_gotoxy(COL_MAP, y);
2078
2079                 /* Display the line */
2080                 for (x = 0; x < wid + 2; ++x)
2081                 {
2082                         ta = ma[y][x];
2083                         tc = mc[y][x];
2084
2085                         /* Hack -- fake monochrome */
2086                         if (!use_graphics)
2087                         {
2088                                 if (world_monster) ta = TERM_DARK;
2089                                 else if (IS_INVULN() || world_player) ta = TERM_WHITE;
2090                                 else if (p_ptr->wraith_form) ta = TERM_L_DARK;
2091                         }
2092
2093                         /* Add the character */
2094                         Term_add_bigch(ta, tc);
2095                 }
2096         }
2097
2098
2099         for (y = 1; y < hgt + 1; ++y)
2100         {
2101           match_autopick = -1;
2102           for (x = 1; x <= wid; x++){
2103             if (match_autopick_yx[y][x] != -1 &&
2104                 (match_autopick > match_autopick_yx[y][x] ||
2105                  match_autopick == -1)){
2106               match_autopick = match_autopick_yx[y][x];
2107               autopick_obj = object_autopick_yx[y][x];
2108             }
2109           }
2110
2111           /* Clear old display */
2112           Term_putstr(0, y, 12, 0, "            ");
2113
2114           if (match_autopick != -1)
2115 #if 1
2116                   display_shortened_item_name(autopick_obj, y);
2117 #else
2118           {
2119                   char buf[13] = "\0";
2120                   strncpy(buf,autopick_list[match_autopick].name,12);
2121                   buf[12] = '\0';
2122                   put_str(buf,y,0); 
2123           }
2124 #endif
2125
2126         }
2127
2128         /* Player location */
2129                 (*cy) = py / yrat + 1 + ROW_MAP;
2130         if (!use_bigtile)
2131                 (*cx) = px / xrat + 1 + COL_MAP;
2132         else
2133                 (*cx) = (px / xrat + 1) * 2 + COL_MAP;
2134
2135         /* Restore lighting effects */
2136         view_special_lite = old_view_special_lite;
2137         view_granite_lite = old_view_granite_lite;
2138
2139         /* Free each line map */
2140         for (y = 0; y < (hgt + 2); y++)
2141         {
2142                 /* Free one row each array */
2143                 C_KILL(ma[y], (wid + 2), byte);
2144                 C_KILL(mc[y], (wid + 2), char);
2145                 C_KILL(mp[y], (wid + 2), byte);
2146                 C_KILL(match_autopick_yx[y], (wid + 2), int);
2147                 C_KILL(object_autopick_yx[y], (wid + 2), object_type *);
2148         }
2149
2150         /* Free each line map */
2151         C_KILL(ma, (hgt + 2), byte_ptr);
2152         C_KILL(mc, (hgt + 2), char_ptr);
2153         C_KILL(mp, (hgt + 2), byte_ptr);
2154         C_KILL(match_autopick_yx, (hgt + 2), sint_ptr);
2155         C_KILL(object_autopick_yx, (hgt + 2), object_type **);
2156
2157         /* Free each line map */
2158         for (y = 0; y < (cur_hgt + 2); y++)
2159         {
2160                 /* Free one row each array */
2161                 C_KILL(bigma[y], (cur_wid + 2), byte);
2162                 C_KILL(bigmc[y], (cur_wid + 2), char);
2163                 C_KILL(bigmp[y], (cur_wid + 2), byte);
2164         }
2165
2166         /* Free each line map */
2167         C_KILL(bigma, (cur_hgt + 2), byte_ptr);
2168         C_KILL(bigmc, (cur_hgt + 2), char_ptr);
2169         C_KILL(bigmp, (cur_hgt + 2), byte_ptr);
2170 }
2171
2172
2173 /*
2174  * Display a "small-scale" map of the dungeon for the player
2175  *
2176  * Currently, the "player" is displayed on the map.  XXX XXX XXX
2177  */
2178 void do_cmd_view_map(void)
2179 {
2180         int cy, cx;
2181
2182
2183         /* Save the screen */
2184         screen_save();
2185
2186         /* Note */
2187 #ifdef JP
2188 prt("¤ªÂÔ¤Á²¼¤µ¤¤...", 0, 0);
2189 #else
2190         prt("Please wait...", 0, 0);
2191 #endif
2192
2193         /* Flush */
2194         Term_fresh();
2195
2196         /* Clear the screen */
2197         Term_clear();
2198
2199         display_autopick = 0;
2200
2201         /* Display the map */
2202         display_map(&cy, &cx);
2203
2204         /* Wait for it */
2205         if(max_autopick && !p_ptr->wild_mode)
2206         {
2207                 display_autopick = ITEM_DISPLAY;
2208
2209                 while (1)
2210                 {
2211                         int i;
2212                         byte flag;
2213
2214                         int wid, hgt, row_message;
2215
2216                         Term_get_size(&wid, &hgt);
2217                         row_message = hgt - 1;
2218
2219 #ifdef JP
2220                         put_str("²¿¤«¥­¡¼¤ò²¡¤·¤Æ¤¯¤À¤µ¤¤('M':½¦¤¦ 'N':ÊüÃÖ 'D':M+N 'K':²õ¤¹¥¢¥¤¥Æ¥à¤òɽ¼¨)", row_message, 1);
2221 #else
2222                         put_str(" Hit M, N(for ~), K(for !), or D(same as M+N) to display auto-picker items.", row_message, 1);
2223 #endif
2224
2225                         /* Hilite the player */
2226                         move_cursor(cy, cx);
2227
2228                         i = inkey();
2229
2230                         if ('M' == i)
2231                                 flag = (DO_AUTOPICK | DO_QUERY_AUTOPICK);
2232                         else if ('N' == i)
2233                                 flag = DONT_AUTOPICK;
2234                         else if ('K' == i)
2235                                 flag = DO_AUTODESTROY;
2236                         else if ('D' == i)
2237                                 flag = (DO_AUTOPICK | DO_QUERY_AUTOPICK | DONT_AUTOPICK);
2238                         else
2239                                 break;
2240
2241                         Term_fresh();
2242                         
2243                         if (~display_autopick & flag)
2244                                 display_autopick |= flag;
2245                         else
2246                                 display_autopick &= ~flag;
2247                         /* Display the map */
2248                         display_map(&cy, &cx);
2249                 }
2250                 
2251                 display_autopick = 0;
2252
2253         }
2254         else
2255         {
2256 #ifdef JP
2257                 put_str("²¿¤«¥­¡¼¤ò²¡¤¹¤È¥²¡¼¥à¤ËÌá¤ê¤Þ¤¹", 23, 30);
2258 #else
2259                 put_str("Hit any key to continue", 23, 30);
2260 #endif          /* Hilite the player */
2261                 move_cursor(cy, cx);
2262                 /* Get any key */
2263                 inkey();
2264         }
2265
2266         /* Restore the screen */
2267         screen_load();
2268 }
2269
2270
2271
2272
2273
2274 /*
2275  * Some comments on the cave grid flags.  -BEN-
2276  *
2277  *
2278  * One of the major bottlenecks in previous versions of Angband was in
2279  * the calculation of "line of sight" from the player to various grids,
2280  * such as monsters.  This was such a nasty bottleneck that a lot of
2281  * silly things were done to reduce the dependancy on "line of sight",
2282  * for example, you could not "see" any grids in a lit room until you
2283  * actually entered the room, and there were all kinds of bizarre grid
2284  * flags to enable this behavior.  This is also why the "call light"
2285  * spells always lit an entire room.
2286  *
2287  * The code below provides functions to calculate the "field of view"
2288  * for the player, which, once calculated, provides extremely fast
2289  * calculation of "line of sight from the player", and to calculate
2290  * the "field of torch lite", which, again, once calculated, provides
2291  * extremely fast calculation of "which grids are lit by the player's
2292  * lite source".  In addition to marking grids as "GRID_VIEW" and/or
2293  * "GRID_LITE", as appropriate, these functions maintain an array for
2294  * each of these two flags, each array containing the locations of all
2295  * of the grids marked with the appropriate flag, which can be used to
2296  * very quickly scan through all of the grids in a given set.
2297  *
2298  * To allow more "semantically valid" field of view semantics, whenever
2299  * the field of view (or the set of torch lit grids) changes, all of the
2300  * grids in the field of view (or the set of torch lit grids) are "drawn"
2301  * so that changes in the world will become apparent as soon as possible.
2302  * This has been optimized so that only grids which actually "change" are
2303  * redrawn, using the "temp" array and the "GRID_TEMP" flag to keep track
2304  * of the grids which are entering or leaving the relevent set of grids.
2305  *
2306  * These new methods are so efficient that the old nasty code was removed.
2307  *
2308  * Note that there is no reason to "update" the "viewable space" unless
2309  * the player "moves", or walls/doors are created/destroyed, and there
2310  * is no reason to "update" the "torch lit grids" unless the field of
2311  * view changes, or the "light radius" changes.  This means that when
2312  * the player is resting, or digging, or doing anything that does not
2313  * involve movement or changing the state of the dungeon, there is no
2314  * need to update the "view" or the "lite" regions, which is nice.
2315  *
2316  * Note that the calls to the nasty "los()" function have been reduced
2317  * to a bare minimum by the use of the new "field of view" calculations.
2318  *
2319  * I wouldn't be surprised if slight modifications to the "update_view()"
2320  * function would allow us to determine "reverse line-of-sight" as well
2321  * as "normal line-of-sight", which would allow monsters to use a more
2322  * "correct" calculation to determine if they can "see" the player.  For
2323  * now, monsters simply "cheat" somewhat and assume that if the player
2324  * has "line of sight" to the monster, then the monster can "pretend"
2325  * that it has "line of sight" to the player.
2326  *
2327  *
2328  * The "update_lite()" function maintains the "CAVE_LITE" flag for each
2329  * grid and maintains an array of all "CAVE_LITE" grids.
2330  *
2331  * This set of grids is the complete set of all grids which are lit by
2332  * the players light source, which allows the "player_can_see_bold()"
2333  * function to work very quickly.
2334  *
2335  * Note that every "CAVE_LITE" grid is also a "CAVE_VIEW" grid, and in
2336  * fact, the player (unless blind) can always "see" all grids which are
2337  * marked as "CAVE_LITE", unless they are "off screen".
2338  *
2339  *
2340  * The "update_view()" function maintains the "CAVE_VIEW" flag for each
2341  * grid and maintains an array of all "CAVE_VIEW" grids.
2342  *
2343  * This set of grids is the complete set of all grids within line of sight
2344  * of the player, allowing the "player_has_los_bold()" macro to work very
2345  * quickly.
2346  *
2347  *
2348  * The current "update_view()" algorithm uses the "CAVE_XTRA" flag as a
2349  * temporary internal flag to mark those grids which are not only in view,
2350  * but which are also "easily" in line of sight of the player.  This flag
2351  * is always cleared when we are done.
2352  *
2353  *
2354  * The current "update_lite()" and "update_view()" algorithms use the
2355  * "CAVE_TEMP" flag, and the array of grids which are marked as "CAVE_TEMP",
2356  * to keep track of which grids were previously marked as "CAVE_LITE" or
2357  * "CAVE_VIEW", which allows us to optimize the "screen updates".
2358  *
2359  * The "CAVE_TEMP" flag, and the array of "CAVE_TEMP" grids, is also used
2360  * for various other purposes, such as spreading lite or darkness during
2361  * "lite_room()" / "unlite_room()", and for calculating monster flow.
2362  *
2363  *
2364  * Any grid can be marked as "CAVE_GLOW" which means that the grid itself is
2365  * in some way permanently lit.  However, for the player to "see" anything
2366  * in the grid, as determined by "player_can_see()", the player must not be
2367  * blind, the grid must be marked as "CAVE_VIEW", and, in addition, "wall"
2368  * grids, even if marked as "perma lit", are only illuminated if they touch
2369  * a grid which is not a wall and is marked both "CAVE_GLOW" and "CAVE_VIEW".
2370  *
2371  *
2372  * To simplify various things, a grid may be marked as "CAVE_MARK", meaning
2373  * that even if the player cannot "see" the grid, he "knows" the terrain in
2374  * that grid.  This is used to "remember" walls/doors/stairs/floors when they
2375  * are "seen" or "detected", and also to "memorize" floors, after "wiz_lite()",
2376  * or when one of the "memorize floor grids" options induces memorization.
2377  *
2378  * Objects are "memorized" in a different way, using a special "marked" flag
2379  * on the object itself, which is set when an object is observed or detected.
2380  *
2381  *
2382  * A grid may be marked as "CAVE_ROOM" which means that it is part of a "room",
2383  * and should be illuminated by "lite room" and "darkness" spells.
2384  *
2385  *
2386  * A grid may be marked as "CAVE_ICKY" which means it is part of a "vault",
2387  * and should be unavailable for "teleportation" destinations.
2388  *
2389  *
2390  * The "view_perma_grids" allows the player to "memorize" every perma-lit grid
2391  * which is observed, and the "view_torch_grids" allows the player to memorize
2392  * every torch-lit grid.  The player will always memorize important walls,
2393  * doors, stairs, and other terrain features, as well as any "detected" grids.
2394  *
2395  * Note that the new "update_view()" method allows, among other things, a room
2396  * to be "partially" seen as the player approaches it, with a growing cone of
2397  * floor appearing as the player gets closer to the door.  Also, by not turning
2398  * on the "memorize perma-lit grids" option, the player will only "see" those
2399  * floor grids which are actually in line of sight.
2400  *
2401  * And my favorite "plus" is that you can now use a special option to draw the
2402  * "floors" in the "viewable region" brightly (actually, to draw the *other*
2403  * grids dimly), providing a "pretty" effect as the player runs around, and
2404  * to efficiently display the "torch lite" in a special color.
2405  *
2406  *
2407  * Some comments on the "update_view()" algorithm...
2408  *
2409  * The algorithm is very fast, since it spreads "obvious" grids very quickly,
2410  * and only has to call "los()" on the borderline cases.  The major axes/diags
2411  * even terminate early when they hit walls.  I need to find a quick way
2412  * to "terminate" the other scans.
2413  *
2414  * Note that in the worst case (a big empty area with say 5% scattered walls),
2415  * each of the 1500 or so nearby grids is checked once, most of them getting
2416  * an "instant" rating, and only a small portion requiring a call to "los()".
2417  *
2418  * The only time that the algorithm appears to be "noticeably" too slow is
2419  * when running, and this is usually only important in town, since the town
2420  * provides about the worst scenario possible, with large open regions and
2421  * a few scattered obstructions.  There is a special "efficiency" option to
2422  * allow the player to reduce his field of view in town, if needed.
2423  *
2424  * In the "best" case (say, a normal stretch of corridor), the algorithm
2425  * makes one check for each viewable grid, and makes no calls to "los()".
2426  * So running in corridors is very fast, and if a lot of monsters are
2427  * nearby, it is much faster than the old methods.
2428  *
2429  * Note that resting, most normal commands, and several forms of running,
2430  * plus all commands executed near large groups of monsters, are strictly
2431  * more efficient with "update_view()" that with the old "compute los() on
2432  * demand" method, primarily because once the "field of view" has been
2433  * calculated, it does not have to be recalculated until the player moves
2434  * (or a wall or door is created or destroyed).
2435  *
2436  * Note that we no longer have to do as many "los()" checks, since once the
2437  * "view" region has been built, very few things cause it to be "changed"
2438  * (player movement, and the opening/closing of doors, changes in wall status).
2439  * Note that door/wall changes are only relevant when the door/wall itself is
2440  * in the "view" region.
2441  *
2442  * The algorithm seems to only call "los()" from zero to ten times, usually
2443  * only when coming down a corridor into a room, or standing in a room, just
2444  * misaligned with a corridor.  So if, say, there are five "nearby" monsters,
2445  * we will be reducing the calls to "los()".
2446  *
2447  * I am thinking in terms of an algorithm that "walks" from the central point
2448  * out to the maximal "distance", at each point, determining the "view" code
2449  * (above).  For each grid not on a major axis or diagonal, the "view" code
2450  * depends on the "cave_los_bold()" and "view" of exactly two other grids
2451  * (the one along the nearest diagonal, and the one next to that one, see
2452  * "update_view_aux()"...).
2453  *
2454  * We "memorize" the viewable space array, so that at the cost of under 3000
2455  * bytes, we reduce the time taken by "forget_view()" to one assignment for
2456  * each grid actually in the "viewable space".  And for another 3000 bytes,
2457  * we prevent "erase + redraw" ineffiencies via the "seen" set.  These bytes
2458  * are also used by other routines, thus reducing the cost to almost nothing.
2459  *
2460  * A similar thing is done for "forget_lite()" in which case the savings are
2461  * much less, but save us from doing bizarre maintenance checking.
2462  *
2463  * In the worst "normal" case (in the middle of the town), the reachable space
2464  * actually reaches to more than half of the largest possible "circle" of view,
2465  * or about 800 grids, and in the worse case (in the middle of a dungeon level
2466  * where all the walls have been removed), the reachable space actually reaches
2467  * the theoretical maximum size of just under 1500 grids.
2468  *
2469  * Each grid G examines the "state" of two (?) other (adjacent) grids, G1 & G2.
2470  * If G1 is lite, G is lite.  Else if G2 is lite, G is half.  Else if G1 and G2
2471  * are both half, G is half.  Else G is dark.  It only takes 2 (or 4) bits to
2472  * "name" a grid, so (for MAX_RAD of 20) we could use 1600 bytes, and scan the
2473  * entire possible space (including initialization) in one step per grid.  If
2474  * we do the "clearing" as a separate step (and use an array of "view" grids),
2475  * then the clearing will take as many steps as grids that were viewed, and the
2476  * algorithm will be able to "stop" scanning at various points.
2477  * Oh, and outside of the "torch radius", only "lite" grids need to be scanned.
2478  */
2479
2480
2481
2482
2483
2484
2485
2486
2487 /*
2488  * Actually erase the entire "lite" array, redrawing every grid
2489  */
2490 void forget_lite(void)
2491 {
2492         int i, x, y;
2493
2494         /* None to forget */
2495         if (!lite_n) return;
2496
2497         /* Clear them all */
2498         for (i = 0; i < lite_n; i++)
2499         {
2500                 y = lite_y[i];
2501                 x = lite_x[i];
2502
2503                 /* Forget "LITE" flag */
2504                 cave[y][x].info &= ~(CAVE_LITE);
2505
2506                 /* Redraw */
2507                 /* lite_spot(y, x); Perhaps don't need? */
2508         }
2509
2510         /* None left */
2511         lite_n = 0;
2512 }
2513
2514
2515 /*
2516  * For delayed visual update
2517  */
2518 #define cave_note_and_redraw_later(C,Y,X) \
2519 {\
2520         (C)->info |= CAVE_NOTE; \
2521         cave_redraw_later((C), (Y), (X)); \
2522 }
2523
2524
2525 /*
2526  * For delayed visual update
2527  */
2528 #define cave_redraw_later(C,Y,X) \
2529 {\
2530         if (!((C)->info & CAVE_REDRAW)) \
2531         { \
2532                 (C)->info |= CAVE_REDRAW; \
2533                 redraw_y[redraw_n] = (Y); \
2534                 redraw_x[redraw_n++] = (X); \
2535         } \
2536 }
2537
2538
2539 /*
2540  * XXX XXX XXX
2541  *
2542  * This macro allows us to efficiently add a grid to the "lite" array,
2543  * note that we are never called for illegal grids, or for grids which
2544  * have already been placed into the "lite" array, and we are never
2545  * called when the "lite" array is full.
2546  */
2547 #define cave_lite_hack(Y,X) \
2548 {\
2549         if (!(cave[Y][X].info & (CAVE_LITE))) \
2550         { \
2551                 cave[Y][X].info |= (CAVE_LITE); \
2552                 lite_y[lite_n] = (Y); \
2553                 lite_x[lite_n++] = (X); \
2554         } \
2555 }
2556
2557
2558 /*
2559  * Update the set of grids "illuminated" by the player's lite.
2560  *
2561  * This routine needs to use the results of "update_view()"
2562  *
2563  * Note that "blindness" does NOT affect "torch lite".  Be careful!
2564  *
2565  * We optimize most lites (all non-artifact lites) by using "obvious"
2566  * facts about the results of "small" lite radius, and we attempt to
2567  * list the "nearby" grids before the more "distant" ones in the
2568  * array of torch-lit grids.
2569  *
2570  * We assume that "radius zero" lite is in fact no lite at all.
2571  *
2572  *     Torch     Lantern     Artifacts
2573  *     (etc)
2574  *                              ***
2575  *                 ***         *****
2576  *      ***       *****       *******
2577  *      *@*       **@**       ***@***
2578  *      ***       *****       *******
2579  *                 ***         *****
2580  *                              ***
2581  */
2582 void update_lite(void)
2583 {
2584         int i, x, y, min_x, max_x, min_y, max_y;
2585         int p = p_ptr->cur_lite;
2586         cave_type *c_ptr;
2587
2588         /*** Special case ***/
2589
2590 #if 0
2591         /* Hack -- Player has no lite */
2592         if (p <= 0)
2593         {
2594                 /* Forget the old lite */
2595                 /* forget_lite(); Perhaps don't need? */
2596
2597                 /* Add it to later visual update */
2598                 cave_redraw_later(&cave[py][px], py, px);
2599         }
2600 #endif
2601
2602         /*** Save the old "lite" grids for later ***/
2603
2604         /* Clear them all */
2605         for (i = 0; i < lite_n; i++)
2606         {
2607                 y = lite_y[i];
2608                 x = lite_x[i];
2609
2610                 /* Mark the grid as not "lite" */
2611                 cave[y][x].info &= ~(CAVE_LITE);
2612
2613                 /* Mark the grid as "seen" */
2614                 cave[y][x].info |= (CAVE_TEMP);
2615
2616                 /* Add it to the "seen" set */
2617                 temp_y[temp_n] = y;
2618                 temp_x[temp_n] = x;
2619                 temp_n++;
2620         }
2621
2622         /* None left */
2623         lite_n = 0;
2624
2625
2626         /*** Collect the new "lite" grids ***/
2627
2628         /* Radius 1 -- torch radius */
2629         if (p >= 1)
2630         {
2631                 /* Player grid */
2632                 cave_lite_hack(py, px);
2633
2634                 /* Adjacent grid */
2635                 cave_lite_hack(py+1, px);
2636                 cave_lite_hack(py-1, px);
2637                 cave_lite_hack(py, px+1);
2638                 cave_lite_hack(py, px-1);
2639
2640                 /* Diagonal grids */
2641                 cave_lite_hack(py+1, px+1);
2642                 cave_lite_hack(py+1, px-1);
2643                 cave_lite_hack(py-1, px+1);
2644                 cave_lite_hack(py-1, px-1);
2645         }
2646
2647         /* Radius 2 -- lantern radius */
2648         if (p >= 2)
2649         {
2650                 /* South of the player */
2651                 if (cave_los_bold(py + 1, px))
2652                 {
2653                         cave_lite_hack(py+2, px);
2654                         cave_lite_hack(py+2, px+1);
2655                         cave_lite_hack(py+2, px-1);
2656                 }
2657
2658                 /* North of the player */
2659                 if (cave_los_bold(py - 1, px))
2660                 {
2661                         cave_lite_hack(py-2, px);
2662                         cave_lite_hack(py-2, px+1);
2663                         cave_lite_hack(py-2, px-1);
2664                 }
2665
2666                 /* East of the player */
2667                 if (cave_los_bold(py, px + 1))
2668                 {
2669                         cave_lite_hack(py, px+2);
2670                         cave_lite_hack(py+1, px+2);
2671                         cave_lite_hack(py-1, px+2);
2672                 }
2673
2674                 /* West of the player */
2675                 if (cave_los_bold(py, px - 1))
2676                 {
2677                         cave_lite_hack(py, px-2);
2678                         cave_lite_hack(py+1, px-2);
2679                         cave_lite_hack(py-1, px-2);
2680                 }
2681         }
2682
2683         /* Radius 3+ -- artifact radius */
2684         if (p >= 3)
2685         {
2686                 int d;
2687
2688                 /* Paranoia -- see "LITE_MAX" */
2689                 if (p > 14) p = 14;
2690
2691                 /* South-East of the player */
2692                 if (cave_los_bold(py + 1, px + 1))
2693                 {
2694                         cave_lite_hack(py+2, px+2);
2695                 }
2696
2697                 /* South-West of the player */
2698                 if (cave_los_bold(py + 1, px - 1))
2699                 {
2700                         cave_lite_hack(py+2, px-2);
2701                 }
2702
2703                 /* North-East of the player */
2704                 if (cave_los_bold(py - 1, px + 1))
2705                 {
2706                         cave_lite_hack(py-2, px+2);
2707                 }
2708
2709                 /* North-West of the player */
2710                 if (cave_los_bold(py - 1, px - 1))
2711                 {
2712                         cave_lite_hack(py-2, px-2);
2713                 }
2714
2715                 /* Maximal north */
2716                 min_y = py - p;
2717                 if (min_y < 0) min_y = 0;
2718
2719                 /* Maximal south */
2720                 max_y = py + p;
2721                 if (max_y > cur_hgt-1) max_y = cur_hgt-1;
2722
2723                 /* Maximal west */
2724                 min_x = px - p;
2725                 if (min_x < 0) min_x = 0;
2726
2727                 /* Maximal east */
2728                 max_x = px + p;
2729                 if (max_x > cur_wid-1) max_x = cur_wid-1;
2730
2731                 /* Scan the maximal box */
2732                 for (y = min_y; y <= max_y; y++)
2733                 {
2734                         for (x = min_x; x <= max_x; x++)
2735                         {
2736                                 int dy = (py > y) ? (py - y) : (y - py);
2737                                 int dx = (px > x) ? (px - x) : (x - px);
2738
2739                                 /* Skip the "central" grids (above) */
2740                                 if ((dy <= 2) && (dx <= 2)) continue;
2741
2742                                 /* Hack -- approximate the distance */
2743                                 d = (dy > dx) ? (dy + (dx>>1)) : (dx + (dy>>1));
2744
2745                                 /* Skip distant grids */
2746                                 if (d > p) continue;
2747
2748                                 /* Viewable, nearby, grids get "torch lit" */
2749                                 if (cave[y][x].info & CAVE_VIEW)
2750                                 {
2751                                         /* This grid is "torch lit" */
2752                                         cave_lite_hack(y, x);
2753                                 }
2754                         }
2755                 }
2756         }
2757
2758
2759         /*** Complete the algorithm ***/
2760
2761         /* Draw the new grids */
2762         for (i = 0; i < lite_n; i++)
2763         {
2764                 y = lite_y[i];
2765                 x = lite_x[i];
2766
2767                 c_ptr = &cave[y][x];
2768
2769                 /* Update fresh grids */
2770                 if (c_ptr->info & (CAVE_TEMP)) continue;
2771
2772                 /* Add it to later visual update */
2773                 cave_note_and_redraw_later(c_ptr, y, x);
2774         }
2775
2776         /* Clear them all */
2777         for (i = 0; i < temp_n; i++)
2778         {
2779                 y = temp_y[i];
2780                 x = temp_x[i];
2781
2782                 c_ptr = &cave[y][x];
2783
2784                 /* No longer in the array */
2785                 c_ptr->info &= ~(CAVE_TEMP);
2786
2787                 /* Update stale grids */
2788                 if (c_ptr->info & (CAVE_LITE)) continue;
2789
2790                 /* Add it to later visual update */
2791                 cave_redraw_later(c_ptr, y, x);
2792         }
2793
2794         /* None left */
2795         temp_n = 0;
2796
2797         /* Mega-Hack -- Visual update later */
2798         p_ptr->update |= (PU_DELAY_VIS);
2799 }
2800
2801
2802 static bool mon_invis;
2803 static s16b mon_fy, mon_fx;
2804
2805 /*
2806  * Add a square to the changes array
2807  */
2808 static void mon_lite_hack(int y, int x)
2809 {
2810         cave_type *c_ptr;
2811         int       midpoint, dpf, d;
2812
2813         /* We trust this grid is in bounds */
2814         /* if (!in_bounds2(y, x)) return; */
2815
2816         c_ptr = &cave[y][x];
2817
2818         /* Want a unlit square in view of the player */
2819         if ((c_ptr->info & (CAVE_MNLT | CAVE_VIEW)) != CAVE_VIEW) return;
2820
2821         if (!cave_los_grid(c_ptr))
2822         {
2823                 /* Hack -- Prevent monster lite leakage in walls */
2824
2825                 /* Horizontal walls between player and a monster */
2826                 if (((y < py) && (y > mon_fy)) || ((y > py) && (y < mon_fy)))
2827                 {
2828                         dpf = py - mon_fy;
2829                         d = y - mon_fy;
2830                         midpoint = mon_fx + ((px - mon_fx) * ABS(d)) / ABS(dpf);
2831
2832                         /* Only first wall viewed from mid-x is lit */
2833                         if (x < midpoint)
2834                         {
2835                                 if (!cave_los_bold(y, x + 1)) return;
2836                         }
2837                         else if (x > midpoint)
2838                         {
2839                                 if (!cave_los_bold(y, x - 1)) return;
2840                         }
2841
2842                         /* Hack XXX XXX - Is it a wall and monster not in LOS? */
2843                         else if (mon_invis) return;
2844                 }
2845
2846                 /* Vertical walls between player and a monster */
2847                 if (((x < px) && (x > mon_fx)) || ((x > px) && (x < mon_fx)))
2848                 {
2849                         dpf = px - mon_fx;
2850                         d = x - mon_fx;
2851                         midpoint = mon_fy + ((py - mon_fy) * ABS(d)) / ABS(dpf);
2852
2853                         /* Only first wall viewed from mid-y is lit */
2854                         if (y < midpoint)
2855                         {
2856                                 if (!cave_los_bold(y + 1, x)) return;
2857                         }
2858                         else if (y > midpoint)
2859                         {
2860                                 if (!cave_los_bold(y - 1, x)) return;
2861                         }
2862
2863                         /* Hack XXX XXX - Is it a wall and monster not in LOS? */
2864                         else if (mon_invis) return;
2865                 }
2866         }
2867
2868         /* We trust temp_n does not exceed TEMP_MAX */
2869
2870         /* New grid */
2871         if (!(c_ptr->info & CAVE_MNDK))
2872         {
2873                 /* Save this square */
2874                 temp_x[temp_n] = x;
2875                 temp_y[temp_n] = y;
2876                 temp_n++;
2877         }
2878
2879         /* Darkened grid */
2880         else
2881         {
2882                 /* No longer dark */
2883                 c_ptr->info &= ~(CAVE_MNDK);
2884         }
2885
2886         /* Light it */
2887         c_ptr->info |= CAVE_MNLT;
2888 }
2889
2890
2891 /*
2892  * Add a square to the changes array
2893  */
2894 static void mon_dark_hack(int y, int x)
2895 {
2896         cave_type *c_ptr;
2897         int       midpoint, dpf, d;
2898
2899         /* We trust this grid is in bounds */
2900         /* if (!in_bounds2(y, x)) return; */
2901
2902         c_ptr = &cave[y][x];
2903
2904         /* Want a unlit and undarkened square in view of the player */
2905         if ((c_ptr->info & (CAVE_LITE | CAVE_MNLT | CAVE_MNDK | CAVE_VIEW)) != CAVE_VIEW) return;
2906
2907         if (!cave_los_grid(c_ptr) && !cave_have_flag_grid(c_ptr, FF_PROJECT))
2908         {
2909                 /* Hack -- Prevent monster dark lite leakage in walls */
2910
2911                 /* Horizontal walls between player and a monster */
2912                 if (((y < py) && (y > mon_fy)) || ((y > py) && (y < mon_fy)))
2913                 {
2914                         dpf = py - mon_fy;
2915                         d = y - mon_fy;
2916                         midpoint = mon_fx + ((px - mon_fx) * ABS(d)) / ABS(dpf);
2917
2918                         /* Only first wall viewed from mid-x is lit */
2919                         if (x < midpoint)
2920                         {
2921                                 if (!cave_los_bold(y, x + 1) && !cave_have_flag_bold(y, x + 1, FF_PROJECT)) return;
2922                         }
2923                         else if (x > midpoint)
2924                         {
2925                                 if (!cave_los_bold(y, x - 1) && !cave_have_flag_bold(y, x - 1, FF_PROJECT)) return;
2926                         }
2927
2928                         /* Hack XXX XXX - Is it a wall and monster not in LOS? */
2929                         else if (mon_invis) return;
2930                 }
2931
2932                 /* Vertical walls between player and a monster */
2933                 if (((x < px) && (x > mon_fx)) || ((x > px) && (x < mon_fx)))
2934                 {
2935                         dpf = px - mon_fx;
2936                         d = x - mon_fx;
2937                         midpoint = mon_fy + ((py - mon_fy) * ABS(d)) / ABS(dpf);
2938
2939                         /* Only first wall viewed from mid-y is lit */
2940                         if (y < midpoint)
2941                         {
2942                                 if (!cave_los_bold(y + 1, x) && !cave_have_flag_bold(y + 1, x, FF_PROJECT)) return;
2943                         }
2944                         else if (y > midpoint)
2945                         {
2946                                 if (!cave_los_bold(y - 1, x) && !cave_have_flag_bold(y - 1, x, FF_PROJECT)) return;
2947                         }
2948
2949                         /* Hack XXX XXX - Is it a wall and monster not in LOS? */
2950                         else if (mon_invis) return;
2951                 }
2952         }
2953
2954         /* We trust temp_n does not exceed TEMP_MAX */
2955
2956         /* Save this square */
2957         temp_x[temp_n] = x;
2958         temp_y[temp_n] = y;
2959         temp_n++;
2960
2961         /* Darken it */
2962         c_ptr->info |= CAVE_MNDK;
2963 }
2964
2965
2966 /*
2967  * Update squares illuminated or darkened by monsters.
2968  *
2969  * Hack - use the CAVE_ROOM flag (renamed to be CAVE_MNLT) to
2970  * denote squares illuminated by monsters.
2971  *
2972  * The CAVE_TEMP and CAVE_XTRA flag are used to store the state during the
2973  * updating.  Only squares in view of the player, whos state
2974  * changes are drawn via lite_spot().
2975  */
2976 void update_mon_lite(void)
2977 {
2978         int i, rad;
2979         cave_type *c_ptr;
2980
2981         s16b fx, fy;
2982         void (*add_mon_lite)(int, int);
2983         int f_flag;
2984
2985         s16b end_temp;
2986
2987         /* Non-Ninja player in the darkness */
2988         int dis_lim = ((d_info[dungeon_type].flags1 & DF1_DARKNESS) && !p_ptr->see_nocto) ?
2989                 (MAX_SIGHT / 2 + 1) : (MAX_SIGHT + 3);
2990
2991         /* Clear all monster lit squares */
2992         for (i = 0; i < mon_lite_n; i++)
2993         {
2994                 /* Point to grid */
2995                 c_ptr = &cave[mon_lite_y[i]][mon_lite_x[i]];
2996
2997                 /* Set temp or xtra flag */
2998                 c_ptr->info |= (c_ptr->info & CAVE_MNLT) ? CAVE_TEMP : CAVE_XTRA;
2999
3000                 /* Clear monster illumination flag */
3001                 c_ptr->info &= ~(CAVE_MNLT | CAVE_MNDK);
3002         }
3003
3004         /* Empty temp list of new squares to lite up */
3005         temp_n = 0;
3006
3007         /* If a monster stops time, don't process */
3008         if (!world_monster)
3009         {
3010                 monster_type *m_ptr;
3011                 monster_race *r_ptr;
3012
3013                 /* Loop through monsters, adding newly lit squares to changes list */
3014                 for (i = 1; i < m_max; i++)
3015                 {
3016                         m_ptr = &m_list[i];
3017                         r_ptr = &r_info[m_ptr->r_idx];
3018
3019                         /* Skip dead monsters */
3020                         if (!m_ptr->r_idx) continue;
3021
3022                         /* Is it too far away? */
3023                         if (m_ptr->cdis > dis_lim) continue;
3024
3025                         /* Get lite radius */
3026                         rad = 0;
3027
3028                         /* Note the radii are cumulative */
3029                         if (r_ptr->flags7 & (RF7_HAS_LITE_1 | RF7_SELF_LITE_1)) rad++;
3030                         if (r_ptr->flags7 & (RF7_HAS_LITE_2 | RF7_SELF_LITE_2)) rad += 2;
3031                         if (r_ptr->flags7 & (RF7_HAS_DARK_1 | RF7_SELF_DARK_1)) rad--;
3032                         if (r_ptr->flags7 & (RF7_HAS_DARK_2 | RF7_SELF_DARK_2)) rad -= 2;
3033
3034                         /* Exit if has no light */
3035                         if (!rad) continue;
3036                         else if (rad > 0)
3037                         {
3038                                 if (!(r_ptr->flags7 & (RF7_SELF_LITE_1 | RF7_SELF_LITE_2)) && (MON_CSLEEP(m_ptr) || (!dun_level && is_daytime()) || p_ptr->inside_battle)) continue;
3039                                 if (d_info[dungeon_type].flags1 & DF1_DARKNESS) rad = 1;
3040                                 add_mon_lite = mon_lite_hack;
3041                                 f_flag = FF_LOS;
3042                         }
3043                         else
3044                         {
3045                                 if (!(r_ptr->flags7 & (RF7_SELF_DARK_1 | RF7_SELF_DARK_2)) && (MON_CSLEEP(m_ptr) || (!dun_level && !is_daytime()))) continue;
3046                                 add_mon_lite = mon_dark_hack;
3047                                 f_flag = FF_PROJECT;
3048                                 rad = -rad; /* Use absolute value */
3049                         }
3050
3051                         /* Access the location */
3052                         mon_fx = m_ptr->fx;
3053                         mon_fy = m_ptr->fy;
3054
3055                         /* Is the monster visible? */
3056                         mon_invis = !(cave[mon_fy][mon_fx].info & CAVE_VIEW);
3057
3058                         /* The square it is on */
3059                         add_mon_lite(mon_fy, mon_fx);
3060
3061                         /* Adjacent squares */
3062                         add_mon_lite(mon_fy + 1, mon_fx);
3063                         add_mon_lite(mon_fy - 1, mon_fx);
3064                         add_mon_lite(mon_fy, mon_fx + 1);
3065                         add_mon_lite(mon_fy, mon_fx - 1);
3066                         add_mon_lite(mon_fy + 1, mon_fx + 1);
3067                         add_mon_lite(mon_fy + 1, mon_fx - 1);
3068                         add_mon_lite(mon_fy - 1, mon_fx + 1);
3069                         add_mon_lite(mon_fy - 1, mon_fx - 1);
3070
3071                         /* Radius 2 */
3072                         if (rad >= 2)
3073                         {
3074                                 /* South of the monster */
3075                                 if (cave_have_flag_bold(mon_fy + 1, mon_fx, f_flag))
3076                                 {
3077                                         add_mon_lite(mon_fy + 2, mon_fx + 1);
3078                                         add_mon_lite(mon_fy + 2, mon_fx);
3079                                         add_mon_lite(mon_fy + 2, mon_fx - 1);
3080
3081                                         c_ptr = &cave[mon_fy + 2][mon_fx];
3082
3083                                         /* Radius 3 */
3084                                         if ((rad == 3) && cave_have_flag_grid(c_ptr, f_flag))
3085                                         {
3086                                                 add_mon_lite(mon_fy + 3, mon_fx + 1);
3087                                                 add_mon_lite(mon_fy + 3, mon_fx);
3088                                                 add_mon_lite(mon_fy + 3, mon_fx - 1);
3089                                         }
3090                                 }
3091
3092                                 /* North of the monster */
3093                                 if (cave_have_flag_bold(mon_fy - 1, mon_fx, f_flag))
3094                                 {
3095                                         add_mon_lite(mon_fy - 2, mon_fx + 1);
3096                                         add_mon_lite(mon_fy - 2, mon_fx);
3097                                         add_mon_lite(mon_fy - 2, mon_fx - 1);
3098
3099                                         c_ptr = &cave[mon_fy - 2][mon_fx];
3100
3101                                         /* Radius 3 */
3102                                         if ((rad == 3) && cave_have_flag_grid(c_ptr, f_flag))
3103                                         {
3104                                                 add_mon_lite(mon_fy - 3, mon_fx + 1);
3105                                                 add_mon_lite(mon_fy - 3, mon_fx);
3106                                                 add_mon_lite(mon_fy - 3, mon_fx - 1);
3107                                         }
3108                                 }
3109
3110                                 /* East of the monster */
3111                                 if (cave_have_flag_bold(mon_fy, mon_fx + 1, f_flag))
3112                                 {
3113                                         add_mon_lite(mon_fy + 1, mon_fx + 2);
3114                                         add_mon_lite(mon_fy, mon_fx + 2);
3115                                         add_mon_lite(mon_fy - 1, mon_fx + 2);
3116
3117                                         c_ptr = &cave[mon_fy][mon_fx + 2];
3118
3119                                         /* Radius 3 */
3120                                         if ((rad == 3) && cave_have_flag_grid(c_ptr, f_flag))
3121                                         {
3122                                                 add_mon_lite(mon_fy + 1, mon_fx + 3);
3123                                                 add_mon_lite(mon_fy, mon_fx + 3);
3124                                                 add_mon_lite(mon_fy - 1, mon_fx + 3);
3125                                         }
3126                                 }
3127
3128                                 /* West of the monster */
3129                                 if (cave_have_flag_bold(mon_fy, mon_fx - 1, f_flag))
3130                                 {
3131                                         add_mon_lite(mon_fy + 1, mon_fx - 2);
3132                                         add_mon_lite(mon_fy, mon_fx - 2);
3133                                         add_mon_lite(mon_fy - 1, mon_fx - 2);
3134
3135                                         c_ptr = &cave[mon_fy][mon_fx - 2];
3136
3137                                         /* Radius 3 */
3138                                         if ((rad == 3) && cave_have_flag_grid(c_ptr, f_flag))
3139                                         {
3140                                                 add_mon_lite(mon_fy + 1, mon_fx - 3);
3141                                                 add_mon_lite(mon_fy, mon_fx - 3);
3142                                                 add_mon_lite(mon_fy - 1, mon_fx - 3);
3143                                         }
3144                                 }
3145                         }
3146
3147                         /* Radius 3 */
3148                         if (rad == 3)
3149                         {
3150                                 /* South-East of the monster */
3151                                 if (cave_have_flag_bold(mon_fy + 1, mon_fx + 1, f_flag))
3152                                 {
3153                                         add_mon_lite(mon_fy + 2, mon_fx + 2);
3154                                 }
3155
3156                                 /* South-West of the monster */
3157                                 if (cave_have_flag_bold(mon_fy + 1, mon_fx - 1, f_flag))
3158                                 {
3159                                         add_mon_lite(mon_fy + 2, mon_fx - 2);
3160                                 }
3161
3162                                 /* North-East of the monster */
3163                                 if (cave_have_flag_bold(mon_fy - 1, mon_fx + 1, f_flag))
3164                                 {
3165                                         add_mon_lite(mon_fy - 2, mon_fx + 2);
3166                                 }
3167
3168                                 /* North-West of the monster */
3169                                 if (cave_have_flag_bold(mon_fy - 1, mon_fx - 1, f_flag))
3170                                 {
3171                                         add_mon_lite(mon_fy - 2, mon_fx - 2);
3172                                 }
3173                         }
3174                 }
3175         }
3176
3177         /* Save end of list of new squares */
3178         end_temp = temp_n;
3179
3180         /*
3181          * Look at old set flags to see if there are any changes.
3182          */
3183         for (i = 0; i < mon_lite_n; i++)
3184         {
3185                 fx = mon_lite_x[i];
3186                 fy = mon_lite_y[i];
3187
3188                 /* We trust this grid is in bounds */
3189
3190                 /* Point to grid */
3191                 c_ptr = &cave[fy][fx];
3192
3193                 if (c_ptr->info & CAVE_TEMP) /* Pervious lit */
3194                 {
3195                         /* It it no longer lit? */
3196                         if ((c_ptr->info & (CAVE_VIEW | CAVE_MNLT)) == CAVE_VIEW)
3197                         {
3198                                 /* It is now unlit */
3199                                 /* Add it to later visual update */
3200                                 cave_note_and_redraw_later(c_ptr, fy, fx);
3201                         }
3202                 }
3203                 else /* Pervious darkened */
3204                 {
3205                         /* It it no longer darken? */
3206                         if ((c_ptr->info & (CAVE_VIEW | CAVE_MNDK)) == CAVE_VIEW)
3207                         {
3208                                 /* It is now undarken */
3209                                 /* Add it to later visual update */
3210                                 cave_note_and_redraw_later(c_ptr, fy, fx);
3211                         }
3212                 }
3213
3214                 /* Add to end of temp array */
3215                 temp_x[temp_n] = (byte)fx;
3216                 temp_y[temp_n] = (byte)fy;
3217                 temp_n++;
3218         }
3219
3220         /* Clear the lite array */
3221         mon_lite_n = 0;
3222
3223         /* Copy the temp array into the lit array lighting the new squares. */
3224         for (i = 0; i < end_temp; i++)
3225         {
3226                 fx = temp_x[i];
3227                 fy = temp_y[i];
3228
3229                 /* We trust this grid is in bounds */
3230
3231                 /* Point to grid */
3232                 c_ptr = &cave[fy][fx];
3233
3234                 if (c_ptr->info & CAVE_MNLT) /* Lit */
3235                 {
3236                         /* The is the square newly lit and visible? */
3237                         if ((c_ptr->info & (CAVE_VIEW | CAVE_TEMP)) == CAVE_VIEW)
3238                         {
3239                                 /* It is now lit */
3240                                 /* Add it to later visual update */
3241                                 cave_note_and_redraw_later(c_ptr, fy, fx);
3242                         }
3243                 }
3244                 else /* Darkened */
3245                 {
3246                         /* The is the square newly darkened and visible? */
3247                         if ((c_ptr->info & (CAVE_VIEW | CAVE_XTRA)) == CAVE_VIEW)
3248                         {
3249                                 /* It is now darkened */
3250                                 /* Add it to later visual update */
3251                                 cave_note_and_redraw_later(c_ptr, fy, fx);
3252                         }
3253                 }
3254
3255                 /* Save in the monster lit or darkened array */
3256                 mon_lite_x[mon_lite_n] = fx;
3257                 mon_lite_y[mon_lite_n] = fy;
3258                 mon_lite_n++;
3259         }
3260
3261         /* Clear the temp flag for the old lit or darken grids */
3262         for (i = end_temp; i < temp_n; i++)
3263         {
3264                 /* We trust this grid is in bounds */
3265
3266                 cave[temp_y[i]][temp_x[i]].info &= ~(CAVE_TEMP | CAVE_XTRA);
3267         }
3268
3269         /* Finished with temp_n */
3270         temp_n = 0;
3271
3272         /* Mega-Hack -- Visual update later */
3273         p_ptr->update |= (PU_DELAY_VIS);
3274
3275         p_ptr->monlite = (cave[py][px].info & CAVE_MNLT) ? TRUE : FALSE;
3276
3277         if (p_ptr->special_defense & NINJA_S_STEALTH)
3278         {
3279                 if (p_ptr->old_monlite != p_ptr->monlite)
3280                 {
3281                         if (p_ptr->monlite)
3282                         {
3283 #ifdef JP
3284                                 msg_print("±Æ¤Îʤ¤¤¤¬Çö¤ì¤¿µ¤¤¬¤¹¤ë¡£");
3285 #else
3286                                 msg_print("Your mantle of shadow become thin.");
3287 #endif
3288                         }
3289                         else
3290                         {
3291 #ifdef JP
3292                                 msg_print("±Æ¤Îʤ¤¤¤¬Ç»¤¯¤Ê¤Ã¤¿¡ª");
3293 #else
3294                                 msg_print("Your mantle of shadow restored its original darkness.");
3295 #endif
3296                         }
3297                 }
3298         }
3299         p_ptr->old_monlite = p_ptr->monlite;
3300 }
3301
3302 void clear_mon_lite(void)
3303 {
3304         int i;
3305         cave_type *c_ptr;
3306
3307         /* Clear all monster lit squares */
3308         for (i = 0; i < mon_lite_n; i++)
3309         {
3310                 /* Point to grid */
3311                 c_ptr = &cave[mon_lite_y[i]][mon_lite_x[i]];
3312
3313                 /* Clear monster illumination flag */
3314                 c_ptr->info &= ~(CAVE_MNLT | CAVE_MNDK);
3315         }
3316
3317         /* Empty the array */
3318         mon_lite_n = 0;
3319 }
3320
3321
3322
3323 /*
3324  * Clear the viewable space
3325  */
3326 void forget_view(void)
3327 {
3328         int i;
3329
3330         cave_type *c_ptr;
3331
3332         /* None to forget */
3333         if (!view_n) return;
3334
3335         /* Clear them all */
3336         for (i = 0; i < view_n; i++)
3337         {
3338                 int y = view_y[i];
3339                 int x = view_x[i];
3340
3341                 /* Access the grid */
3342                 c_ptr = &cave[y][x];
3343
3344                 /* Forget that the grid is viewable */
3345                 c_ptr->info &= ~(CAVE_VIEW);
3346
3347                 /* if (!panel_contains(y, x)) continue; */
3348
3349                 /* Update the screen */
3350                 /* lite_spot(y, x); Perhaps don't need? */
3351         }
3352
3353         /* None left */
3354         view_n = 0;
3355 }
3356
3357
3358
3359 /*
3360  * This macro allows us to efficiently add a grid to the "view" array,
3361  * note that we are never called for illegal grids, or for grids which
3362  * have already been placed into the "view" array, and we are never
3363  * called when the "view" array is full.
3364  */
3365 #define cave_view_hack(C,Y,X) \
3366 {\
3367     if (!((C)->info & (CAVE_VIEW))){\
3368     (C)->info |= (CAVE_VIEW); \
3369     view_y[view_n] = (Y); \
3370     view_x[view_n] = (X); \
3371     view_n++;}\
3372 }
3373
3374
3375
3376 /*
3377  * Helper function for "update_view()" below
3378  *
3379  * We are checking the "viewability" of grid (y,x) by the player.
3380  *
3381  * This function assumes that (y,x) is legal (i.e. on the map).
3382  *
3383  * Grid (y1,x1) is on the "diagonal" between (py,px) and (y,x)
3384  * Grid (y2,x2) is "adjacent", also between (py,px) and (y,x).
3385  *
3386  * Note that we are using the "CAVE_XTRA" field for marking grids as
3387  * "easily viewable".  This bit is cleared at the end of "update_view()".
3388  *
3389  * This function adds (y,x) to the "viewable set" if necessary.
3390  *
3391  * This function now returns "TRUE" if vision is "blocked" by grid (y,x).
3392  */
3393 static bool update_view_aux(int y, int x, int y1, int x1, int y2, int x2)
3394 {
3395         bool f1, f2, v1, v2, z1, z2, wall;
3396
3397         cave_type *c_ptr;
3398
3399         cave_type *g1_c_ptr;
3400         cave_type *g2_c_ptr;
3401
3402         /* Access the grids */
3403         g1_c_ptr = &cave[y1][x1];
3404         g2_c_ptr = &cave[y2][x2];
3405
3406
3407         /* Check for walls */
3408         f1 = (cave_los_grid(g1_c_ptr));
3409         f2 = (cave_los_grid(g2_c_ptr));
3410
3411         /* Totally blocked by physical walls */
3412         if (!f1 && !f2) return (TRUE);
3413
3414
3415         /* Check for visibility */
3416         v1 = (f1 && (g1_c_ptr->info & (CAVE_VIEW)));
3417         v2 = (f2 && (g2_c_ptr->info & (CAVE_VIEW)));
3418
3419         /* Totally blocked by "unviewable neighbors" */
3420         if (!v1 && !v2) return (TRUE);
3421
3422
3423         /* Access the grid */
3424         c_ptr = &cave[y][x];
3425
3426
3427         /* Check for walls */
3428         wall = (!cave_los_grid(c_ptr));
3429
3430
3431         /* Check the "ease" of visibility */
3432         z1 = (v1 && (g1_c_ptr->info & (CAVE_XTRA)));
3433         z2 = (v2 && (g2_c_ptr->info & (CAVE_XTRA)));
3434
3435         /* Hack -- "easy" plus "easy" yields "easy" */
3436         if (z1 && z2)
3437         {
3438                 c_ptr->info |= (CAVE_XTRA);
3439
3440                 cave_view_hack(c_ptr, y, x);
3441
3442                 return (wall);
3443         }
3444
3445         /* Hack -- primary "easy" yields "viewed" */
3446         if (z1)
3447         {
3448                 cave_view_hack(c_ptr, y, x);
3449
3450                 return (wall);
3451         }
3452
3453         /* Hack -- "view" plus "view" yields "view" */
3454         if (v1 && v2)
3455         {
3456                 /* c_ptr->info |= (CAVE_XTRA); */
3457
3458                 cave_view_hack(c_ptr, y, x);
3459
3460                 return (wall);
3461         }
3462
3463
3464         /* Mega-Hack -- the "los()" function works poorly on walls */
3465         if (wall)
3466         {
3467                 cave_view_hack(c_ptr, y, x);
3468
3469                 return (wall);
3470         }
3471
3472
3473         /* Hack -- check line of sight */
3474         if (los(py, px, y, x))
3475         {
3476                 cave_view_hack(c_ptr, y, x);
3477
3478                 return (wall);
3479         }
3480
3481
3482         /* Assume no line of sight. */
3483         return (TRUE);
3484 }
3485
3486
3487
3488 /*
3489  * Calculate the viewable space
3490  *
3491  *  1: Process the player
3492  *  1a: The player is always (easily) viewable
3493  *  2: Process the diagonals
3494  *  2a: The diagonals are (easily) viewable up to the first wall
3495  *  2b: But never go more than 2/3 of the "full" distance
3496  *  3: Process the main axes
3497  *  3a: The main axes are (easily) viewable up to the first wall
3498  *  3b: But never go more than the "full" distance
3499  *  4: Process sequential "strips" in each of the eight octants
3500  *  4a: Each strip runs along the previous strip
3501  *  4b: The main axes are "previous" to the first strip
3502  *  4c: Process both "sides" of each "direction" of each strip
3503  *  4c1: Each side aborts as soon as possible
3504  *  4c2: Each side tells the next strip how far it has to check
3505  *
3506  * Note that the octant processing involves some pretty interesting
3507  * observations involving when a grid might possibly be viewable from
3508  * a given grid, and on the order in which the strips are processed.
3509  *
3510  * Note the use of the mathematical facts shown below, which derive
3511  * from the fact that (1 < sqrt(2) < 1.5), and that the length of the
3512  * hypotenuse of a right triangle is primarily determined by the length
3513  * of the longest side, when one side is small, and is strictly less
3514  * than one-and-a-half times as long as the longest side when both of
3515  * the sides are large.
3516  *
3517  *   if (manhatten(dy,dx) < R) then (hypot(dy,dx) < R)
3518  *   if (manhatten(dy,dx) > R*3/2) then (hypot(dy,dx) > R)
3519  *
3520  *   hypot(dy,dx) is approximated by (dx+dy+MAX(dx,dy)) / 2
3521  *
3522  * These observations are important because the calculation of the actual
3523  * value of "hypot(dx,dy)" is extremely expensive, involving square roots,
3524  * while for small values (up to about 20 or so), the approximations above
3525  * are correct to within an error of at most one grid or so.
3526  *
3527  * Observe the use of "full" and "over" in the code below, and the use of
3528  * the specialized calculation involving "limit", all of which derive from
3529  * the observations given above.  Basically, we note that the "circle" of
3530  * view is completely contained in an "octagon" whose bounds are easy to
3531  * determine, and that only a few steps are needed to derive the actual
3532  * bounds of the circle given the bounds of the octagon.
3533  *
3534  * Note that by skipping all the grids in the corners of the octagon, we
3535  * place an upper limit on the number of grids in the field of view, given
3536  * that "full" is never more than 20.  Of the 1681 grids in the "square" of
3537  * view, only about 1475 of these are in the "octagon" of view, and even
3538  * fewer are in the "circle" of view, so 1500 or 1536 is more than enough
3539  * entries to completely contain the actual field of view.
3540  *
3541  * Note also the care taken to prevent "running off the map".  The use of
3542  * explicit checks on the "validity" of the "diagonal", and the fact that
3543  * the loops are never allowed to "leave" the map, lets "update_view_aux()"
3544  * use the optimized "cave_los_bold()" macro, and to avoid the overhead
3545  * of multiple checks on the validity of grids.
3546  *
3547  * Note the "optimizations" involving the "se","sw","ne","nw","es","en",
3548  * "ws","wn" variables.  They work like this: While travelling down the
3549  * south-bound strip just to the east of the main south axis, as soon as
3550  * we get to a grid which does not "transmit" viewing, if all of the strips
3551  * preceding us (in this case, just the main axis) had terminated at or before
3552  * the same point, then we can stop, and reset the "max distance" to ourself.
3553  * So, each strip (named by major axis plus offset, thus "se" in this case)
3554  * maintains a "blockage" variable, initialized during the main axis step,
3555  * and checks it whenever a blockage is observed.  After processing each
3556  * strip as far as the previous strip told us to process, the next strip is
3557  * told not to go farther than the current strip's farthest viewable grid,
3558  * unless open space is still available.  This uses the "k" variable.
3559  *
3560  * Note the use of "inline" macros for efficiency.  The "cave_los_grid()"
3561  * macro is a replacement for "cave_los_bold()" which takes a pointer to
3562  * a cave grid instead of its location.  The "cave_view_hack()" macro is a
3563  * chunk of code which adds the given location to the "view" array if it
3564  * is not already there, using both the actual location and a pointer to
3565  * the cave grid.  See above.
3566  *
3567  * By the way, the purpose of this code is to reduce the dependancy on the
3568  * "los()" function which is slow, and, in some cases, not very accurate.
3569  *
3570  * It is very possible that I am the only person who fully understands this
3571  * function, and for that I am truly sorry, but efficiency was very important
3572  * and the "simple" version of this function was just not fast enough.  I am
3573  * more than willing to replace this function with a simpler one, if it is
3574  * equally efficient, and especially willing if the new function happens to
3575  * derive "reverse-line-of-sight" at the same time, since currently monsters
3576  * just use an optimized hack of "you see me, so I see you", and then use the
3577  * actual "projectable()" function to check spell attacks.
3578  */
3579 void update_view(void)
3580 {
3581         int n, m, d, k, y, x, z;
3582
3583         int se, sw, ne, nw, es, en, ws, wn;
3584
3585         int full, over;
3586
3587         int y_max = cur_hgt - 1;
3588         int x_max = cur_wid - 1;
3589
3590         cave_type *c_ptr;
3591
3592         /*** Initialize ***/
3593
3594         /* Optimize */
3595         if (view_reduce_view && !dun_level)
3596         {
3597                 /* Full radius (10) */
3598                 full = MAX_SIGHT / 2;
3599
3600                 /* Octagon factor (15) */
3601                 over = MAX_SIGHT * 3 / 4;
3602         }
3603
3604         /* Normal */
3605         else
3606         {
3607                 /* Full radius (20) */
3608                 full = MAX_SIGHT;
3609
3610                 /* Octagon factor (30) */
3611                 over = MAX_SIGHT * 3 / 2;
3612         }
3613
3614
3615         /*** Step 0 -- Begin ***/
3616
3617         /* Save the old "view" grids for later */
3618         for (n = 0; n < view_n; n++)
3619         {
3620                 y = view_y[n];
3621                 x = view_x[n];
3622
3623                 /* Access the grid */
3624                 c_ptr = &cave[y][x];
3625
3626                 /* Mark the grid as not in "view" */
3627                 c_ptr->info &= ~(CAVE_VIEW);
3628
3629                 /* Mark the grid as "seen" */
3630                 c_ptr->info |= (CAVE_TEMP);
3631
3632                 /* Add it to the "seen" set */
3633                 temp_y[temp_n] = y;
3634                 temp_x[temp_n] = x;
3635                 temp_n++;
3636         }
3637
3638         /* Start over with the "view" array */
3639         view_n = 0;
3640
3641         /*** Step 1 -- adjacent grids ***/
3642
3643         /* Now start on the player */
3644         y = py;
3645         x = px;
3646
3647         /* Access the grid */
3648         c_ptr = &cave[y][x];
3649
3650         /* Assume the player grid is easily viewable */
3651         c_ptr->info |= (CAVE_XTRA);
3652
3653         /* Assume the player grid is viewable */
3654         cave_view_hack(c_ptr, y, x);
3655
3656
3657         /*** Step 2 -- Major Diagonals ***/
3658
3659         /* Hack -- Limit */
3660         z = full * 2 / 3;
3661
3662         /* Scan south-east */
3663         for (d = 1; d <= z; d++)
3664         {
3665                 c_ptr = &cave[y+d][x+d];
3666                 c_ptr->info |= (CAVE_XTRA);
3667                 cave_view_hack(c_ptr, y+d, x+d);
3668                 if (!cave_los_grid(c_ptr)) break;
3669         }
3670
3671         /* Scan south-west */
3672         for (d = 1; d <= z; d++)
3673         {
3674                 c_ptr = &cave[y+d][x-d];
3675                 c_ptr->info |= (CAVE_XTRA);
3676                 cave_view_hack(c_ptr, y+d, x-d);
3677                 if (!cave_los_grid(c_ptr)) break;
3678         }
3679
3680         /* Scan north-east */
3681         for (d = 1; d <= z; d++)
3682         {
3683                 c_ptr = &cave[y-d][x+d];
3684                 c_ptr->info |= (CAVE_XTRA);
3685                 cave_view_hack(c_ptr, y-d, x+d);
3686                 if (!cave_los_grid(c_ptr)) break;
3687         }
3688
3689         /* Scan north-west */
3690         for (d = 1; d <= z; d++)
3691         {
3692                 c_ptr = &cave[y-d][x-d];
3693                 c_ptr->info |= (CAVE_XTRA);
3694                 cave_view_hack(c_ptr, y-d, x-d);
3695                 if (!cave_los_grid(c_ptr)) break;
3696         }
3697
3698
3699         /*** Step 3 -- major axes ***/
3700
3701         /* Scan south */
3702         for (d = 1; d <= full; d++)
3703         {
3704                 c_ptr = &cave[y+d][x];
3705                 c_ptr->info |= (CAVE_XTRA);
3706                 cave_view_hack(c_ptr, y+d, x);
3707                 if (!cave_los_grid(c_ptr)) break;
3708         }
3709
3710         /* Initialize the "south strips" */
3711         se = sw = d;
3712
3713         /* Scan north */
3714         for (d = 1; d <= full; d++)
3715         {
3716                 c_ptr = &cave[y-d][x];
3717                 c_ptr->info |= (CAVE_XTRA);
3718                 cave_view_hack(c_ptr, y-d, x);
3719                 if (!cave_los_grid(c_ptr)) break;
3720         }
3721
3722         /* Initialize the "north strips" */
3723         ne = nw = d;
3724
3725         /* Scan east */
3726         for (d = 1; d <= full; d++)
3727         {
3728                 c_ptr = &cave[y][x+d];
3729                 c_ptr->info |= (CAVE_XTRA);
3730                 cave_view_hack(c_ptr, y, x+d);
3731                 if (!cave_los_grid(c_ptr)) break;
3732         }
3733
3734         /* Initialize the "east strips" */
3735         es = en = d;
3736
3737         /* Scan west */
3738         for (d = 1; d <= full; d++)
3739         {
3740                 c_ptr = &cave[y][x-d];
3741                 c_ptr->info |= (CAVE_XTRA);
3742                 cave_view_hack(c_ptr, y, x-d);
3743                 if (!cave_los_grid(c_ptr)) break;
3744         }
3745
3746         /* Initialize the "west strips" */
3747         ws = wn = d;
3748
3749
3750         /*** Step 4 -- Divide each "octant" into "strips" ***/
3751
3752         /* Now check each "diagonal" (in parallel) */
3753         for (n = 1; n <= over / 2; n++)
3754         {
3755                 int ypn, ymn, xpn, xmn;
3756
3757
3758                 /* Acquire the "bounds" of the maximal circle */
3759                 z = over - n - n;
3760                 if (z > full - n) z = full - n;
3761                 while ((z + n + (n>>1)) > full) z--;
3762
3763
3764                 /* Access the four diagonal grids */
3765                 ypn = y + n;
3766                 ymn = y - n;
3767                 xpn = x + n;
3768                 xmn = x - n;
3769
3770
3771                 /* South strip */
3772                 if (ypn < y_max)
3773                 {
3774                         /* Maximum distance */
3775                         m = MIN(z, y_max - ypn);
3776
3777                         /* East side */
3778                         if ((xpn <= x_max) && (n < se))
3779                         {
3780                                 /* Scan */
3781                                 for (k = n, d = 1; d <= m; d++)
3782                                 {
3783                                         /* Check grid "d" in strip "n", notice "blockage" */
3784                                         if (update_view_aux(ypn+d, xpn, ypn+d-1, xpn-1, ypn+d-1, xpn))
3785                                         {
3786                                                 if (n + d >= se) break;
3787                                         }
3788
3789                                         /* Track most distant "non-blockage" */
3790                                         else
3791                                         {
3792                                                 k = n + d;
3793                                         }
3794                                 }
3795
3796                                 /* Limit the next strip */
3797                                 se = k + 1;
3798                         }
3799
3800                         /* West side */
3801                         if ((xmn >= 0) && (n < sw))
3802                         {
3803                                 /* Scan */
3804                                 for (k = n, d = 1; d <= m; d++)
3805                                 {
3806                                         /* Check grid "d" in strip "n", notice "blockage" */
3807                                         if (update_view_aux(ypn+d, xmn, ypn+d-1, xmn+1, ypn+d-1, xmn))
3808                                         {
3809                                                 if (n + d >= sw) break;
3810                                         }
3811
3812                                         /* Track most distant "non-blockage" */
3813                                         else
3814                                         {
3815                                                 k = n + d;
3816                                         }
3817                                 }
3818
3819                                 /* Limit the next strip */
3820                                 sw = k + 1;
3821                         }
3822                 }
3823
3824
3825                 /* North strip */
3826                 if (ymn > 0)
3827                 {
3828                         /* Maximum distance */
3829                         m = MIN(z, ymn);
3830
3831                         /* East side */
3832                         if ((xpn <= x_max) && (n < ne))
3833                         {
3834                                 /* Scan */
3835                                 for (k = n, d = 1; d <= m; d++)
3836                                 {
3837                                         /* Check grid "d" in strip "n", notice "blockage" */
3838                                         if (update_view_aux(ymn-d, xpn, ymn-d+1, xpn-1, ymn-d+1, xpn))
3839                                         {
3840                                                 if (n + d >= ne) break;
3841                                         }
3842
3843                                         /* Track most distant "non-blockage" */
3844                                         else
3845                                         {
3846                                                 k = n + d;
3847                                         }
3848                                 }
3849
3850                                 /* Limit the next strip */
3851                                 ne = k + 1;
3852                         }
3853
3854                         /* West side */
3855                         if ((xmn >= 0) && (n < nw))
3856                         {
3857                                 /* Scan */
3858                                 for (k = n, d = 1; d <= m; d++)
3859                                 {
3860                                         /* Check grid "d" in strip "n", notice "blockage" */
3861                                         if (update_view_aux(ymn-d, xmn, ymn-d+1, xmn+1, ymn-d+1, xmn))
3862                                         {
3863                                                 if (n + d >= nw) break;
3864                                         }
3865
3866                                         /* Track most distant "non-blockage" */
3867                                         else
3868                                         {
3869                                                 k = n + d;
3870                                         }
3871                                 }
3872
3873                                 /* Limit the next strip */
3874                                 nw = k + 1;
3875                         }
3876                 }
3877
3878
3879                 /* East strip */
3880                 if (xpn < x_max)
3881                 {
3882                         /* Maximum distance */
3883                         m = MIN(z, x_max - xpn);
3884
3885                         /* South side */
3886                         if ((ypn <= x_max) && (n < es))
3887                         {
3888                                 /* Scan */
3889                                 for (k = n, d = 1; d <= m; d++)
3890                                 {
3891                                         /* Check grid "d" in strip "n", notice "blockage" */
3892                                         if (update_view_aux(ypn, xpn+d, ypn-1, xpn+d-1, ypn, xpn+d-1))
3893                                         {
3894                                                 if (n + d >= es) break;
3895                                         }
3896
3897                                         /* Track most distant "non-blockage" */
3898                                         else
3899                                         {
3900                                                 k = n + d;
3901                                         }
3902                                 }
3903
3904                                 /* Limit the next strip */
3905                                 es = k + 1;
3906                         }
3907
3908                         /* North side */
3909                         if ((ymn >= 0) && (n < en))
3910                         {
3911                                 /* Scan */
3912                                 for (k = n, d = 1; d <= m; d++)
3913                                 {
3914                                         /* Check grid "d" in strip "n", notice "blockage" */
3915                                         if (update_view_aux(ymn, xpn+d, ymn+1, xpn+d-1, ymn, xpn+d-1))
3916                                         {
3917                                                 if (n + d >= en) break;
3918                                         }
3919
3920                                         /* Track most distant "non-blockage" */
3921                                         else
3922                                         {
3923                                                 k = n + d;
3924                                         }
3925                                 }
3926
3927                                 /* Limit the next strip */
3928                                 en = k + 1;
3929                         }
3930                 }
3931
3932
3933                 /* West strip */
3934                 if (xmn > 0)
3935                 {
3936                         /* Maximum distance */
3937                         m = MIN(z, xmn);
3938
3939                         /* South side */
3940                         if ((ypn <= y_max) && (n < ws))
3941                         {
3942                                 /* Scan */
3943                                 for (k = n, d = 1; d <= m; d++)
3944                                 {
3945                                         /* Check grid "d" in strip "n", notice "blockage" */
3946                                         if (update_view_aux(ypn, xmn-d, ypn-1, xmn-d+1, ypn, xmn-d+1))
3947                                         {
3948                                                 if (n + d >= ws) break;
3949                                         }
3950
3951                                         /* Track most distant "non-blockage" */
3952                                         else
3953                                         {
3954                                                 k = n + d;
3955                                         }
3956                                 }
3957
3958                                 /* Limit the next strip */
3959                                 ws = k + 1;
3960                         }
3961
3962                         /* North side */
3963                         if ((ymn >= 0) && (n < wn))
3964                         {
3965                                 /* Scan */
3966                                 for (k = n, d = 1; d <= m; d++)
3967                                 {
3968                                         /* Check grid "d" in strip "n", notice "blockage" */
3969                                         if (update_view_aux(ymn, xmn-d, ymn+1, xmn-d+1, ymn, xmn-d+1))
3970                                         {
3971                                                 if (n + d >= wn) break;
3972                                         }
3973
3974                                         /* Track most distant "non-blockage" */
3975                                         else
3976                                         {
3977                                                 k = n + d;
3978                                         }
3979                                 }
3980
3981                                 /* Limit the next strip */
3982                                 wn = k + 1;
3983                         }
3984                 }
3985         }
3986
3987
3988         /*** Step 5 -- Complete the algorithm ***/
3989
3990         /* Update all the new grids */
3991         for (n = 0; n < view_n; n++)
3992         {
3993                 y = view_y[n];
3994                 x = view_x[n];
3995
3996                 /* Access the grid */
3997                 c_ptr = &cave[y][x];
3998
3999                 /* Clear the "CAVE_XTRA" flag */
4000                 c_ptr->info &= ~(CAVE_XTRA);
4001
4002                 /* Update only newly viewed grids */
4003                 if (c_ptr->info & (CAVE_TEMP)) continue;
4004
4005                 /* Add it to later visual update */
4006                 cave_note_and_redraw_later(c_ptr, y, x);
4007         }
4008
4009         /* Wipe the old grids, update as needed */
4010         for (n = 0; n < temp_n; n++)
4011         {
4012                 y = temp_y[n];
4013                 x = temp_x[n];
4014
4015                 /* Access the grid */
4016                 c_ptr = &cave[y][x];
4017
4018                 /* No longer in the array */
4019                 c_ptr->info &= ~(CAVE_TEMP);
4020
4021                 /* Update only non-viewable grids */
4022                 if (c_ptr->info & (CAVE_VIEW)) continue;
4023
4024                 /* Add it to later visual update */
4025                 cave_redraw_later(c_ptr, y, x);
4026         }
4027
4028         /* None left */
4029         temp_n = 0;
4030
4031         /* Mega-Hack -- Visual update later */
4032         p_ptr->update |= (PU_DELAY_VIS);
4033 }
4034
4035
4036 /*
4037  * Mega-Hack -- Delayed visual update
4038  * Only used if update_view(), update_lite() or update_mon_lite() was called
4039  */
4040 void delayed_visual_update(void)
4041 {
4042         int       i, y, x;
4043         cave_type *c_ptr;
4044
4045         /* Update needed grids */
4046         for (i = 0; i < redraw_n; i++)
4047         {
4048                 y = redraw_y[i];
4049                 x = redraw_x[i];
4050
4051                 /* Access the grid */
4052                 c_ptr = &cave[y][x];
4053
4054                 /* Update only needed grids (prevent multiple updating) */
4055                 if (!(c_ptr->info & CAVE_REDRAW)) continue;
4056
4057                 /* If required, note */
4058                 if (c_ptr->info & CAVE_NOTE) note_spot(y, x);
4059
4060                 /* Redraw */
4061                 lite_spot(y, x);
4062
4063                 /* Hack -- Visual update of monster on this grid */
4064                 if (c_ptr->m_idx) update_mon(c_ptr->m_idx, FALSE);
4065
4066                 /* No longer in the array */
4067                 c_ptr->info &= ~(CAVE_NOTE | CAVE_REDRAW);
4068         }
4069
4070         /* None left */
4071         redraw_n = 0;
4072 }
4073
4074
4075 /*
4076  * Hack -- forget the "flow" information
4077  */
4078 void forget_flow(void)
4079 {
4080         int x, y;
4081
4082         /* Check the entire dungeon */
4083         for (y = 0; y < cur_hgt; y++)
4084         {
4085                 for (x = 0; x < cur_wid; x++)
4086                 {
4087                         /* Forget the old data */
4088                         cave[y][x].dist = 0;
4089                         cave[y][x].cost = 0;
4090                         cave[y][x].when = 0;
4091                 }
4092         }
4093 }
4094
4095
4096 /*
4097  * Hack - speed up the update_flow algorithm by only doing
4098  * it everytime the player moves out of LOS of the last
4099  * "way-point".
4100  */
4101 static u16b flow_x = 0;
4102 static u16b flow_y = 0;
4103
4104
4105
4106 /*
4107  * Hack -- fill in the "cost" field of every grid that the player
4108  * can "reach" with the number of steps needed to reach that grid.
4109  * This also yields the "distance" of the player from every grid.
4110  *
4111  * In addition, mark the "when" of the grids that can reach
4112  * the player with the incremented value of "flow_n".
4113  *
4114  * Hack -- use the "seen" array as a "circular queue".
4115  *
4116  * We do not need a priority queue because the cost from grid
4117  * to grid is always "one" and we process them in order.
4118  */
4119 void update_flow(void)
4120 {
4121         int x, y, d;
4122         int flow_head = 1;
4123         int flow_tail = 0;
4124
4125         /* Paranoia -- make sure the array is empty */
4126         if (temp_n) return;
4127
4128         /* The last way-point is on the map */
4129         if (running && in_bounds(flow_y, flow_x))
4130         {
4131                 /* The way point is in sight - do not update.  (Speedup) */
4132                 if (cave[flow_y][flow_x].info & CAVE_VIEW) return;
4133         }
4134
4135         /* Erase all of the current flow information */
4136         for (y = 0; y < cur_hgt; y++)
4137         {
4138                 for (x = 0; x < cur_wid; x++)
4139                 {
4140                         cave[y][x].cost = 0;
4141                         cave[y][x].dist = 0;
4142                 }
4143         }
4144
4145         /* Save player position */
4146         flow_y = py;
4147         flow_x = px;
4148
4149         /* Add the player's grid to the queue */
4150         temp_y[0] = py;
4151         temp_x[0] = px;
4152
4153         /* Now process the queue */
4154         while (flow_head != flow_tail)
4155         {
4156                 int ty, tx;
4157
4158                 /* Extract the next entry */
4159                 ty = temp_y[flow_tail];
4160                 tx = temp_x[flow_tail];
4161
4162                 /* Forget that entry */
4163                 if (++flow_tail == TEMP_MAX) flow_tail = 0;
4164
4165                 /* Add the "children" */
4166                 for (d = 0; d < 8; d++)
4167                 {
4168                         int old_head = flow_head;
4169                         int m = cave[ty][tx].cost + 1;
4170                         int n = cave[ty][tx].dist + 1;
4171                         cave_type *c_ptr;
4172
4173                         /* Child location */
4174                         y = ty + ddy_ddd[d];
4175                         x = tx + ddx_ddd[d];
4176
4177                         /* Ignore player's grid */
4178                         if (player_bold(y, x)) continue;
4179
4180                         c_ptr = &cave[y][x];
4181
4182                         if (is_closed_door(c_ptr->feat)) m += 3;
4183
4184                         /* Ignore "pre-stamped" entries */
4185                         if (c_ptr->dist != 0 && c_ptr->dist <= n && c_ptr->cost <= m) continue;
4186
4187                         /* Ignore "walls" and "rubble" */
4188                         if (!cave_have_flag_grid(c_ptr, FF_MOVE) && !is_closed_door(c_ptr->feat)) continue;
4189
4190                         /* Save the flow cost */
4191                         if (c_ptr->cost == 0 || c_ptr->cost > m) c_ptr->cost = m;
4192                         if (c_ptr->dist == 0 || c_ptr->dist > n) c_ptr->dist = n;
4193
4194                         /* Hack -- limit flow depth */
4195                         if (n == MONSTER_FLOW_DEPTH) continue;
4196
4197                         /* Enqueue that entry */
4198                         temp_y[flow_head] = y;
4199                         temp_x[flow_head] = x;
4200
4201                         /* Advance the queue */
4202                         if (++flow_head == TEMP_MAX) flow_head = 0;
4203
4204                         /* Hack -- notice overflow by forgetting new entry */
4205                         if (flow_head == flow_tail) flow_head = old_head;
4206                 }
4207         }
4208 }
4209
4210
4211 static int scent_when = 0;
4212
4213 /*
4214  * Characters leave scent trails for perceptive monsters to track.
4215  *
4216  * Smell is rather more limited than sound.  Many creatures cannot use 
4217  * it at all, it doesn't extend very far outwards from the character's 
4218  * current position, and monsters can use it to home in the character, 
4219  * but not to run away from him.
4220  *
4221  * Smell is valued according to age.  When a character takes his turn, 
4222  * scent is aged by one, and new scent of the current age is laid down.  
4223  * Speedy characters leave more scent, true, but it also ages faster, 
4224  * which makes it harder to hunt them down.
4225  *
4226  * Whenever the age count loops, most of the scent trail is erased and 
4227  * the age of the remainder is recalculated.
4228  */
4229 void update_smell(void)
4230 {
4231         int i, j;
4232         int y, x;
4233
4234         /* Create a table that controls the spread of scent */
4235         const int scent_adjust[5][5] = 
4236         {
4237                 { -1, 0, 0, 0,-1 },
4238                 {  0, 1, 1, 1, 0 },
4239                 {  0, 1, 2, 1, 0 },
4240                 {  0, 1, 1, 1, 0 },
4241                 { -1, 0, 0, 0,-1 },
4242         };
4243
4244         /* Loop the age and adjust scent values when necessary */
4245         if (++scent_when == 254)
4246         {
4247                 /* Scan the entire dungeon */
4248                 for (y = 0; y < cur_hgt; y++)
4249                 {
4250                         for (x = 0; x < cur_wid; x++)
4251                         {
4252                                 int w = cave[y][x].when;
4253                                 cave[y][x].when = (w > 128) ? (w - 128) : 0;
4254                         }
4255                 }
4256
4257                 /* Restart */
4258                 scent_when = 126;
4259         }
4260
4261
4262         /* Lay down new scent */
4263         for (i = 0; i < 5; i++)
4264         {
4265                 for (j = 0; j < 5; j++)
4266                 {
4267                         cave_type *c_ptr;
4268
4269                         /* Translate table to map grids */
4270                         y = i + py - 2;
4271                         x = j + px - 2;
4272
4273                         /* Check Bounds */
4274                         if (!in_bounds(y, x)) continue;
4275
4276                         c_ptr = &cave[y][x];
4277
4278                         /* Walls, water, and lava cannot hold scent. */
4279                         if (!cave_have_flag_grid(c_ptr, FF_MOVE) && !is_closed_door(c_ptr->feat)) continue;
4280
4281                         /* Grid must not be blocked by walls from the character */
4282                         if (!player_has_los_bold(y, x)) continue;
4283
4284                         /* Note grids that are too far away */
4285                         if (scent_adjust[i][j] == -1) continue;
4286
4287                         /* Mark the grid with new scent */
4288                         c_ptr->when = scent_when + scent_adjust[i][j];
4289                 }
4290         }
4291 }
4292
4293
4294 /*
4295  * Hack -- map the current panel (plus some) ala "magic mapping"
4296  */
4297 void map_area(int range)
4298 {
4299         int             i, x, y;
4300         cave_type       *c_ptr;
4301         s16b            feat;
4302         feature_type    *f_ptr;
4303
4304         if (d_info[dungeon_type].flags1 & DF1_DARKNESS) range /= 3;
4305
4306         /* Scan that area */
4307         for (y = 1; y < cur_hgt - 1; y++)
4308         {
4309                 for (x = 1; x < cur_wid - 1; x++)
4310                 {
4311                         if (distance(py, px, y, x) > range) continue;
4312
4313                         c_ptr = &cave[y][x];
4314
4315                         /* Memorize terrain of the grid */
4316                         c_ptr->info |= (CAVE_KNOWN);
4317
4318                         /* Feature code (applying "mimic" field) */
4319                         feat = get_feat_mimic(c_ptr);
4320                         f_ptr = &f_info[feat];
4321
4322                         /* All non-walls are "checked" */
4323                         if (!have_flag(f_ptr->flags, FF_WALL))
4324                         {
4325                                 /* Memorize normal features */
4326                                 if (have_flag(f_ptr->flags, FF_REMEMBER))
4327                                 {
4328                                         /* Memorize the object */
4329                                         c_ptr->info |= (CAVE_MARK);
4330                                 }
4331
4332                                 /* Memorize known walls */
4333                                 for (i = 0; i < 8; i++)
4334                                 {
4335                                         c_ptr = &cave[y + ddy_ddd[i]][x + ddx_ddd[i]];
4336
4337                                         /* Feature code (applying "mimic" field) */
4338                                         feat = get_feat_mimic(c_ptr);
4339                                         f_ptr = &f_info[feat];
4340
4341                                         /* Memorize walls (etc) */
4342                                         if (have_flag(f_ptr->flags, FF_REMEMBER))
4343                                         {
4344                                                 /* Memorize the walls */
4345                                                 c_ptr->info |= (CAVE_MARK);
4346                                         }
4347                                 }
4348                         }
4349                 }
4350         }
4351
4352         /* Redraw map */
4353         p_ptr->redraw |= (PR_MAP);
4354
4355         /* Window stuff */
4356         p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
4357 }
4358
4359
4360
4361 /*
4362  * Light up the dungeon using "clairvoyance"
4363  *
4364  * This function "illuminates" every grid in the dungeon, memorizes all
4365  * "objects", memorizes all grids as with magic mapping, and, under the
4366  * standard option settings (view_perma_grids but not view_torch_grids)
4367  * memorizes all floor grids too.
4368  *
4369  * Note that if "view_perma_grids" is not set, we do not memorize floor
4370  * grids, since this would defeat the purpose of "view_perma_grids", not
4371  * that anyone seems to play without this option.
4372  *
4373  * Note that if "view_torch_grids" is set, we do not memorize floor grids,
4374  * since this would prevent the use of "view_torch_grids" as a method to
4375  * keep track of what grids have been observed directly.
4376  */
4377 void wiz_lite(bool ninja)
4378 {
4379         int i, y, x;
4380         s16b feat;
4381         feature_type *f_ptr;
4382
4383         /* Memorize objects */
4384         for (i = 1; i < o_max; i++)
4385         {
4386                 object_type *o_ptr = &o_list[i];
4387
4388                 /* Skip dead objects */
4389                 if (!o_ptr->k_idx) continue;
4390
4391                 /* Skip held objects */
4392                 if (o_ptr->held_m_idx) continue;
4393
4394                 /* Memorize */
4395                 o_ptr->marked |= OM_FOUND;
4396         }
4397
4398         /* Scan all normal grids */
4399         for (y = 1; y < cur_hgt - 1; y++)
4400         {
4401                 /* Scan all normal grids */
4402                 for (x = 1; x < cur_wid - 1; x++)
4403                 {
4404                         cave_type *c_ptr = &cave[y][x];
4405
4406                         /* Memorize terrain of the grid */
4407                         c_ptr->info |= (CAVE_KNOWN);
4408
4409                         /* Feature code (applying "mimic" field) */
4410                         feat = get_feat_mimic(c_ptr);
4411                         f_ptr = &f_info[feat];
4412
4413                         /* Process all non-walls */
4414                         if (!have_flag(f_ptr->flags, FF_WALL))
4415                         {
4416                                 /* Scan all neighbors */
4417                                 for (i = 0; i < 9; i++)
4418                                 {
4419                                         int yy = y + ddy_ddd[i];
4420                                         int xx = x + ddx_ddd[i];
4421
4422                                         /* Get the grid */
4423                                         c_ptr = &cave[yy][xx];
4424
4425                                         /* Feature code (applying "mimic" field) */
4426                                         f_ptr = &f_info[get_feat_mimic(c_ptr)];
4427
4428                                         /* Perma-lite the grid */
4429                                         if (!(d_info[dungeon_type].flags1 & DF1_DARKNESS) && !ninja)
4430                                         {
4431                                                 c_ptr->info |= (CAVE_GLOW);
4432                                         }
4433
4434                                         /* Memorize normal features */
4435                                         if (have_flag(f_ptr->flags, FF_REMEMBER))
4436                                         {
4437                                                 /* Memorize the grid */
4438                                                 c_ptr->info |= (CAVE_MARK);
4439                                         }
4440
4441                                         /* Perma-lit grids (newly and previously) */
4442                                         else if (c_ptr->info & CAVE_GLOW)
4443                                         {
4444                                                 /* Normally, memorize floors (see above) */
4445                                                 if (view_perma_grids && !view_torch_grids)
4446                                                 {
4447                                                         /* Memorize the grid */
4448                                                         c_ptr->info |= (CAVE_MARK);
4449                                                 }
4450                                         }
4451                                 }
4452                         }
4453                 }
4454         }
4455
4456         /* Update the monsters */
4457         p_ptr->update |= (PU_MONSTERS);
4458
4459         /* Redraw map */
4460         p_ptr->redraw |= (PR_MAP);
4461
4462         /* Window stuff */
4463         p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
4464
4465         if (p_ptr->special_defense & NINJA_S_STEALTH)
4466         {
4467                 if (cave[py][px].info & CAVE_GLOW) set_superstealth(FALSE);
4468         }
4469 }
4470
4471
4472 /*
4473  * Forget the dungeon map (ala "Thinking of Maud...").
4474  */
4475 void wiz_dark(void)
4476 {
4477         int i, y, x;
4478
4479
4480         /* Forget every grid */
4481         for (y = 1; y < cur_hgt - 1; y++)
4482         {
4483                 for (x = 1; x < cur_wid - 1; x++)
4484                 {
4485                         cave_type *c_ptr = &cave[y][x];
4486
4487                         /* Process the grid */
4488                         c_ptr->info &= ~(CAVE_MARK | CAVE_IN_DETECT | CAVE_KNOWN);
4489                         c_ptr->info |= (CAVE_UNSAFE);
4490                 }
4491         }
4492
4493         /* Forget every grid on horizontal edge */
4494         for (x = 0; x < cur_wid; x++)
4495         {
4496                 cave[0][x].info &= ~(CAVE_MARK);
4497                 cave[cur_hgt - 1][x].info &= ~(CAVE_MARK);
4498         }
4499
4500         /* Forget every grid on vertical edge */
4501         for (y = 1; y < (cur_hgt - 1); y++)
4502         {
4503                 cave[y][0].info &= ~(CAVE_MARK);
4504                 cave[y][cur_wid - 1].info &= ~(CAVE_MARK);
4505         }
4506
4507         /* Forget all objects */
4508         for (i = 1; i < o_max; i++)
4509         {
4510                 object_type *o_ptr = &o_list[i];
4511
4512                 /* Skip dead objects */
4513                 if (!o_ptr->k_idx) continue;
4514
4515                 /* Skip held objects */
4516                 if (o_ptr->held_m_idx) continue;
4517
4518                 /* Forget the object */
4519                 o_ptr->marked &= OM_TOUCHED;
4520         }
4521
4522         /* Forget travel route when we have forgotten map */
4523         forget_travel_flow();
4524
4525         /* Mega-Hack -- Forget the view and lite */
4526         p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
4527
4528         /* Update the view and lite */
4529         p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
4530
4531         /* Update the monsters */
4532         p_ptr->update |= (PU_MONSTERS);
4533
4534         /* Redraw map */
4535         p_ptr->redraw |= (PR_MAP);
4536
4537         /* Window stuff */
4538         p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
4539 }
4540
4541
4542
4543
4544
4545 /*
4546  * Change the "feat" flag for a grid, and notice/redraw the grid
4547  */
4548 void cave_set_feat(int y, int x, int feat)
4549 {
4550         cave_type *c_ptr = &cave[y][x];
4551         feature_type *f_ptr = &f_info[feat];
4552         bool old_los, old_mirror;
4553
4554         if (!character_dungeon)
4555         {
4556                 /* Clear mimic type */
4557                 c_ptr->mimic = 0;
4558
4559                 /* Change the feature */
4560                 c_ptr->feat = feat;
4561
4562                 /* Hack -- glow the GLOW terrain */
4563                 if (have_flag(f_ptr->flags, FF_GLOW) && !(d_info[dungeon_type].flags1 & DF1_DARKNESS))
4564                 {
4565                         int i, yy, xx;
4566
4567                         for (i = 0; i < 9; i++)
4568                         {
4569                                 yy = y + ddy_ddd[i];
4570                                 xx = x + ddx_ddd[i];
4571                                 if (!in_bounds2(yy, xx)) continue;
4572                                 cave[yy][xx].info |= CAVE_GLOW;
4573                         }
4574                 }
4575
4576                 return;
4577         }
4578
4579         old_los = cave_have_flag_bold(y, x, FF_LOS);
4580         old_mirror = is_mirror_grid(c_ptr);
4581
4582         /* Clear mimic type */
4583         c_ptr->mimic = 0;
4584
4585         /* Change the feature */
4586         c_ptr->feat = feat;
4587
4588         /* Remove flag for mirror/glyph */
4589         c_ptr->info &= ~(CAVE_OBJECT);
4590
4591         if (old_mirror && (d_info[dungeon_type].flags1 & DF1_DARKNESS))
4592         {
4593                 c_ptr->info &= ~(CAVE_GLOW);
4594                 if (!view_torch_grids) c_ptr->info &= ~(CAVE_MARK);
4595
4596                 update_local_illumination(y, x);
4597         }
4598
4599         /* Check for change to boring grid */
4600         if (!have_flag(f_ptr->flags, FF_REMEMBER)) c_ptr->info &= ~(CAVE_MARK);
4601
4602         /* Update the monster */
4603         if (c_ptr->m_idx) update_mon(c_ptr->m_idx, FALSE);
4604
4605         /* Notice */
4606         note_spot(y, x);
4607
4608         /* Redraw */
4609         lite_spot(y, x);
4610
4611         /* Check if los has changed */
4612         if (old_los ^ have_flag(f_ptr->flags, FF_LOS))
4613         {
4614
4615 #ifdef COMPLEX_WALL_ILLUMINATION /* COMPLEX_WALL_ILLUMINATION */
4616
4617                 update_local_illumination(y, x);
4618
4619 #endif /* COMPLEX_WALL_ILLUMINATION */
4620
4621                 /* Update the visuals */
4622                 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE | PU_MONSTERS);
4623         }
4624
4625         /* Hack -- glow the GLOW terrain */
4626         if (have_flag(f_ptr->flags, FF_GLOW) && !(d_info[dungeon_type].flags1 & DF1_DARKNESS))
4627         {
4628                 int i, yy, xx;
4629                 cave_type *cc_ptr;
4630
4631                 for (i = 0; i < 9; i++)
4632                 {
4633                         yy = y + ddy_ddd[i];
4634                         xx = x + ddx_ddd[i];
4635                         if (!in_bounds2(yy, xx)) continue;
4636                         cc_ptr = &cave[yy][xx];
4637                         cc_ptr->info |= CAVE_GLOW;
4638
4639                         if (player_has_los_grid(cc_ptr))
4640                         {
4641                                 /* Update the monster */
4642                                 if (cc_ptr->m_idx) update_mon(cc_ptr->m_idx, FALSE);
4643
4644                                 /* Notice */
4645                                 note_spot(yy, xx);
4646
4647                                 /* Redraw */
4648                                 lite_spot(yy, xx);
4649                         }
4650
4651                         update_local_illumination(yy, xx);
4652                 }
4653
4654                 if (p_ptr->special_defense & NINJA_S_STEALTH)
4655                 {
4656                         if (cave[py][px].info & CAVE_GLOW) set_superstealth(FALSE);
4657                 }
4658         }
4659 }
4660
4661
4662 int conv_dungeon_feat(int newfeat)
4663 {
4664         feature_type *f_ptr = &f_info[newfeat];
4665
4666         if (have_flag(f_ptr->flags, FF_CONVERT))
4667         {
4668                 switch (f_ptr->subtype)
4669                 {
4670                 case CONVERT_TYPE_FLOOR:
4671                         return floor_type[randint0(100)];
4672                 case CONVERT_TYPE_WALL:
4673                         return fill_type[randint0(100)];
4674                 case CONVERT_TYPE_INNER:
4675                         return feat_wall_inner;
4676                 case CONVERT_TYPE_OUTER:
4677                         return feat_wall_outer;
4678                 case CONVERT_TYPE_SOLID:
4679                         return feat_wall_solid;
4680                 case CONVERT_TYPE_STREAM1:
4681                         return d_info[dungeon_type].stream1;
4682                 case CONVERT_TYPE_STREAM2:
4683                         return d_info[dungeon_type].stream2;
4684                 default:
4685                         return newfeat;
4686                 }
4687         }
4688         else return newfeat;
4689 }
4690
4691
4692 /*
4693  * Take a feature, determine what that feature becomes
4694  * through applying the given action.
4695  */
4696 int feat_state(int feat, int action)
4697 {
4698         feature_type *f_ptr = &f_info[feat];
4699         int i;
4700
4701         /* Get the new feature */
4702         for (i = 0; i < MAX_FEAT_STATES; i++)
4703         {
4704                 if (f_ptr->state[i].action == action) return conv_dungeon_feat(f_ptr->state[i].result);
4705         }
4706
4707         if (have_flag(f_ptr->flags, FF_PERMANENT)) return feat;
4708
4709         return (feature_action_flags[action] & FAF_DESTROY) ? conv_dungeon_feat(f_ptr->destroyed) : feat;
4710 }
4711
4712 /*
4713  * Takes a location and action and changes the feature at that 
4714  * location through applying the given action.
4715  */
4716 void cave_alter_feat(int y, int x, int action)
4717 {
4718         /* Set old feature */
4719         int oldfeat = cave[y][x].feat;
4720
4721         /* Get the new feat */
4722         int newfeat = feat_state(oldfeat, action);
4723
4724         /* No change */
4725         if (newfeat == oldfeat) return;
4726
4727         /* Set the new feature */
4728         cave_set_feat(y, x, newfeat);
4729
4730         if (!(feature_action_flags[action] & FAF_NO_DROP))
4731         {
4732                 feature_type *old_f_ptr = &f_info[oldfeat];
4733                 feature_type *f_ptr = &f_info[newfeat];
4734                 bool found = FALSE;
4735
4736                 /* Handle gold */
4737                 if (have_flag(old_f_ptr->flags, FF_HAS_GOLD) && !have_flag(f_ptr->flags, FF_HAS_GOLD))
4738                 {
4739                         /* Place some gold */
4740                         place_gold(y, x);
4741                         found = TRUE;
4742                 }
4743
4744                 /* Handle item */
4745                 if (have_flag(old_f_ptr->flags, FF_HAS_ITEM) && !have_flag(f_ptr->flags, FF_HAS_ITEM) && (randint0(100) < (15 - dun_level / 2)))
4746                 {
4747                         /* Place object */
4748                         place_object(y, x, 0L);
4749                         found = TRUE;
4750                 }
4751
4752                 if (found && character_dungeon && player_can_see_bold(y, x))
4753                 {
4754 #ifdef JP
4755                         msg_print("²¿¤«¤òȯ¸«¤·¤¿¡ª");
4756 #else
4757                         msg_print("You have found something!");
4758 #endif
4759                 }
4760         }
4761
4762         if (feature_action_flags[action] & FAF_CRASH_GLASS)
4763         {
4764                 feature_type *old_f_ptr = &f_info[oldfeat];
4765
4766                 if (have_flag(old_f_ptr->flags, FF_GLASS) && character_dungeon)
4767                 {
4768                         project(PROJECT_WHO_GLASS_SHARDS, 1, y, x, MIN(dun_level, 100) / 4, GF_SHARDS,
4769                                 (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_HIDE | PROJECT_JUMP | PROJECT_NO_HANGEKI), -1);
4770                 }
4771         }
4772 }
4773
4774
4775 /* Remove a mirror */
4776 void remove_mirror(int y, int x)
4777 {
4778         cave_type *c_ptr = &cave[y][x];
4779
4780         /* Remove the mirror */
4781         c_ptr->info &= ~(CAVE_OBJECT);
4782         c_ptr->mimic = 0;
4783
4784         if (d_info[dungeon_type].flags1 & DF1_DARKNESS)
4785         {
4786                 c_ptr->info &= ~(CAVE_GLOW);
4787                 if (!view_torch_grids) c_ptr->info &= ~(CAVE_MARK);
4788
4789                 /* Update the monster */
4790                 if (c_ptr->m_idx) update_mon(c_ptr->m_idx, FALSE);
4791
4792                 update_local_illumination(y, x);
4793         }
4794
4795         /* Notice */
4796         note_spot(y, x);
4797
4798         /* Redraw */
4799         lite_spot(y, x);
4800 }
4801
4802
4803 /*
4804  *  Return TRUE if there is a mirror on the grid.
4805  */
4806 bool is_mirror_grid(cave_type *c_ptr)
4807 {
4808         if ((c_ptr->info & CAVE_OBJECT) && have_flag(f_info[c_ptr->mimic].flags, FF_MIRROR))
4809                 return TRUE;
4810         else
4811                 return FALSE;
4812 }
4813
4814
4815 /*
4816  *  Return TRUE if there is a mirror on the grid.
4817  */
4818 bool is_glyph_grid(cave_type *c_ptr)
4819 {
4820         if ((c_ptr->info & CAVE_OBJECT) && have_flag(f_info[c_ptr->mimic].flags, FF_GLYPH))
4821                 return TRUE;
4822         else
4823                 return FALSE;
4824 }
4825
4826
4827 /*
4828  *  Return TRUE if there is a mirror on the grid.
4829  */
4830 bool is_explosive_rune_grid(cave_type *c_ptr)
4831 {
4832         if ((c_ptr->info & CAVE_OBJECT) && have_flag(f_info[c_ptr->mimic].flags, FF_MINOR_GLYPH))
4833                 return TRUE;
4834         else
4835                 return FALSE;
4836 }
4837
4838
4839 /*
4840  * Calculate "incremental motion". Used by project() and shoot().
4841  * Assumes that (*y,*x) lies on the path from (y1,x1) to (y2,x2).
4842  */
4843 void mmove2(int *y, int *x, int y1, int x1, int y2, int x2)
4844 {
4845         int dy, dx, dist, shift;
4846
4847         /* Extract the distance travelled */
4848         dy = (*y < y1) ? y1 - *y : *y - y1;
4849         dx = (*x < x1) ? x1 - *x : *x - x1;
4850
4851         /* Number of steps */
4852         dist = (dy > dx) ? dy : dx;
4853
4854         /* We are calculating the next location */
4855         dist++;
4856
4857
4858         /* Calculate the total distance along each axis */
4859         dy = (y2 < y1) ? (y1 - y2) : (y2 - y1);
4860         dx = (x2 < x1) ? (x1 - x2) : (x2 - x1);
4861
4862         /* Paranoia -- Hack -- no motion */
4863         if (!dy && !dx) return;
4864
4865
4866         /* Move mostly vertically */
4867         if (dy > dx)
4868         {
4869                 /* Extract a shift factor */
4870                 shift = (dist * dx + (dy - 1) / 2) / dy;
4871
4872                 /* Sometimes move along the minor axis */
4873                 (*x) = (x2 < x1) ? (x1 - shift) : (x1 + shift);
4874
4875                 /* Always move along major axis */
4876                 (*y) = (y2 < y1) ? (y1 - dist) : (y1 + dist);
4877         }
4878
4879         /* Move mostly horizontally */
4880         else
4881         {
4882                 /* Extract a shift factor */
4883                 shift = (dist * dy + (dx - 1) / 2) / dx;
4884
4885                 /* Sometimes move along the minor axis */
4886                 (*y) = (y2 < y1) ? (y1 - shift) : (y1 + shift);
4887
4888                 /* Always move along major axis */
4889                 (*x) = (x2 < x1) ? (x1 - dist) : (x1 + dist);
4890         }
4891 }
4892
4893
4894
4895 /*
4896  * Determine if a bolt spell cast from (y1,x1) to (y2,x2) will arrive
4897  * at the final destination, assuming no monster gets in the way.
4898  *
4899  * This is slightly (but significantly) different from "los(y1,x1,y2,x2)".
4900  */
4901 bool projectable(int y1, int x1, int y2, int x2)
4902 {
4903         int y, x;
4904
4905         int grid_n = 0;
4906         u16b grid_g[512];
4907
4908         /* Check the projection path */
4909         grid_n = project_path(grid_g, (project_length ? project_length : MAX_RANGE), y1, x1, y2, x2, 0);
4910
4911         /* Identical grid */
4912         if (!grid_n) return TRUE;
4913
4914         /* Final grid */
4915         y = GRID_Y(grid_g[grid_n - 1]);
4916         x = GRID_X(grid_g[grid_n - 1]);
4917
4918         /* May not end in an unrequested grid */
4919         if ((y != y2) || (x != x2)) return (FALSE);
4920
4921         /* Assume okay */
4922         return (TRUE);
4923 }
4924
4925
4926 /*
4927  * Standard "find me a location" function
4928  *
4929  * Obtains a legal location within the given distance of the initial
4930  * location, and with "los()" from the source to destination location.
4931  *
4932  * This function is often called from inside a loop which searches for
4933  * locations while increasing the "d" distance.
4934  *
4935  * Currently the "m" parameter is unused.
4936  */
4937 void scatter(int *yp, int *xp, int y, int x, int d, int m)
4938 {
4939         int nx, ny;
4940
4941         /* Unused */
4942         m = m;
4943
4944         /* Pick a location */
4945         while (TRUE)
4946         {
4947                 /* Pick a new location */
4948                 ny = rand_spread(y, d);
4949                 nx = rand_spread(x, d);
4950
4951                 /* Ignore annoying locations */
4952                 if (!in_bounds(ny, nx)) continue;
4953
4954                 /* Ignore "excessively distant" locations */
4955                 if ((d > 1) && (distance(y, x, ny, nx) > d)) continue;
4956
4957                 /* Require "line of projection" */
4958                 if (projectable(y, x, ny, nx)) break;
4959         }
4960
4961         /* Save the location */
4962         (*yp) = ny;
4963         (*xp) = nx;
4964 }
4965
4966
4967
4968
4969 /*
4970  * Track a new monster
4971  */
4972 void health_track(int m_idx)
4973 {
4974         /* Mount monster is already tracked */
4975         if (m_idx && m_idx == p_ptr->riding) return;
4976
4977         /* Track a new guy */
4978         p_ptr->health_who = m_idx;
4979
4980         /* Redraw (later) */
4981         p_ptr->redraw |= (PR_HEALTH);
4982 }
4983
4984
4985
4986 /*
4987  * Hack -- track the given monster race
4988  */
4989 void monster_race_track(int r_idx)
4990 {
4991         /* Save this monster ID */
4992         p_ptr->monster_race_idx = r_idx;
4993
4994         /* Window stuff */
4995         p_ptr->window |= (PW_MONSTER);
4996 }
4997
4998
4999
5000 /*
5001  * Hack -- track the given object kind
5002  */
5003 void object_kind_track(int k_idx)
5004 {
5005         /* Save this monster ID */
5006         p_ptr->object_kind_idx = k_idx;
5007
5008         /* Window stuff */
5009         p_ptr->window |= (PW_OBJECT);
5010 }
5011
5012
5013
5014 /*
5015  * Something has happened to disturb the player.
5016  *
5017  * The first arg indicates a major disturbance, which affects search.
5018  *
5019  * The second arg is currently unused, but could induce output flush.
5020  *
5021  * All disturbance cancels repeated commands, resting, and running.
5022  */
5023 void disturb(int stop_search, int stop_travel)
5024 {
5025 #ifndef TRAVEL
5026         /* Unused */
5027         stop_travel = stop_travel;
5028 #endif
5029
5030         /* Cancel auto-commands */
5031         /* command_new = 0; */
5032
5033         /* Cancel repeated commands */
5034         if (command_rep)
5035         {
5036                 /* Cancel */
5037                 command_rep = 0;
5038
5039                 /* Redraw the state (later) */
5040                 p_ptr->redraw |= (PR_STATE);
5041         }
5042
5043         /* Cancel Resting */
5044         if ((p_ptr->action == ACTION_REST) || (p_ptr->action == ACTION_FISH) || (stop_search && (p_ptr->action == ACTION_SEARCH)))
5045         {
5046                 /* Cancel */
5047                 set_action(ACTION_NONE);
5048         }
5049
5050         /* Cancel running */
5051         if (running)
5052         {
5053                 /* Cancel */
5054                 running = 0;
5055
5056                 /* Check for new panel if appropriate */
5057                 if (center_player && !center_running) verify_panel();
5058
5059                 /* Calculate torch radius */
5060                 p_ptr->update |= (PU_TORCH);
5061
5062                 /* Update monster flow */
5063                 p_ptr->update |= (PU_FLOW);
5064         }
5065
5066 #ifdef TRAVEL
5067         if (stop_travel)
5068         {
5069                 /* Cancel */
5070                 travel.run = 0;
5071
5072                 /* Check for new panel if appropriate */
5073                 if (center_player && !center_running) verify_panel();
5074
5075                 /* Calculate torch radius */
5076                 p_ptr->update |= (PU_TORCH);
5077         }
5078 #endif
5079
5080         /* Flush the input if requested */
5081         if (flush_disturb) flush();
5082 }
5083
5084
5085 /*
5086  * Glow deep lava and building entrances in the floor
5087  */
5088 void glow_deep_lava_and_bldg(void)
5089 {
5090         int y, x, i, yy, xx;
5091         cave_type *c_ptr;
5092
5093         /* Not in the darkness dungeon */
5094         if (d_info[dungeon_type].flags1 & DF1_DARKNESS) return;
5095
5096         for (y = 0; y < cur_hgt; y++)
5097         {
5098                 for (x = 0; x < cur_wid; x++)
5099                 {
5100                         c_ptr = &cave[y][x];
5101
5102                         /* Feature code (applying "mimic" field) */
5103
5104                         if (have_flag(f_info[get_feat_mimic(c_ptr)].flags, FF_GLOW))
5105                         {
5106                                 for (i = 0; i < 9; i++)
5107                                 {
5108                                         yy = y + ddy_ddd[i];
5109                                         xx = x + ddx_ddd[i];
5110                                         if (!in_bounds2(yy, xx)) continue;
5111                                         cave[yy][xx].info |= CAVE_GLOW;
5112                                 }
5113                         }
5114                 }
5115         }
5116
5117         /* Update the view and lite */
5118         p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
5119
5120         /* Redraw map */
5121         p_ptr->redraw |= (PR_MAP);
5122 }