1 #include "core/player-update-types.h"
2 #include "floor/cave.h"
3 #include "floor/line-of-sight.h"
4 #include "game-option/map-screen-options.h"
6 #include "player/player-view.h"
7 #include "system/floor-type-definition.h"
8 #include "system/player-type-definition.h"
9 #include "util/point-2d.h"
14 * Helper function for "update_view()" below
16 * We are checking the "viewability" of grid (y,x) by the player.
18 * This function assumes that (y,x) is legal (i.e. on the map).
20 * Grid (y1,x1) is on the "diagonal" between (subject_ptr->y,subject_ptr->x) and (y,x)
21 * Grid (y2,x2) is "adjacent", also between (subject_ptr->y,subject_ptr->x) and (y,x).
23 * Note that we are using the "CAVE_XTRA" field for marking grids as
24 * "easily viewable". This bit is cleared at the end of "update_view()".
26 * This function adds (y,x) to the "viewable set" if necessary.
28 * This function now returns "TRUE" if vision is "blocked" by grid (y,x).
30 static bool update_view_aux(player_type *subject_ptr, POSITION y, POSITION x, POSITION y1, POSITION x1, POSITION y2, POSITION x2)
32 floor_type *floor_ptr = subject_ptr->current_floor_ptr;
35 g1_c_ptr = &floor_ptr->grid_array[y1][x1];
36 g2_c_ptr = &floor_ptr->grid_array[y2][x2];
37 bool f1 = (cave_los_grid(g1_c_ptr));
38 bool f2 = (cave_los_grid(g2_c_ptr));
42 bool v1 = (f1 && (g1_c_ptr->info & CAVE_VIEW));
43 bool v2 = (f2 && (g2_c_ptr->info & CAVE_VIEW));
48 g_ptr = &floor_ptr->grid_array[y][x];
49 bool wall = (!cave_los_grid(g_ptr));
50 bool z1 = (v1 && (g1_c_ptr->info & CAVE_XTRA));
51 bool z2 = (v2 && (g2_c_ptr->info & CAVE_XTRA));
53 g_ptr->info |= CAVE_XTRA;
54 cave_view_hack(floor_ptr, g_ptr, y, x);
59 cave_view_hack(floor_ptr, g_ptr, y, x);
64 cave_view_hack(floor_ptr, g_ptr, y, x);
69 cave_view_hack(floor_ptr, g_ptr, y, x);
73 if (los(subject_ptr, subject_ptr->y, subject_ptr->x, y, x)) {
74 cave_view_hack(floor_ptr, g_ptr, y, x);
82 * Calculate the viewable space
84 * 1: Process the player
85 * 1a: The player is always (easily) viewable
86 * 2: Process the diagonals
87 * 2a: The diagonals are (easily) viewable up to the first wall
88 * 2b: But never go more than 2/3 of the "full" distance
89 * 3: Process the main axes
90 * 3a: The main axes are (easily) viewable up to the first wall
91 * 3b: But never go more than the "full" distance
92 * 4: Process sequential "strips" in each of the eight octants
93 * 4a: Each strip runs along the previous strip
94 * 4b: The main axes are "previous" to the first strip
95 * 4c: Process both "sides" of each "direction" of each strip
96 * 4c1: Each side aborts as soon as possible
97 * 4c2: Each side tells the next strip how far it has to check
99 void update_view(player_type *subject_ptr)
101 // 前回プレイヤーから見えていた座標たちを格納する配列。
102 std::vector<Pos2D> points;
107 int se, sw, ne, nw, es, en, ws, wn;
111 floor_type *floor_ptr = subject_ptr->current_floor_ptr;
112 POSITION y_max = floor_ptr->height - 1;
113 POSITION x_max = floor_ptr->width - 1;
116 if (view_reduce_view && !floor_ptr->dun_level) {
117 full = MAX_SIGHT / 2;
118 over = MAX_SIGHT * 3 / 4;
121 over = MAX_SIGHT * 3 / 2;
124 for (n = 0; n < floor_ptr->view_n; n++) {
125 y = floor_ptr->view_y[n];
126 x = floor_ptr->view_x[n];
127 g_ptr = &floor_ptr->grid_array[y][x];
128 g_ptr->info &= ~(CAVE_VIEW);
129 g_ptr->info |= CAVE_TEMP;
131 points.emplace_back(y, x);
134 floor_ptr->view_n = 0;
137 g_ptr = &floor_ptr->grid_array[y][x];
138 g_ptr->info |= CAVE_XTRA;
139 cave_view_hack(floor_ptr, g_ptr, y, x);
142 for (d = 1; d <= z; d++) {
143 g_ptr = &floor_ptr->grid_array[y + d][x + d];
144 g_ptr->info |= CAVE_XTRA;
145 cave_view_hack(floor_ptr, g_ptr, y + d, x + d);
146 if (!cave_los_grid(g_ptr))
150 for (d = 1; d <= z; d++) {
151 g_ptr = &floor_ptr->grid_array[y + d][x - d];
152 g_ptr->info |= CAVE_XTRA;
153 cave_view_hack(floor_ptr, g_ptr, y + d, x - d);
154 if (!cave_los_grid(g_ptr))
158 for (d = 1; d <= z; d++) {
159 g_ptr = &floor_ptr->grid_array[y - d][x + d];
160 g_ptr->info |= CAVE_XTRA;
161 cave_view_hack(floor_ptr, g_ptr, y - d, x + d);
162 if (!cave_los_grid(g_ptr))
166 for (d = 1; d <= z; d++) {
167 g_ptr = &floor_ptr->grid_array[y - d][x - d];
168 g_ptr->info |= CAVE_XTRA;
169 cave_view_hack(floor_ptr, g_ptr, y - d, x - d);
170 if (!cave_los_grid(g_ptr))
174 for (d = 1; d <= full; d++) {
175 g_ptr = &floor_ptr->grid_array[y + d][x];
176 g_ptr->info |= CAVE_XTRA;
177 cave_view_hack(floor_ptr, g_ptr, y + d, x);
178 if (!cave_los_grid(g_ptr))
183 for (d = 1; d <= full; d++) {
184 g_ptr = &floor_ptr->grid_array[y - d][x];
185 g_ptr->info |= CAVE_XTRA;
186 cave_view_hack(floor_ptr, g_ptr, y - d, x);
187 if (!cave_los_grid(g_ptr))
192 for (d = 1; d <= full; d++) {
193 g_ptr = &floor_ptr->grid_array[y][x + d];
194 g_ptr->info |= CAVE_XTRA;
195 cave_view_hack(floor_ptr, g_ptr, y, x + d);
196 if (!cave_los_grid(g_ptr))
201 for (d = 1; d <= full; d++) {
202 g_ptr = &floor_ptr->grid_array[y][x - d];
203 g_ptr->info |= CAVE_XTRA;
204 cave_view_hack(floor_ptr, g_ptr, y, x - d);
205 if (!cave_los_grid(g_ptr))
210 for (n = 1; n <= over / 2; n++) {
211 POSITION ypn, ymn, xpn, xmn;
216 while ((z + n + (n >> 1)) > full)
224 m = MIN(z, y_max - ypn);
225 if ((xpn <= x_max) && (n < se)) {
226 for (k = n, d = 1; d <= m; d++) {
227 if (update_view_aux(subject_ptr, ypn + d, xpn, ypn + d - 1, xpn - 1, ypn + d - 1, xpn)) {
237 if ((xmn >= 0) && (n < sw)) {
238 for (k = n, d = 1; d <= m; d++) {
239 if (update_view_aux(subject_ptr, ypn + d, xmn, ypn + d - 1, xmn + 1, ypn + d - 1, xmn)) {
252 if ((xpn <= x_max) && (n < ne)) {
253 for (k = n, d = 1; d <= m; d++) {
254 if (update_view_aux(subject_ptr, ymn - d, xpn, ymn - d + 1, xpn - 1, ymn - d + 1, xpn)) {
264 if ((xmn >= 0) && (n < nw)) {
265 for (k = n, d = 1; d <= m; d++) {
266 if (update_view_aux(subject_ptr, ymn - d, xmn, ymn - d + 1, xmn + 1, ymn - d + 1, xmn)) {
278 m = MIN(z, x_max - xpn);
279 if ((ypn <= x_max) && (n < es)) {
280 for (k = n, d = 1; d <= m; d++) {
281 if (update_view_aux(subject_ptr, ypn, xpn + d, ypn - 1, xpn + d - 1, ypn, xpn + d - 1)) {
291 if ((ymn >= 0) && (n < en)) {
292 for (k = n, d = 1; d <= m; d++) {
293 if (update_view_aux(subject_ptr, ymn, xpn + d, ymn + 1, xpn + d - 1, ymn, xpn + d - 1)) {
306 if ((ypn <= y_max) && (n < ws)) {
307 for (k = n, d = 1; d <= m; d++) {
308 if (update_view_aux(subject_ptr, ypn, xmn - d, ypn - 1, xmn - d + 1, ypn, xmn - d + 1)) {
318 if ((ymn >= 0) && (n < wn)) {
319 for (k = n, d = 1; d <= m; d++) {
320 if (update_view_aux(subject_ptr, ymn, xmn - d, ymn + 1, xmn - d + 1, ymn, xmn - d + 1)) {
332 for (n = 0; n < floor_ptr->view_n; n++) {
333 y = floor_ptr->view_y[n];
334 x = floor_ptr->view_x[n];
335 g_ptr = &floor_ptr->grid_array[y][x];
336 g_ptr->info &= ~(CAVE_XTRA);
337 if (g_ptr->info & CAVE_TEMP)
340 cave_note_and_redraw_later(floor_ptr, g_ptr, y, x);
343 for (const auto &[py, px] : points) {
344 g_ptr = &floor_ptr->grid_array[py][px];
345 g_ptr->info &= ~(CAVE_TEMP);
346 if (g_ptr->info & CAVE_VIEW)
349 cave_redraw_later(floor_ptr, g_ptr, py, px);
352 subject_ptr->update |= PU_DELAY_VIS;