5 #include "floor-events.h"
8 #include "monster-status.h"
10 #include "object-hook.h"
11 #include "player-move.h"
13 #include "player-effects.h"
15 static bool mon_invis;
16 static POSITION mon_fy, mon_fx;
21 msg_print(_("夜が明けた。", "The sun has risen."));
23 if (!p_ptr->wild_mode)
25 /* Hack -- Scan the town */
26 for (y = 0; y < current_floor_ptr->height; y++)
28 for (x = 0; x < current_floor_ptr->width; x++)
30 grid_type *g_ptr = ¤t_floor_ptr->grid_array[y][x];
33 g_ptr->info |= (CAVE_GLOW);
35 /* Hack -- Memorize lit grids if allowed */
36 if (view_perma_grids) g_ptr->info |= (CAVE_MARK);
38 /* Hack -- Notice spot */
44 p_ptr->update |= (PU_MONSTERS | PU_MON_LITE);
45 p_ptr->redraw |= (PR_MAP);
46 p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
48 if (p_ptr->special_defense & NINJA_S_STEALTH)
50 if (current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].info & CAVE_GLOW) set_superstealth(FALSE);
55 void night_falls(void)
58 msg_print(_("日が沈んだ。", "The sun has fallen."));
60 if (!p_ptr->wild_mode)
62 /* Hack -- Scan the town */
63 for (y = 0; y < current_floor_ptr->height; y++)
65 for (x = 0; x < current_floor_ptr->width; x++)
67 grid_type *g_ptr = ¤t_floor_ptr->grid_array[y][x];
69 /* Feature code (applying "mimic" field) */
70 feature_type *f_ptr = &f_info[get_feat_mimic(g_ptr)];
72 if (!is_mirror_grid(g_ptr) && !have_flag(f_ptr->flags, FF_QUEST_ENTER) &&
73 !have_flag(f_ptr->flags, FF_ENTRANCE))
76 g_ptr->info &= ~(CAVE_GLOW);
78 if (!have_flag(f_ptr->flags, FF_REMEMBER))
80 /* Forget the normal floor grid */
81 g_ptr->info &= ~(CAVE_MARK);
83 /* Hack -- Notice spot */
89 /* Glow deep lava and building entrances */
90 glow_deep_lava_and_bldg();
94 p_ptr->update |= (PU_MONSTERS | PU_MON_LITE);
95 p_ptr->redraw |= (PR_MAP);
96 p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
98 if (p_ptr->special_defense & NINJA_S_STEALTH)
100 if (current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].info & CAVE_GLOW) set_superstealth(FALSE);
106 * @brief 現在フロアに残っている敵モンスターの数を返す /
107 * @return 現在の敵モンスターの数
109 MONSTER_NUMBER count_all_hostile_monsters(void)
112 MONSTER_NUMBER number_mon = 0;
114 for (x = 0; x < current_floor_ptr->width; ++x)
116 for (y = 0; y < current_floor_ptr->height; ++y)
118 MONSTER_IDX m_idx = current_floor_ptr->grid_array[y][x].m_idx;
120 if (m_idx > 0 && is_hostile(¤t_floor_ptr->m_list[m_idx]))
133 * ダンジョンの雰囲気を計算するための非線形基準値 / Dungeon rating is no longer linear
135 #define RATING_BOOST(delta) (delta * delta + 50 * delta)
138 * @brief ダンジョンの雰囲気を算出する。
139 * / Examine all monsters and unidentified objects, and get the feeling of current dungeon floor
140 * @return 算出されたダンジョンの雰囲気ランク
142 byte get_dungeon_feeling(void)
148 /* Hack -- no feeling in the town */
149 if (!current_floor_ptr->dun_level) return 0;
151 /* Examine each monster */
152 for (i = 1; i < m_max; i++)
154 monster_type *m_ptr = ¤t_floor_ptr->m_list[i];
157 if (!monster_is_valid(m_ptr)) continue;
159 if (is_pet(m_ptr)) continue;
161 r_ptr = &r_info[m_ptr->r_idx];
163 if (r_ptr->flags1 & (RF1_UNIQUE))
165 /* Nearly out-of-depth unique monsters */
166 if (r_ptr->level + 10 > current_floor_ptr->dun_level)
168 /* Boost rating by twice delta-depth */
169 delta += (r_ptr->level + 10 - current_floor_ptr->dun_level) * 2 * base;
174 /* Out-of-depth monsters */
175 if (r_ptr->level > current_floor_ptr->dun_level)
177 /* Boost rating by delta-depth */
178 delta += (r_ptr->level - current_floor_ptr->dun_level) * base;
182 /* Unusually crowded monsters get a little bit of rating boost */
183 if (r_ptr->flags1 & RF1_FRIENDS)
185 if (5 <= get_monster_crowd_number(i)) delta += 1;
189 if (2 <= get_monster_crowd_number(i)) delta += 1;
193 rating += RATING_BOOST(delta);
196 /* Examine each unidentified object */
197 for (i = 1; i < o_max; i++)
199 object_type *o_ptr = ¤t_floor_ptr->o_list[i];
200 object_kind *k_ptr = &k_info[o_ptr->k_idx];
203 /* Skip dead objects */
204 if (!o_ptr->k_idx) continue;
206 /* Skip known objects */
207 if (object_is_known(o_ptr))
210 if (o_ptr->marked & OM_TOUCHED) continue;
213 /* Skip pseudo-known objects */
214 if (o_ptr->ident & IDENT_SENSE) continue;
217 if (object_is_ego(o_ptr))
219 ego_item_type *e_ptr = &e_info[o_ptr->name2];
221 delta += e_ptr->rating * base;
225 if (object_is_artifact(o_ptr))
227 PRICE cost = object_value_real(o_ptr);
230 if (cost > 10000L) delta += 10 * base;
231 if (cost > 50000L) delta += 10 * base;
232 if (cost > 100000L) delta += 10 * base;
234 /* Special feeling */
235 if (!preserve_mode) return 1;
238 if (o_ptr->tval == TV_DRAG_ARMOR) delta += 30 * base;
239 if (o_ptr->tval == TV_SHIELD && o_ptr->sval == SV_DRAGON_SHIELD) delta += 5 * base;
240 if (o_ptr->tval == TV_GLOVES && o_ptr->sval == SV_SET_OF_DRAGON_GLOVES) delta += 5 * base;
241 if (o_ptr->tval == TV_BOOTS && o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE) delta += 5 * base;
242 if (o_ptr->tval == TV_HELM && o_ptr->sval == SV_DRAGON_HELM) delta += 5 * base;
243 if (o_ptr->tval == TV_RING && o_ptr->sval == SV_RING_SPEED && !object_is_cursed(o_ptr)) delta += 25 * base;
244 if (o_ptr->tval == TV_RING && o_ptr->sval == SV_RING_LORDLY && !object_is_cursed(o_ptr)) delta += 15 * base;
245 if (o_ptr->tval == TV_AMULET && o_ptr->sval == SV_AMULET_THE_MAGI && !object_is_cursed(o_ptr)) delta += 15 * base;
247 /* Out-of-depth objects */
248 if (!object_is_cursed(o_ptr) && !object_is_broken(o_ptr) && k_ptr->level > current_floor_ptr->dun_level)
250 /* Rating increase */
251 delta += (k_ptr->level - current_floor_ptr->dun_level) * base;
254 rating += RATING_BOOST(delta);
258 if (rating > RATING_BOOST(1000)) return 2;
259 if (rating > RATING_BOOST(800)) return 3;
260 if (rating > RATING_BOOST(600)) return 4;
261 if (rating > RATING_BOOST(400)) return 5;
262 if (rating > RATING_BOOST(300)) return 6;
263 if (rating > RATING_BOOST(200)) return 7;
264 if (rating > RATING_BOOST(100)) return 8;
265 if (rating > RATING_BOOST(0)) return 9;
271 * @brief ダンジョンの雰囲気を更新し、変化があった場合メッセージを表示する
272 * / Update dungeon feeling, and announce it if changed
275 void update_dungeon_feeling(void)
281 /* No feeling on the surface */
282 if (!current_floor_ptr->dun_level) return;
284 /* No feeling in the arena */
285 if (p_ptr->inside_battle) return;
287 /* Extract delay time */
288 delay = MAX(10, 150 - p_ptr->skill_fos) * (150 - current_floor_ptr->dun_level) * TURNS_PER_TICK / 100;
290 /* Not yet felt anything */
291 if (current_world_ptr->game_turn < p_ptr->feeling_turn + delay && !cheat_xtra) return;
293 /* Extract quest number (if any) */
294 quest_num = quest_number(current_floor_ptr->dun_level);
296 /* No feeling in a quest */
298 (is_fixed_quest_idx(quest_num) &&
299 !((quest_num == QUEST_OBERON) || (quest_num == QUEST_SERPENT) ||
300 !(quest[quest_num].flags & QUEST_FLAG_PRESET)))) return;
303 /* Get new dungeon feeling */
304 new_feeling = get_dungeon_feeling();
306 /* Remember last time updated */
307 p_ptr->feeling_turn = current_world_ptr->game_turn;
310 if (p_ptr->feeling == new_feeling) return;
312 /* Dungeon feeling is changed */
313 p_ptr->feeling = new_feeling;
315 /* Announce feeling */
318 select_floor_music();
320 /* Update the level indicator */
321 p_ptr->redraw |= (PR_DEPTH);
323 if (disturb_minor) disturb(FALSE, FALSE);
328 * Glow deep lava and building entrances in the floor
330 void glow_deep_lava_and_bldg(void)
332 POSITION y, x, yy, xx;
336 /* Not in the darkness dungeon */
337 if (d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS) return;
339 for (y = 0; y < current_floor_ptr->height; y++)
341 for (x = 0; x < current_floor_ptr->width; x++)
343 g_ptr = ¤t_floor_ptr->grid_array[y][x];
345 /* Feature code (applying "mimic" field) */
347 if (have_flag(f_info[get_feat_mimic(g_ptr)].flags, FF_GLOW))
349 for (i = 0; i < 9; i++)
353 if (!in_bounds2(yy, xx)) continue;
354 current_floor_ptr->grid_array[yy][xx].info |= CAVE_GLOW;
360 /* Update the view and lite */
361 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
363 p_ptr->redraw |= (PR_MAP);
367 * Actually erase the entire "lite" array, redrawing every grid
369 void forget_lite(void)
375 if (!current_floor_ptr->lite_n) return;
378 for (i = 0; i < current_floor_ptr->lite_n; i++)
380 y = current_floor_ptr->lite_y[i];
381 x = current_floor_ptr->lite_x[i];
383 /* Forget "LITE" flag */
384 current_floor_ptr->grid_array[y][x].info &= ~(CAVE_LITE);
386 /* lite_spot(y, x); Perhaps don't need? */
390 current_floor_ptr->lite_n = 0;
396 * Update the set of grids "illuminated" by the player's lite.
398 * This routine needs to use the results of "update_view()"
400 * Note that "blindness" does NOT affect "torch lite". Be careful!
402 * We optimize most lites (all non-artifact lites) by using "obvious"
403 * facts about the results of "small" lite radius, and we attempt to
404 * list the "nearby" grids before the more "distant" ones in the
405 * array of torch-lit grids.
407 * We assume that "radius zero" lite is in fact no lite at all.
409 * Torch Lantern Artifacts
419 void update_lite(void)
422 POSITION x, y, min_x, max_x, min_y, max_y;
423 POSITION p = p_ptr->cur_lite;
426 /*** Special case ***/
429 /* Hack -- Player has no lite */
432 /* Forget the old lite */
433 /* forget_lite(); Perhaps don't need? */
435 /* Add it to later visual update */
436 cave_redraw_later(¤t_floor_ptr->grid_array[p_ptr->y][p_ptr->x], p_ptr->y, p_ptr->x);
440 /*** Save the old "lite" grids for later ***/
443 for (i = 0; i < current_floor_ptr->lite_n; i++)
445 y = current_floor_ptr->lite_y[i];
446 x = current_floor_ptr->lite_x[i];
448 /* Mark the grid as not "lite" */
449 current_floor_ptr->grid_array[y][x].info &= ~(CAVE_LITE);
451 /* Mark the grid as "seen" */
452 current_floor_ptr->grid_array[y][x].info |= (CAVE_TEMP);
454 /* Add it to the "seen" set */
455 tmp_pos.y[tmp_pos.n] = y;
456 tmp_pos.x[tmp_pos.n] = x;
461 current_floor_ptr->lite_n = 0;
464 /*** Collect the new "lite" grids ***/
466 /* Radius 1 -- torch radius */
470 cave_lite_hack(p_ptr->y, p_ptr->x);
473 cave_lite_hack(p_ptr->y + 1, p_ptr->x);
474 cave_lite_hack(p_ptr->y - 1, p_ptr->x);
475 cave_lite_hack(p_ptr->y, p_ptr->x + 1);
476 cave_lite_hack(p_ptr->y, p_ptr->x - 1);
479 cave_lite_hack(p_ptr->y + 1, p_ptr->x + 1);
480 cave_lite_hack(p_ptr->y + 1, p_ptr->x - 1);
481 cave_lite_hack(p_ptr->y - 1, p_ptr->x + 1);
482 cave_lite_hack(p_ptr->y - 1, p_ptr->x - 1);
485 /* Radius 2 -- lantern radius */
488 /* South of the player */
489 if (cave_los_bold(p_ptr->y + 1, p_ptr->x))
491 cave_lite_hack(p_ptr->y + 2, p_ptr->x);
492 cave_lite_hack(p_ptr->y + 2, p_ptr->x + 1);
493 cave_lite_hack(p_ptr->y + 2, p_ptr->x - 1);
496 /* North of the player */
497 if (cave_los_bold(p_ptr->y - 1, p_ptr->x))
499 cave_lite_hack(p_ptr->y - 2, p_ptr->x);
500 cave_lite_hack(p_ptr->y - 2, p_ptr->x + 1);
501 cave_lite_hack(p_ptr->y - 2, p_ptr->x - 1);
504 /* East of the player */
505 if (cave_los_bold(p_ptr->y, p_ptr->x + 1))
507 cave_lite_hack(p_ptr->y, p_ptr->x + 2);
508 cave_lite_hack(p_ptr->y + 1, p_ptr->x + 2);
509 cave_lite_hack(p_ptr->y - 1, p_ptr->x + 2);
512 /* West of the player */
513 if (cave_los_bold(p_ptr->y, p_ptr->x - 1))
515 cave_lite_hack(p_ptr->y, p_ptr->x - 2);
516 cave_lite_hack(p_ptr->y + 1, p_ptr->x - 2);
517 cave_lite_hack(p_ptr->y - 1, p_ptr->x - 2);
521 /* Radius 3+ -- artifact radius */
526 /* Paranoia -- see "LITE_MAX" */
529 /* South-East of the player */
530 if (cave_los_bold(p_ptr->y + 1, p_ptr->x + 1))
532 cave_lite_hack(p_ptr->y + 2, p_ptr->x + 2);
535 /* South-West of the player */
536 if (cave_los_bold(p_ptr->y + 1, p_ptr->x - 1))
538 cave_lite_hack(p_ptr->y + 2, p_ptr->x - 2);
541 /* North-East of the player */
542 if (cave_los_bold(p_ptr->y - 1, p_ptr->x + 1))
544 cave_lite_hack(p_ptr->y - 2, p_ptr->x + 2);
547 /* North-West of the player */
548 if (cave_los_bold(p_ptr->y - 1, p_ptr->x - 1))
550 cave_lite_hack(p_ptr->y - 2, p_ptr->x - 2);
554 min_y = p_ptr->y - p;
555 if (min_y < 0) min_y = 0;
558 max_y = p_ptr->y + p;
559 if (max_y > current_floor_ptr->height - 1) max_y = current_floor_ptr->height - 1;
562 min_x = p_ptr->x - p;
563 if (min_x < 0) min_x = 0;
566 max_x = p_ptr->x + p;
567 if (max_x > current_floor_ptr->width - 1) max_x = current_floor_ptr->width - 1;
569 /* Scan the maximal box */
570 for (y = min_y; y <= max_y; y++)
572 for (x = min_x; x <= max_x; x++)
574 int dy = (p_ptr->y > y) ? (p_ptr->y - y) : (y - p_ptr->y);
575 int dx = (p_ptr->x > x) ? (p_ptr->x - x) : (x - p_ptr->x);
577 /* Skip the "central" grids (above) */
578 if ((dy <= 2) && (dx <= 2)) continue;
580 /* Hack -- approximate the distance */
581 d = (dy > dx) ? (dy + (dx >> 1)) : (dx + (dy >> 1));
583 /* Skip distant grids */
586 /* Viewable, nearby, grids get "torch lit" */
587 if (current_floor_ptr->grid_array[y][x].info & CAVE_VIEW)
589 /* This grid is "torch lit" */
590 cave_lite_hack(y, x);
597 /*** Complete the algorithm ***/
599 /* Draw the new grids */
600 for (i = 0; i < current_floor_ptr->lite_n; i++)
602 y = current_floor_ptr->lite_y[i];
603 x = current_floor_ptr->lite_x[i];
605 g_ptr = ¤t_floor_ptr->grid_array[y][x];
607 /* Update fresh grids */
608 if (g_ptr->info & (CAVE_TEMP)) continue;
610 /* Add it to later visual update */
611 cave_note_and_redraw_later(g_ptr, y, x);
615 for (i = 0; i < tmp_pos.n; i++)
620 g_ptr = ¤t_floor_ptr->grid_array[y][x];
622 /* No longer in the array */
623 g_ptr->info &= ~(CAVE_TEMP);
625 /* Update stale grids */
626 if (g_ptr->info & (CAVE_LITE)) continue;
628 /* Add it to later visual update */
629 cave_redraw_later(g_ptr, y, x);
635 /* Mega-Hack -- Visual update later */
636 p_ptr->update |= (PU_DELAY_VIS);
641 * Clear the viewable space
643 void forget_view(void)
650 if (!current_floor_ptr->view_n) return;
653 for (i = 0; i < current_floor_ptr->view_n; i++)
655 POSITION y = current_floor_ptr->view_y[i];
656 POSITION x = current_floor_ptr->view_x[i];
657 g_ptr = ¤t_floor_ptr->grid_array[y][x];
659 /* Forget that the grid is viewable */
660 g_ptr->info &= ~(CAVE_VIEW);
662 /* if (!panel_contains(y, x)) continue; */
664 /* Update the screen */
665 /* lite_spot(y, x); Perhaps don't need? */
669 current_floor_ptr->view_n = 0;
675 * Helper function for "update_view()" below
677 * We are checking the "viewability" of grid (y,x) by the player.
679 * This function assumes that (y,x) is legal (i.e. on the map).
681 * Grid (y1,x1) is on the "diagonal" between (p_ptr->y,p_ptr->x) and (y,x)
682 * Grid (y2,x2) is "adjacent", also between (p_ptr->y,p_ptr->x) and (y,x).
684 * Note that we are using the "CAVE_XTRA" field for marking grids as
685 * "easily viewable". This bit is cleared at the end of "update_view()".
687 * This function adds (y,x) to the "viewable set" if necessary.
689 * This function now returns "TRUE" if vision is "blocked" by grid (y,x).
691 static bool update_view_aux(POSITION y, POSITION x, POSITION y1, POSITION x1, POSITION y2, POSITION x2)
693 bool f1, f2, v1, v2, z1, z2, wall;
700 /* Access the grids */
701 g1_c_ptr = ¤t_floor_ptr->grid_array[y1][x1];
702 g2_c_ptr = ¤t_floor_ptr->grid_array[y2][x2];
705 /* Check for walls */
706 f1 = (cave_los_grid(g1_c_ptr));
707 f2 = (cave_los_grid(g2_c_ptr));
709 /* Totally blocked by physical walls */
710 if (!f1 && !f2) return (TRUE);
713 /* Check for visibility */
714 v1 = (f1 && (g1_c_ptr->info & (CAVE_VIEW)));
715 v2 = (f2 && (g2_c_ptr->info & (CAVE_VIEW)));
717 /* Totally blocked by "unviewable neighbors" */
718 if (!v1 && !v2) return (TRUE);
720 g_ptr = ¤t_floor_ptr->grid_array[y][x];
723 /* Check for walls */
724 wall = (!cave_los_grid(g_ptr));
727 /* Check the "ease" of visibility */
728 z1 = (v1 && (g1_c_ptr->info & (CAVE_XTRA)));
729 z2 = (v2 && (g2_c_ptr->info & (CAVE_XTRA)));
731 /* Hack -- "easy" plus "easy" yields "easy" */
734 g_ptr->info |= (CAVE_XTRA);
736 cave_view_hack(g_ptr, y, x);
741 /* Hack -- primary "easy" yields "viewed" */
744 cave_view_hack(g_ptr, y, x);
749 /* Hack -- "view" plus "view" yields "view" */
752 /* g_ptr->info |= (CAVE_XTRA); */
754 cave_view_hack(g_ptr, y, x);
760 /* Mega-Hack -- the "los()" function works poorly on walls */
763 cave_view_hack(g_ptr, y, x);
769 /* Hack -- check line of sight */
770 if (los(p_ptr->y, p_ptr->x, y, x))
772 cave_view_hack(g_ptr, y, x);
778 /* Assume no line of sight. */
784 * Calculate the viewable space
786 * 1: Process the player
787 * 1a: The player is always (easily) viewable
788 * 2: Process the diagonals
789 * 2a: The diagonals are (easily) viewable up to the first wall
790 * 2b: But never go more than 2/3 of the "full" distance
791 * 3: Process the main axes
792 * 3a: The main axes are (easily) viewable up to the first wall
793 * 3b: But never go more than the "full" distance
794 * 4: Process sequential "strips" in each of the eight octants
795 * 4a: Each strip runs along the previous strip
796 * 4b: The main axes are "previous" to the first strip
797 * 4c: Process both "sides" of each "direction" of each strip
798 * 4c1: Each side aborts as soon as possible
799 * 4c2: Each side tells the next strip how far it has to check
801 * Note that the octant processing involves some pretty interesting
802 * observations involving when a grid might possibly be viewable from
803 * a given grid, and on the order in which the strips are processed.
805 * Note the use of the mathematical facts shown below, which derive
806 * from the fact that (1 < sqrt(2) < 1.5), and that the length of the
807 * hypotenuse of a right triangle is primarily determined by the length
808 * of the longest side, when one side is small, and is strictly less
809 * than one-and-a-half times as long as the longest side when both of
810 * the sides are large.
812 * if (manhatten(dy,dx) < R) then (hypot(dy,dx) < R)
813 * if (manhatten(dy,dx) > R*3/2) then (hypot(dy,dx) > R)
815 * hypot(dy,dx) is approximated by (dx+dy+MAX(dx,dy)) / 2
817 * These observations are important because the calculation of the actual
818 * value of "hypot(dx,dy)" is extremely expensive, involving square roots,
819 * while for small values (up to about 20 or so), the approximations above
820 * are correct to within an error of at most one grid or so.
822 * Observe the use of "full" and "over" in the code below, and the use of
823 * the specialized calculation involving "limit", all of which derive from
824 * the observations given above. Basically, we note that the "circle" of
825 * view is completely contained in an "octagon" whose bounds are easy to
826 * determine, and that only a few steps are needed to derive the actual
827 * bounds of the circle given the bounds of the octagon.
829 * Note that by skipping all the grids in the corners of the octagon, we
830 * place an upper limit on the number of grids in the field of view, given
831 * that "full" is never more than 20. Of the 1681 grids in the "square" of
832 * view, only about 1475 of these are in the "octagon" of view, and even
833 * fewer are in the "circle" of view, so 1500 or 1536 is more than enough
834 * entries to completely contain the actual field of view.
836 * Note also the care taken to prevent "running off the map". The use of
837 * explicit checks on the "validity" of the "diagonal", and the fact that
838 * the loops are never allowed to "leave" the map, lets "update_view_aux()"
839 * use the optimized "cave_los_bold()" macro, and to avoid the overhead
840 * of multiple checks on the validity of grids.
842 * Note the "optimizations" involving the "se","sw","ne","nw","es","en",
843 * "ws","wn" variables. They work like this: While travelling down the
844 * south-bound strip just to the east of the main south axis, as soon as
845 * we get to a grid which does not "transmit" viewing, if all of the strips
846 * preceding us (in this case, just the main axis) had terminated at or before
847 * the same point, then we can stop, and reset the "max distance" to ourself.
848 * So, each strip (named by major axis plus offset, thus "se" in this case)
849 * maintains a "blockage" variable, initialized during the main axis step,
850 * and checks it whenever a blockage is observed. After processing each
851 * strip as far as the previous strip told us to process, the next strip is
852 * told not to go farther than the current strip's farthest viewable grid,
853 * unless open space is still available. This uses the "k" variable.
855 * Note the use of "inline" macros for efficiency. The "cave_los_grid()"
856 * macro is a replacement for "cave_los_bold()" which takes a pointer to
857 * a grid instead of its location. The "cave_view_hack()" macro is a
858 * chunk of code which adds the given location to the "view" array if it
859 * is not already there, using both the actual location and a pointer to
860 * the grid. See above.
862 * By the way, the purpose of this code is to reduce the dependancy on the
863 * "los()" function which is slow, and, in some cases, not very accurate.
865 * It is very possible that I am the only person who fully understands this
866 * function, and for that I am truly sorry, but efficiency was very important
867 * and the "simple" version of this function was just not fast enough. I am
868 * more than willing to replace this function with a simpler one, if it is
869 * equally efficient, and especially willing if the new function happens to
870 * derive "reverse-line-of-sight" at the same time, since currently monsters
871 * just use an optimized hack of "you see me, so I see you", and then use the
872 * actual "projectable()" function to check spell attacks.
874 void update_view(void)
879 int se, sw, ne, nw, es, en, ws, wn;
883 POSITION y_max = current_floor_ptr->height - 1;
884 POSITION x_max = current_floor_ptr->width - 1;
891 if (view_reduce_view && !current_floor_ptr->dun_level)
893 /* Full radius (10) */
894 full = MAX_SIGHT / 2;
896 /* Octagon factor (15) */
897 over = MAX_SIGHT * 3 / 4;
903 /* Full radius (20) */
906 /* Octagon factor (30) */
907 over = MAX_SIGHT * 3 / 2;
911 /*** Step 0 -- Begin ***/
913 /* Save the old "view" grids for later */
914 for (n = 0; n < current_floor_ptr->view_n; n++)
916 y = current_floor_ptr->view_y[n];
917 x = current_floor_ptr->view_x[n];
918 g_ptr = ¤t_floor_ptr->grid_array[y][x];
920 /* Mark the grid as not in "view" */
921 g_ptr->info &= ~(CAVE_VIEW);
923 /* Mark the grid as "seen" */
924 g_ptr->info |= (CAVE_TEMP);
926 /* Add it to the "seen" set */
927 tmp_pos.y[tmp_pos.n] = y;
928 tmp_pos.x[tmp_pos.n] = x;
932 /* Start over with the "view" array */
933 current_floor_ptr->view_n = 0;
935 /*** Step 1 -- adjacent grids ***/
937 /* Now start on the player */
940 g_ptr = ¤t_floor_ptr->grid_array[y][x];
942 /* Assume the player grid is easily viewable */
943 g_ptr->info |= (CAVE_XTRA);
945 /* Assume the player grid is viewable */
946 cave_view_hack(g_ptr, y, x);
949 /*** Step 2 -- Major Diagonals ***/
954 /* Scan south-east */
955 for (d = 1; d <= z; d++)
957 g_ptr = ¤t_floor_ptr->grid_array[y + d][x + d];
958 g_ptr->info |= (CAVE_XTRA);
959 cave_view_hack(g_ptr, y + d, x + d);
960 if (!cave_los_grid(g_ptr)) break;
963 /* Scan south-west */
964 for (d = 1; d <= z; d++)
966 g_ptr = ¤t_floor_ptr->grid_array[y + d][x - d];
967 g_ptr->info |= (CAVE_XTRA);
968 cave_view_hack(g_ptr, y + d, x - d);
969 if (!cave_los_grid(g_ptr)) break;
972 /* Scan north-east */
973 for (d = 1; d <= z; d++)
975 g_ptr = ¤t_floor_ptr->grid_array[y - d][x + d];
976 g_ptr->info |= (CAVE_XTRA);
977 cave_view_hack(g_ptr, y - d, x + d);
978 if (!cave_los_grid(g_ptr)) break;
981 /* Scan north-west */
982 for (d = 1; d <= z; d++)
984 g_ptr = ¤t_floor_ptr->grid_array[y - d][x - d];
985 g_ptr->info |= (CAVE_XTRA);
986 cave_view_hack(g_ptr, y - d, x - d);
987 if (!cave_los_grid(g_ptr)) break;
990 /*** Step 3 -- major axes ***/
993 for (d = 1; d <= full; d++)
995 g_ptr = ¤t_floor_ptr->grid_array[y + d][x];
996 g_ptr->info |= (CAVE_XTRA);
997 cave_view_hack(g_ptr, y + d, x);
998 if (!cave_los_grid(g_ptr)) break;
1001 /* Initialize the "south strips" */
1005 for (d = 1; d <= full; d++)
1007 g_ptr = ¤t_floor_ptr->grid_array[y - d][x];
1008 g_ptr->info |= (CAVE_XTRA);
1009 cave_view_hack(g_ptr, y - d, x);
1010 if (!cave_los_grid(g_ptr)) break;
1013 /* Initialize the "north strips" */
1017 for (d = 1; d <= full; d++)
1019 g_ptr = ¤t_floor_ptr->grid_array[y][x + d];
1020 g_ptr->info |= (CAVE_XTRA);
1021 cave_view_hack(g_ptr, y, x + d);
1022 if (!cave_los_grid(g_ptr)) break;
1025 /* Initialize the "east strips" */
1029 for (d = 1; d <= full; d++)
1031 g_ptr = ¤t_floor_ptr->grid_array[y][x - d];
1032 g_ptr->info |= (CAVE_XTRA);
1033 cave_view_hack(g_ptr, y, x - d);
1034 if (!cave_los_grid(g_ptr)) break;
1037 /* Initialize the "west strips" */
1041 /*** Step 4 -- Divide each "octant" into "strips" ***/
1043 /* Now check each "diagonal" (in parallel) */
1044 for (n = 1; n <= over / 2; n++)
1046 POSITION ypn, ymn, xpn, xmn;
1048 /* Acquire the "bounds" of the maximal circle */
1050 if (z > full - n) z = full - n;
1051 while ((z + n + (n >> 1)) > full) z--;
1054 /* Access the four diagonal grids */
1064 /* Maximum distance */
1065 m = MIN(z, y_max - ypn);
1068 if ((xpn <= x_max) && (n < se))
1071 for (k = n, d = 1; d <= m; d++)
1073 /* Check grid "d" in strip "n", notice "blockage" */
1074 if (update_view_aux(ypn + d, xpn, ypn + d - 1, xpn - 1, ypn + d - 1, xpn))
1076 if (n + d >= se) break;
1079 /* Track most distant "non-blockage" */
1086 /* Limit the next strip */
1091 if ((xmn >= 0) && (n < sw))
1094 for (k = n, d = 1; d <= m; d++)
1096 /* Check grid "d" in strip "n", notice "blockage" */
1097 if (update_view_aux(ypn + d, xmn, ypn + d - 1, xmn + 1, ypn + d - 1, xmn))
1099 if (n + d >= sw) break;
1102 /* Track most distant "non-blockage" */
1109 /* Limit the next strip */
1118 /* Maximum distance */
1122 if ((xpn <= x_max) && (n < ne))
1125 for (k = n, d = 1; d <= m; d++)
1127 /* Check grid "d" in strip "n", notice "blockage" */
1128 if (update_view_aux(ymn - d, xpn, ymn - d + 1, xpn - 1, ymn - d + 1, xpn))
1130 if (n + d >= ne) break;
1133 /* Track most distant "non-blockage" */
1140 /* Limit the next strip */
1145 if ((xmn >= 0) && (n < nw))
1148 for (k = n, d = 1; d <= m; d++)
1150 /* Check grid "d" in strip "n", notice "blockage" */
1151 if (update_view_aux(ymn - d, xmn, ymn - d + 1, xmn + 1, ymn - d + 1, xmn))
1153 if (n + d >= nw) break;
1156 /* Track most distant "non-blockage" */
1163 /* Limit the next strip */
1172 /* Maximum distance */
1173 m = MIN(z, x_max - xpn);
1176 if ((ypn <= x_max) && (n < es))
1179 for (k = n, d = 1; d <= m; d++)
1181 /* Check grid "d" in strip "n", notice "blockage" */
1182 if (update_view_aux(ypn, xpn + d, ypn - 1, xpn + d - 1, ypn, xpn + d - 1))
1184 if (n + d >= es) break;
1187 /* Track most distant "non-blockage" */
1194 /* Limit the next strip */
1199 if ((ymn >= 0) && (n < en))
1202 for (k = n, d = 1; d <= m; d++)
1204 /* Check grid "d" in strip "n", notice "blockage" */
1205 if (update_view_aux(ymn, xpn + d, ymn + 1, xpn + d - 1, ymn, xpn + d - 1))
1207 if (n + d >= en) break;
1210 /* Track most distant "non-blockage" */
1217 /* Limit the next strip */
1226 /* Maximum distance */
1230 if ((ypn <= y_max) && (n < ws))
1233 for (k = n, d = 1; d <= m; d++)
1235 /* Check grid "d" in strip "n", notice "blockage" */
1236 if (update_view_aux(ypn, xmn - d, ypn - 1, xmn - d + 1, ypn, xmn - d + 1))
1238 if (n + d >= ws) break;
1241 /* Track most distant "non-blockage" */
1248 /* Limit the next strip */
1253 if ((ymn >= 0) && (n < wn))
1256 for (k = n, d = 1; d <= m; d++)
1258 /* Check grid "d" in strip "n", notice "blockage" */
1259 if (update_view_aux(ymn, xmn - d, ymn + 1, xmn - d + 1, ymn, xmn - d + 1))
1261 if (n + d >= wn) break;
1264 /* Track most distant "non-blockage" */
1271 /* Limit the next strip */
1278 /*** Step 5 -- Complete the algorithm ***/
1280 /* Update all the new grids */
1281 for (n = 0; n < current_floor_ptr->view_n; n++)
1283 y = current_floor_ptr->view_y[n];
1284 x = current_floor_ptr->view_x[n];
1285 g_ptr = ¤t_floor_ptr->grid_array[y][x];
1287 /* Clear the "CAVE_XTRA" flag */
1288 g_ptr->info &= ~(CAVE_XTRA);
1290 /* Update only newly viewed grids */
1291 if (g_ptr->info & (CAVE_TEMP)) continue;
1293 /* Add it to later visual update */
1294 cave_note_and_redraw_later(g_ptr, y, x);
1297 /* Wipe the old grids, update as needed */
1298 for (n = 0; n < tmp_pos.n; n++)
1302 g_ptr = ¤t_floor_ptr->grid_array[y][x];
1304 /* No longer in the array */
1305 g_ptr->info &= ~(CAVE_TEMP);
1307 /* Update only non-viewable grids */
1308 if (g_ptr->info & (CAVE_VIEW)) continue;
1310 /* Add it to later visual update */
1311 cave_redraw_later(g_ptr, y, x);
1317 /* Mega-Hack -- Visual update later */
1318 p_ptr->update |= (PU_DELAY_VIS);
1323 * Add a square to the changes array
1325 static void mon_lite_hack(POSITION y, POSITION x)
1331 /* We trust this grid is in bounds */
1332 /* if (!in_bounds2(y, x)) return; */
1334 g_ptr = ¤t_floor_ptr->grid_array[y][x];
1336 /* Want a unlit square in view of the player */
1337 if ((g_ptr->info & (CAVE_MNLT | CAVE_VIEW)) != CAVE_VIEW) return;
1339 if (!cave_los_grid(g_ptr))
1341 /* Hack -- Prevent monster lite leakage in walls */
1343 /* Horizontal walls between player and a monster */
1344 if (((y < p_ptr->y) && (y > mon_fy)) || ((y > p_ptr->y) && (y < mon_fy)))
1346 dpf = p_ptr->y - mon_fy;
1348 midpoint = mon_fx + ((p_ptr->x - mon_fx) * ABS(d)) / ABS(dpf);
1350 /* Only first wall viewed from mid-x is lit */
1353 if (!cave_los_bold(y, x + 1)) return;
1355 else if (x > midpoint)
1357 if (!cave_los_bold(y, x - 1)) return;
1360 /* Hack XXX XXX - Is it a wall and monster not in LOS? */
1361 else if (mon_invis) return;
1364 /* Vertical walls between player and a monster */
1365 if (((x < p_ptr->x) && (x > mon_fx)) || ((x > p_ptr->x) && (x < mon_fx)))
1367 dpf = p_ptr->x - mon_fx;
1369 midpoint = mon_fy + ((p_ptr->y - mon_fy) * ABS(d)) / ABS(dpf);
1371 /* Only first wall viewed from mid-y is lit */
1374 if (!cave_los_bold(y + 1, x)) return;
1376 else if (y > midpoint)
1378 if (!cave_los_bold(y - 1, x)) return;
1381 /* Hack XXX XXX - Is it a wall and monster not in LOS? */
1382 else if (mon_invis) return;
1386 /* We trust tmp_pos.n does not exceed TEMP_MAX */
1389 if (!(g_ptr->info & CAVE_MNDK))
1391 /* Save this square */
1392 tmp_pos.x[tmp_pos.n] = x;
1393 tmp_pos.y[tmp_pos.n] = y;
1400 /* No longer dark */
1401 g_ptr->info &= ~(CAVE_MNDK);
1405 g_ptr->info |= CAVE_MNLT;
1410 * Add a square to the changes array
1412 static void mon_dark_hack(POSITION y, POSITION x)
1415 int midpoint, dpf, d;
1417 /* We trust this grid is in bounds */
1418 /* if (!in_bounds2(y, x)) return; */
1420 g_ptr = ¤t_floor_ptr->grid_array[y][x];
1422 /* Want a unlit and undarkened square in view of the player */
1423 if ((g_ptr->info & (CAVE_LITE | CAVE_MNLT | CAVE_MNDK | CAVE_VIEW)) != CAVE_VIEW) return;
1425 if (!cave_los_grid(g_ptr) && !cave_have_flag_grid(g_ptr, FF_PROJECT))
1427 /* Hack -- Prevent monster dark lite leakage in walls */
1429 /* Horizontal walls between player and a monster */
1430 if (((y < p_ptr->y) && (y > mon_fy)) || ((y > p_ptr->y) && (y < mon_fy)))
1432 dpf = p_ptr->y - mon_fy;
1434 midpoint = mon_fx + ((p_ptr->x - mon_fx) * ABS(d)) / ABS(dpf);
1436 /* Only first wall viewed from mid-x is lit */
1439 if (!cave_los_bold(y, x + 1) && !cave_have_flag_bold(y, x + 1, FF_PROJECT)) return;
1441 else if (x > midpoint)
1443 if (!cave_los_bold(y, x - 1) && !cave_have_flag_bold(y, x - 1, FF_PROJECT)) return;
1446 /* Hack XXX XXX - Is it a wall and monster not in LOS? */
1447 else if (mon_invis) return;
1450 /* Vertical walls between player and a monster */
1451 if (((x < p_ptr->x) && (x > mon_fx)) || ((x > p_ptr->x) && (x < mon_fx)))
1453 dpf = p_ptr->x - mon_fx;
1455 midpoint = mon_fy + ((p_ptr->y - mon_fy) * ABS(d)) / ABS(dpf);
1457 /* Only first wall viewed from mid-y is lit */
1460 if (!cave_los_bold(y + 1, x) && !cave_have_flag_bold(y + 1, x, FF_PROJECT)) return;
1462 else if (y > midpoint)
1464 if (!cave_los_bold(y - 1, x) && !cave_have_flag_bold(y - 1, x, FF_PROJECT)) return;
1467 /* Hack XXX XXX - Is it a wall and monster not in LOS? */
1468 else if (mon_invis) return;
1472 /* We trust tmp_pos.n does not exceed TEMP_MAX */
1474 /* Save this square */
1475 tmp_pos.x[tmp_pos.n] = x;
1476 tmp_pos.y[tmp_pos.n] = y;
1480 g_ptr->info |= CAVE_MNDK;
1484 * Update squares illuminated or darkened by monsters.
1486 * Hack - use the CAVE_ROOM flag (renamed to be CAVE_MNLT) to
1487 * denote squares illuminated by monsters.
1489 * The CAVE_TEMP and CAVE_XTRA flag are used to store the state during the
1490 * updating. Only squares in view of the player, whos state
1491 * changes are drawn via lite_spot().
1493 void update_mon_lite(void)
1499 void(*add_mon_lite)(POSITION, POSITION);
1504 /* Non-Ninja player in the darkness */
1505 int dis_lim = ((d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS) && !p_ptr->see_nocto) ?
1506 (MAX_SIGHT / 2 + 1) : (MAX_SIGHT + 3);
1508 /* Clear all monster lit squares */
1509 for (i = 0; i < current_floor_ptr->mon_lite_n; i++)
1512 g_ptr = ¤t_floor_ptr->grid_array[current_floor_ptr->mon_lite_y[i]][current_floor_ptr->mon_lite_x[i]];
1514 /* Set temp or xtra flag */
1515 g_ptr->info |= (g_ptr->info & CAVE_MNLT) ? CAVE_TEMP : CAVE_XTRA;
1517 /* Clear monster illumination flag */
1518 g_ptr->info &= ~(CAVE_MNLT | CAVE_MNDK);
1521 /* Empty temp list of new squares to lite up */
1524 /* If a monster stops time, don't process */
1525 if (!current_world_ptr->timewalk_m_idx)
1527 monster_type *m_ptr;
1528 monster_race *r_ptr;
1530 /* Loop through monsters, adding newly lit squares to changes list */
1531 for (i = 1; i < m_max; i++)
1533 m_ptr = ¤t_floor_ptr->m_list[i];
1534 r_ptr = &r_info[m_ptr->r_idx];
1535 if (!monster_is_valid(m_ptr)) continue;
1537 /* Is it too far away? */
1538 if (m_ptr->cdis > dis_lim) continue;
1540 /* Get lite radius */
1543 /* Note the radii are cumulative */
1544 if (r_ptr->flags7 & (RF7_HAS_LITE_1 | RF7_SELF_LITE_1)) rad++;
1545 if (r_ptr->flags7 & (RF7_HAS_LITE_2 | RF7_SELF_LITE_2)) rad += 2;
1546 if (r_ptr->flags7 & (RF7_HAS_DARK_1 | RF7_SELF_DARK_1)) rad--;
1547 if (r_ptr->flags7 & (RF7_HAS_DARK_2 | RF7_SELF_DARK_2)) rad -= 2;
1549 /* Exit if has no light */
1553 if (!(r_ptr->flags7 & (RF7_SELF_LITE_1 | RF7_SELF_LITE_2)) && (MON_CSLEEP(m_ptr) || (!current_floor_ptr->dun_level && is_daytime()) || p_ptr->inside_battle)) continue;
1554 if (d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS) rad = 1;
1555 add_mon_lite = mon_lite_hack;
1560 if (!(r_ptr->flags7 & (RF7_SELF_DARK_1 | RF7_SELF_DARK_2)) && (MON_CSLEEP(m_ptr) || (!current_floor_ptr->dun_level && !is_daytime()))) continue;
1561 add_mon_lite = mon_dark_hack;
1562 f_flag = FF_PROJECT;
1563 rad = -rad; /* Use absolute value */
1569 /* Is the monster visible? */
1570 mon_invis = !(current_floor_ptr->grid_array[mon_fy][mon_fx].info & CAVE_VIEW);
1572 /* The square it is on */
1573 add_mon_lite(mon_fy, mon_fx);
1575 /* Adjacent squares */
1576 add_mon_lite(mon_fy + 1, mon_fx);
1577 add_mon_lite(mon_fy - 1, mon_fx);
1578 add_mon_lite(mon_fy, mon_fx + 1);
1579 add_mon_lite(mon_fy, mon_fx - 1);
1580 add_mon_lite(mon_fy + 1, mon_fx + 1);
1581 add_mon_lite(mon_fy + 1, mon_fx - 1);
1582 add_mon_lite(mon_fy - 1, mon_fx + 1);
1583 add_mon_lite(mon_fy - 1, mon_fx - 1);
1588 /* South of the monster */
1589 if (cave_have_flag_bold(mon_fy + 1, mon_fx, f_flag))
1591 add_mon_lite(mon_fy + 2, mon_fx + 1);
1592 add_mon_lite(mon_fy + 2, mon_fx);
1593 add_mon_lite(mon_fy + 2, mon_fx - 1);
1595 g_ptr = ¤t_floor_ptr->grid_array[mon_fy + 2][mon_fx];
1598 if ((rad == 3) && cave_have_flag_grid(g_ptr, f_flag))
1600 add_mon_lite(mon_fy + 3, mon_fx + 1);
1601 add_mon_lite(mon_fy + 3, mon_fx);
1602 add_mon_lite(mon_fy + 3, mon_fx - 1);
1606 /* North of the monster */
1607 if (cave_have_flag_bold(mon_fy - 1, mon_fx, f_flag))
1609 add_mon_lite(mon_fy - 2, mon_fx + 1);
1610 add_mon_lite(mon_fy - 2, mon_fx);
1611 add_mon_lite(mon_fy - 2, mon_fx - 1);
1613 g_ptr = ¤t_floor_ptr->grid_array[mon_fy - 2][mon_fx];
1616 if ((rad == 3) && cave_have_flag_grid(g_ptr, f_flag))
1618 add_mon_lite(mon_fy - 3, mon_fx + 1);
1619 add_mon_lite(mon_fy - 3, mon_fx);
1620 add_mon_lite(mon_fy - 3, mon_fx - 1);
1624 /* East of the monster */
1625 if (cave_have_flag_bold(mon_fy, mon_fx + 1, f_flag))
1627 add_mon_lite(mon_fy + 1, mon_fx + 2);
1628 add_mon_lite(mon_fy, mon_fx + 2);
1629 add_mon_lite(mon_fy - 1, mon_fx + 2);
1631 g_ptr = ¤t_floor_ptr->grid_array[mon_fy][mon_fx + 2];
1634 if ((rad == 3) && cave_have_flag_grid(g_ptr, f_flag))
1636 add_mon_lite(mon_fy + 1, mon_fx + 3);
1637 add_mon_lite(mon_fy, mon_fx + 3);
1638 add_mon_lite(mon_fy - 1, mon_fx + 3);
1642 /* West of the monster */
1643 if (cave_have_flag_bold(mon_fy, mon_fx - 1, f_flag))
1645 add_mon_lite(mon_fy + 1, mon_fx - 2);
1646 add_mon_lite(mon_fy, mon_fx - 2);
1647 add_mon_lite(mon_fy - 1, mon_fx - 2);
1649 g_ptr = ¤t_floor_ptr->grid_array[mon_fy][mon_fx - 2];
1652 if ((rad == 3) && cave_have_flag_grid(g_ptr, f_flag))
1654 add_mon_lite(mon_fy + 1, mon_fx - 3);
1655 add_mon_lite(mon_fy, mon_fx - 3);
1656 add_mon_lite(mon_fy - 1, mon_fx - 3);
1664 /* South-East of the monster */
1665 if (cave_have_flag_bold(mon_fy + 1, mon_fx + 1, f_flag))
1667 add_mon_lite(mon_fy + 2, mon_fx + 2);
1670 /* South-West of the monster */
1671 if (cave_have_flag_bold(mon_fy + 1, mon_fx - 1, f_flag))
1673 add_mon_lite(mon_fy + 2, mon_fx - 2);
1676 /* North-East of the monster */
1677 if (cave_have_flag_bold(mon_fy - 1, mon_fx + 1, f_flag))
1679 add_mon_lite(mon_fy - 2, mon_fx + 2);
1682 /* North-West of the monster */
1683 if (cave_have_flag_bold(mon_fy - 1, mon_fx - 1, f_flag))
1685 add_mon_lite(mon_fy - 2, mon_fx - 2);
1691 /* Save end of list of new squares */
1692 end_temp = tmp_pos.n;
1695 * Look at old set flags to see if there are any changes.
1697 for (i = 0; i < current_floor_ptr->mon_lite_n; i++)
1699 fx = current_floor_ptr->mon_lite_x[i];
1700 fy = current_floor_ptr->mon_lite_y[i];
1702 /* We trust this grid is in bounds */
1705 g_ptr = ¤t_floor_ptr->grid_array[fy][fx];
1707 if (g_ptr->info & CAVE_TEMP) /* Pervious lit */
1709 /* It it no longer lit? */
1710 if ((g_ptr->info & (CAVE_VIEW | CAVE_MNLT)) == CAVE_VIEW)
1712 /* It is now unlit */
1713 /* Add it to later visual update */
1714 cave_note_and_redraw_later(g_ptr, fy, fx);
1717 else /* Pervious darkened */
1719 /* It it no longer darken? */
1720 if ((g_ptr->info & (CAVE_VIEW | CAVE_MNDK)) == CAVE_VIEW)
1722 /* It is now undarken */
1723 /* Add it to later visual update */
1724 cave_note_and_redraw_later(g_ptr, fy, fx);
1728 /* Add to end of temp array */
1729 tmp_pos.x[tmp_pos.n] = fx;
1730 tmp_pos.y[tmp_pos.n] = fy;
1734 /* Clear the lite array */
1735 current_floor_ptr->mon_lite_n = 0;
1737 /* Copy the temp array into the lit array lighting the new squares. */
1738 for (i = 0; i < end_temp; i++)
1743 /* We trust this grid is in bounds */
1746 g_ptr = ¤t_floor_ptr->grid_array[fy][fx];
1748 if (g_ptr->info & CAVE_MNLT) /* Lit */
1750 /* The is the square newly lit and visible? */
1751 if ((g_ptr->info & (CAVE_VIEW | CAVE_TEMP)) == CAVE_VIEW)
1754 /* Add it to later visual update */
1755 cave_note_and_redraw_later(g_ptr, fy, fx);
1760 /* The is the square newly darkened and visible? */
1761 if ((g_ptr->info & (CAVE_VIEW | CAVE_XTRA)) == CAVE_VIEW)
1763 /* It is now darkened */
1764 /* Add it to later visual update */
1765 cave_note_and_redraw_later(g_ptr, fy, fx);
1769 /* Save in the monster lit or darkened array */
1770 current_floor_ptr->mon_lite_x[current_floor_ptr->mon_lite_n] = fx;
1771 current_floor_ptr->mon_lite_y[current_floor_ptr->mon_lite_n] = fy;
1772 current_floor_ptr->mon_lite_n++;
1775 /* Clear the temp flag for the old lit or darken grids */
1776 for (i = end_temp; i < tmp_pos.n; i++)
1778 /* We trust this grid is in bounds */
1780 current_floor_ptr->grid_array[tmp_pos.y[i]][tmp_pos.x[i]].info &= ~(CAVE_TEMP | CAVE_XTRA);
1783 /* Finished with tmp_pos.n */
1786 /* Mega-Hack -- Visual update later */
1787 p_ptr->update |= (PU_DELAY_VIS);
1789 p_ptr->monlite = (current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].info & CAVE_MNLT) ? TRUE : FALSE;
1791 if (p_ptr->special_defense & NINJA_S_STEALTH)
1793 if (p_ptr->old_monlite != p_ptr->monlite)
1797 msg_print(_("影の覆いが薄れた気がする。", "Your mantle of shadow become thin."));
1801 msg_print(_("影の覆いが濃くなった!", "Your mantle of shadow restored its original darkness."));
1805 p_ptr->old_monlite = p_ptr->monlite;
1808 void clear_mon_lite(void)
1813 /* Clear all monster lit squares */
1814 for (i = 0; i < current_floor_ptr->mon_lite_n; i++)
1817 g_ptr = ¤t_floor_ptr->grid_array[current_floor_ptr->mon_lite_y[i]][current_floor_ptr->mon_lite_x[i]];
1819 /* Clear monster illumination flag */
1820 g_ptr->info &= ~(CAVE_MNLT | CAVE_MNDK);
1823 /* Empty the array */
1824 current_floor_ptr->mon_lite_n = 0;