1 #include "target/target-setter.h"
2 #include "core/player-redraw-types.h"
3 #include "core/player-update-types.h"
4 #include "core/stuff-handler.h"
5 #include "core/window-redrawer.h"
6 #include "floor/floor.h"
7 #include "game-option/cheat-options.h"
8 #include "game-option/game-play-options.h"
9 #include "game-option/input-options.h"
10 #include "grid/grid.h"
11 #include "io/cursor.h"
12 #include "io/input-key-requester.h"
13 #include "io/screen-util.h"
14 #include "main/sound-of-music.h"
15 #include "system/floor-type-definition.h"
16 #include "target/target-checker.h"
17 #include "target/target-describer.h"
18 #include "target/target-preparation.h"
19 #include "target/target-types.h"
20 #include "term/screen-processor.h"
21 #include "util/int-char-converter.h"
22 #include "window/main-window-util.h"
25 typedef struct ts_type {
42 static ts_type *initialize_target_set_type(player_type *creature_ptr, ts_type *ts_ptr, target_type mode)
45 ts_ptr->y = creature_ptr->y;
46 ts_ptr->x = creature_ptr->x;
49 get_screen_size(&ts_ptr->wid, &ts_ptr->hgt);
55 * @brief フォーカスを当てるべきマップ描画の基準座標を指定する
56 * @param creature_ptr プレーヤーへの参照ポインタ
60 * Handle a request to change the current panel
61 * Return TRUE if the panel was changed.
62 * Also used in do_cmd_locate
63 * @return 実際に再描画が必要だった場合TRUEを返す
65 static bool change_panel_xy(player_type *creature_ptr, POSITION y, POSITION x)
67 POSITION dy = 0, dx = 0;
69 get_screen_size(&wid, &hgt);
70 if (y < panel_row_min)
73 if (y > panel_row_max)
76 if (x < panel_col_min)
79 if (x > panel_col_max)
85 return change_panel(creature_ptr, dy, dx);
89 * Help "select" a location (see below)
91 static POSITION_IDX target_pick(POSITION y1, POSITION x1, POSITION dy, POSITION dx)
93 POSITION_IDX b_i = -1, b_v = 9999;
94 for (POSITION_IDX i = 0; i < tmp_pos.n; i++) {
95 POSITION x2 = tmp_pos.x[i];
96 POSITION y2 = tmp_pos.y[i];
97 POSITION x3 = (x2 - x1);
98 POSITION y3 = (y2 - y1);
99 if (dx && (x3 * dx <= 0))
102 if (dy && (y3 * dy <= 0))
105 POSITION x4 = ABS(x3);
106 POSITION y4 = ABS(y3);
107 if (dy && !dx && (x4 > y4))
110 if (dx && !dy && (y4 > x4))
113 POSITION_IDX v = ((x4 > y4) ? (x4 + x4 + y4) : (y4 + y4 + x4));
114 if ((b_i >= 0) && (v >= b_v))
124 static void describe_projectablity(player_type *creature_ptr, ts_type *ts_ptr)
126 ts_ptr->y = tmp_pos.y[ts_ptr->m];
127 ts_ptr->x = tmp_pos.x[ts_ptr->m];
128 change_panel_xy(creature_ptr, ts_ptr->y, ts_ptr->x);
129 if ((ts_ptr->mode & TARGET_LOOK) == 0)
130 print_path(creature_ptr, ts_ptr->y, ts_ptr->x);
132 ts_ptr->g_ptr = &creature_ptr->current_floor_ptr->grid_array[ts_ptr->y][ts_ptr->x];
133 if (target_able(creature_ptr, ts_ptr->g_ptr->m_idx))
134 strcpy(ts_ptr->info, _("q止 t決 p自 o現 +次 -前", "q,t,p,o,+,-,<dir>"));
136 strcpy(ts_ptr->info, _("q止 p自 o現 +次 -前", "q,p,o,+,-,<dir>"));
142 sprintf(cheatinfo, " LOS:%d, PROJECTABLE:%d", los(creature_ptr, creature_ptr->y, creature_ptr->x, ts_ptr->y, ts_ptr->x),
143 projectable(creature_ptr, creature_ptr->y, creature_ptr->x, ts_ptr->y, ts_ptr->x));
144 strcat(ts_ptr->info, cheatinfo);
147 static void menu_target(ts_type *ts_ptr)
152 if (ts_ptr->query == '\r')
156 static void switch_target_input(player_type *creature_ptr, ts_type *ts_ptr)
158 ts_ptr->distance = 0;
159 switch (ts_ptr->query) {
168 if (!target_able(creature_ptr, ts_ptr->g_ptr->m_idx)) {
173 health_track(creature_ptr, ts_ptr->g_ptr->m_idx);
174 target_who = ts_ptr->g_ptr->m_idx;
175 target_row = ts_ptr->y;
176 target_col = ts_ptr->x;
182 if (++ts_ptr->m != tmp_pos.n)
191 if (ts_ptr->m-- != 0)
194 ts_ptr->m = tmp_pos.n - 1;
200 verify_panel(creature_ptr);
201 creature_ptr->update |= PU_MONSTERS;
202 creature_ptr->redraw |= PR_MAP;
203 creature_ptr->window |= PW_OVERHEAD;
204 handle_stuff(creature_ptr);
205 target_set_prepare(creature_ptr, ts_ptr->mode);
206 ts_ptr->y = creature_ptr->y;
207 ts_ptr->x = creature_ptr->x;
211 ts_ptr->flag = FALSE;
216 if (ts_ptr->query != rogue_like_commands ? 'x' : 'l') {
217 ts_ptr->distance = get_keymap_dir(ts_ptr->query);
218 if (ts_ptr->distance == 0)
224 if (++ts_ptr->m != tmp_pos.n)
235 static bool check_panel_changed(player_type *creature_ptr, ts_type *ts_ptr)
237 if (!change_panel(creature_ptr, ddy[ts_ptr->distance], ddx[ts_ptr->distance]))
240 int v = tmp_pos.y[ts_ptr->m];
241 int u = tmp_pos.x[ts_ptr->m];
242 target_set_prepare(creature_ptr, ts_ptr->mode);
244 ts_ptr->target_num = target_pick(v, u, ddy[ts_ptr->distance], ddx[ts_ptr->distance]);
245 if (ts_ptr->target_num >= 0)
246 ts_ptr->m = ts_ptr->target_num;
251 static void sweep_targets(player_type *creature_ptr, ts_type *ts_ptr)
253 floor_type *floor_ptr = creature_ptr->current_floor_ptr;
254 while (ts_ptr->flag && (ts_ptr->target_num < 0)) {
255 if (check_panel_changed(creature_ptr, ts_ptr))
258 POSITION dx = ddx[ts_ptr->distance];
259 POSITION dy = ddy[ts_ptr->distance];
260 panel_row_min = ts_ptr->y2;
261 panel_col_min = ts_ptr->x2;
262 panel_bounds_center();
263 creature_ptr->update |= PU_MONSTERS;
264 creature_ptr->redraw |= PR_MAP;
265 creature_ptr->window |= PW_OVERHEAD;
266 handle_stuff(creature_ptr);
267 target_set_prepare(creature_ptr, ts_ptr->mode);
268 ts_ptr->flag = FALSE;
271 if (((ts_ptr->x < panel_col_min + ts_ptr->wid / 2) && (dx > 0)) || ((ts_ptr->x > panel_col_min + ts_ptr->wid / 2) && (dx < 0)))
274 if (((ts_ptr->y < panel_row_min + ts_ptr->hgt / 2) && (dy > 0)) || ((ts_ptr->y > panel_row_min + ts_ptr->hgt / 2) && (dy < 0)))
277 if ((ts_ptr->y >= panel_row_min + ts_ptr->hgt) || (ts_ptr->y < panel_row_min) || (ts_ptr->x >= panel_col_min + ts_ptr->wid)
278 || (ts_ptr->x < panel_col_min)) {
279 if (change_panel(creature_ptr, dy, dx))
280 target_set_prepare(creature_ptr, ts_ptr->mode);
283 if (ts_ptr->x >= floor_ptr->width - 1)
284 ts_ptr->x = floor_ptr->width - 2;
285 else if (ts_ptr->x <= 0)
288 if (ts_ptr->y >= floor_ptr->height - 1)
289 ts_ptr->y = floor_ptr->height - 2;
290 else if (ts_ptr->y <= 0)
295 static bool set_target_grid(player_type *creature_ptr, ts_type *ts_ptr)
297 if (!ts_ptr->flag || (tmp_pos.n == 0))
300 describe_projectablity(creature_ptr, ts_ptr);
302 ts_ptr->query = examine_grid(creature_ptr, ts_ptr->y, ts_ptr->x, ts_ptr->mode, ts_ptr->info);
308 switch_target_input(creature_ptr, ts_ptr);
309 if (ts_ptr->distance == 0)
312 ts_ptr->y2 = panel_row_min;
313 ts_ptr->x2 = panel_col_min;
314 ts_ptr->target_num = target_pick(tmp_pos.y[ts_ptr->m], tmp_pos.x[ts_ptr->m], ddy[ts_ptr->distance], ddx[ts_ptr->distance]);
315 sweep_targets(creature_ptr, ts_ptr);
316 ts_ptr->m = ts_ptr->target_num;
321 * Handle "target" and "look".
323 bool target_set(player_type *creature_ptr, target_type mode)
326 ts_type *ts_ptr = initialize_target_set_type(creature_ptr, &tmp_ts, mode);
328 target_set_prepare(creature_ptr, mode);
329 floor_type *floor_ptr = creature_ptr->current_floor_ptr;
330 while (!ts_ptr->done) {
331 if (set_target_grid(creature_ptr, ts_ptr))
334 bool move_fast = FALSE;
335 if (!(mode & TARGET_LOOK))
336 print_path(creature_ptr, ts_ptr->y, ts_ptr->x);
338 ts_ptr->g_ptr = &floor_ptr->grid_array[ts_ptr->y][ts_ptr->x];
339 strcpy(ts_ptr->info, _("q止 t決 p自 m近 +次 -前", "q,t,p,m,+,-,<dir>"));
342 sprintf(cheatinfo, " LOS:%d, PROJECTABLE:%d, SPECIAL:%d", los(creature_ptr, creature_ptr->y, creature_ptr->x, ts_ptr->y, ts_ptr->x),
343 projectable(creature_ptr, creature_ptr->y, creature_ptr->x, ts_ptr->y, ts_ptr->x), ts_ptr->g_ptr->special);
344 strcat(ts_ptr->info, cheatinfo);
347 /* Describe and Prompt (enable "TARGET_LOOK") */
348 while ((ts_ptr->query = examine_grid(creature_ptr, ts_ptr->y, ts_ptr->x, mode | TARGET_LOOK, ts_ptr->info)) == 0)
352 if (use_menu && (ts_ptr->query == '\r'))
355 switch (ts_ptr->query) {
365 target_row = ts_ptr->y;
366 target_col = ts_ptr->x;
370 verify_panel(creature_ptr);
371 creature_ptr->update |= (PU_MONSTERS);
372 creature_ptr->redraw |= (PR_MAP);
373 creature_ptr->window |= (PW_OVERHEAD);
374 handle_stuff(creature_ptr);
375 target_set_prepare(creature_ptr, mode);
376 ts_ptr->y = creature_ptr->y;
377 ts_ptr->x = creature_ptr->x;
388 for (int i = 0; i < tmp_pos.n; i++) {
389 int t = distance(ts_ptr->y, ts_ptr->x, tmp_pos.y[i], tmp_pos.x[i]);
397 ts_ptr->flag = FALSE;
402 d = get_keymap_dir(ts_ptr->query);
403 if (isupper(ts_ptr->query))
413 POSITION dx = ddx[d];
414 POSITION dy = ddy[d];
416 int mag = MIN(ts_ptr->wid / 2, ts_ptr->hgt / 2);
417 ts_ptr->x += dx * mag;
418 ts_ptr->y += dy * mag;
424 if (((ts_ptr->x < panel_col_min + ts_ptr->wid / 2) && (dx > 0)) || ((ts_ptr->x > panel_col_min + ts_ptr->wid / 2) && (dx < 0)))
427 if (((ts_ptr->y < panel_row_min + ts_ptr->hgt / 2) && (dy > 0)) || ((ts_ptr->y > panel_row_min + ts_ptr->hgt / 2) && (dy < 0)))
430 if ((ts_ptr->y >= panel_row_min + ts_ptr->hgt) || (ts_ptr->y < panel_row_min) || (ts_ptr->x >= panel_col_min + ts_ptr->wid)
431 || (ts_ptr->x < panel_col_min)) {
432 if (change_panel(creature_ptr, dy, dx))
433 target_set_prepare(creature_ptr, mode);
436 if (ts_ptr->x >= floor_ptr->width - 1)
437 ts_ptr->x = floor_ptr->width - 2;
438 else if (ts_ptr->x <= 0)
441 if (ts_ptr->y >= floor_ptr->height - 1)
442 ts_ptr->y = floor_ptr->height - 2;
443 else if (ts_ptr->y <= 0)
450 verify_panel(creature_ptr);
451 creature_ptr->update |= (PU_MONSTERS);
452 creature_ptr->redraw |= (PR_MAP);
453 creature_ptr->window |= (PW_OVERHEAD);
454 handle_stuff(creature_ptr);
455 return target_who != 0;