OSDN Git Service

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