OSDN Git Service

[refactor] Rename ang_sort_swap_distance to ang_sort_swap_position
[hengbandforosx/hengbandosx.git] / src / target / grid-selector.c
1 #include "target/grid-selector.h"
2 #include "core/player-redraw-types.h"
3 #include "core/player-update-types.h"
4 #include "core/window-redrawer.h"
5 #include "core/stuff-handler.h"
6 #include "floor/cave.h"
7 #include "game-option/game-play-options.h"
8 #include "game-option/keymap-directory-getter.h"
9 #include "grid/feature-flag-types.h"
10 #include "grid/grid.h"
11 #include "io/cursor.h"
12 #include "io/input-key-acceptor.h"
13 #include "io/screen-util.h"
14 #include "system/floor-type-definition.h"
15 #include "target/target-checker.h"
16 #include "term/screen-processor.h"
17 #include "util/int-char-converter.h"
18 #include "util/sort.h"
19 #include "view/display-messages.h"
20 #include "window/main-window-util.h"
21
22 /*
23  * XAngband: determine if a given location is "interesting"
24  * based on target_set_accept function.
25  */
26 static bool tgt_pt_accept(player_type *creature_ptr, POSITION y, POSITION x)
27 {
28     floor_type *floor_ptr = creature_ptr->current_floor_ptr;
29     if (!(in_bounds(floor_ptr, y, x)))
30         return FALSE;
31
32     if ((y == creature_ptr->y) && (x == creature_ptr->x))
33         return TRUE;
34
35     if (creature_ptr->image)
36         return FALSE;
37
38     grid_type *g_ptr;
39     g_ptr = &floor_ptr->grid_array[y][x];
40     if (!(g_ptr->info & (CAVE_MARK)))
41         return FALSE;
42
43     if (cave_has_flag_grid(g_ptr, FF_LESS) || cave_has_flag_grid(g_ptr, FF_MORE) || cave_has_flag_grid(g_ptr, FF_QUEST_ENTER)
44         || cave_has_flag_grid(g_ptr, FF_QUEST_EXIT))
45         return TRUE;
46
47     return FALSE;
48 }
49
50 /*
51  * XAngband: Prepare the "temp" array for "tget_pt"
52  * based on target_set_prepare funciton.
53  */
54 static void tgt_pt_prepare(player_type *creature_ptr)
55 {
56     tmp_pos.n = 0;
57     if (!expand_list)
58         return;
59
60     floor_type *floor_ptr = creature_ptr->current_floor_ptr;
61     for (POSITION y = 1; y < floor_ptr->height; y++) {
62         for (POSITION x = 1; x < floor_ptr->width; x++) {
63             if (!tgt_pt_accept(creature_ptr, y, x))
64                 continue;
65
66             tmp_pos.x[tmp_pos.n] = x;
67             tmp_pos.y[tmp_pos.n] = y;
68             tmp_pos.n++;
69         }
70     }
71
72     ang_sort(creature_ptr, tmp_pos.x, tmp_pos.y, tmp_pos.n, ang_sort_comp_distance, ang_sort_swap_position);
73 }
74
75 /*
76  * old -- from PsiAngband.
77  */
78 bool tgt_pt(player_type *creature_ptr, POSITION *x_ptr, POSITION *y_ptr)
79 {
80     TERM_LEN wid, hgt;
81     get_screen_size(&wid, &hgt);
82
83     POSITION x = creature_ptr->x;
84     POSITION y = creature_ptr->y;
85     if (expand_list)
86         tgt_pt_prepare(creature_ptr);
87
88     msg_print(_("場所を選んでスペースキーを押して下さい。", "Select a point and press space."));
89     msg_flag = FALSE;
90
91     char ch = 0;
92     int n = 0;
93     bool success = FALSE;
94     while ((ch != ESCAPE) && !success) {
95         bool move_fast = FALSE;
96         move_cursor_relative(y, x);
97         ch = inkey();
98         switch (ch) {
99         case ESCAPE:
100             break;
101         case ' ':
102         case 't':
103         case '.':
104         case '5':
105         case '0':
106             if (player_bold(creature_ptr, y, x))
107                 ch = 0;
108             else
109                 success = TRUE;
110
111             break;
112         case '>':
113         case '<': {
114             if (!expand_list || !tmp_pos.n)
115                 break;
116
117             int dx, dy;
118             int cx = (panel_col_min + panel_col_max) / 2;
119             int cy = (panel_row_min + panel_row_max) / 2;
120             n++;
121             for (; n < tmp_pos.n; ++n) {
122                 grid_type *g_ptr = &creature_ptr->current_floor_ptr->grid_array[tmp_pos.y[n]][tmp_pos.x[n]];
123                 if (cave_has_flag_grid(g_ptr, FF_STAIRS) && cave_has_flag_grid(g_ptr, ch == '>' ? FF_MORE : FF_LESS))
124                     break;
125             }
126
127             if (n == tmp_pos.n) {
128                 n = 0;
129                 y = creature_ptr->y;
130                 x = creature_ptr->x;
131                 verify_panel(creature_ptr);
132                 creature_ptr->update |= PU_MONSTERS;
133                 creature_ptr->redraw |= PR_MAP;
134                 creature_ptr->window_flags |= PW_OVERHEAD;
135                 handle_stuff(creature_ptr);
136             } else {
137                 y = tmp_pos.y[n];
138                 x = tmp_pos.x[n];
139                 dy = 2 * (y - cy) / hgt;
140                 dx = 2 * (x - cx) / wid;
141                 if (dy || dx)
142                     change_panel(creature_ptr, dy, dx);
143             }
144
145             break;
146         }
147         default: {
148             int d = get_keymap_dir(ch);
149             if (isupper(ch))
150                 move_fast = TRUE;
151
152             if (d == 0)
153                 break;
154
155             int dx = ddx[d];
156             int dy = ddy[d];
157             if (move_fast) {
158                 int mag = MIN(wid / 2, hgt / 2);
159                 x += dx * mag;
160                 y += dy * mag;
161             } else {
162                 x += dx;
163                 y += dy;
164             }
165
166             if (((x < panel_col_min + wid / 2) && (dx > 0)) || ((x > panel_col_min + wid / 2) && (dx < 0)))
167                 dx = 0;
168
169             if (((y < panel_row_min + hgt / 2) && (dy > 0)) || ((y > panel_row_min + hgt / 2) && (dy < 0)))
170                 dy = 0;
171
172             if ((y >= panel_row_min + hgt) || (y < panel_row_min) || (x >= panel_col_min + wid) || (x < panel_col_min))
173                 change_panel(creature_ptr, dy, dx);
174
175             if (x >= creature_ptr->current_floor_ptr->width - 1)
176                 x = creature_ptr->current_floor_ptr->width - 2;
177             else if (x <= 0)
178                 x = 1;
179
180             if (y >= creature_ptr->current_floor_ptr->height - 1)
181                 y = creature_ptr->current_floor_ptr->height - 2;
182             else if (y <= 0)
183                 y = 1;
184
185             break;
186         }
187         }
188     }
189
190     prt("", 0, 0);
191     verify_panel(creature_ptr);
192     creature_ptr->update |= PU_MONSTERS;
193     creature_ptr->redraw |= PR_MAP;
194     creature_ptr->window_flags |= PW_OVERHEAD;
195     handle_stuff(creature_ptr);
196     *x_ptr = x;
197     *y_ptr = y;
198     return success;
199 }