1 #include "target/target-preparation.h"
2 #include "floor/cave.h"
3 #include "game-option/input-options.h"
4 #include "grid/feature.h"
6 #include "monster/monster-info.h"
7 #include "monster/monster-status.h"
8 #include "object/object-mark-types.h"
9 #include "system/floor-type-definition.h"
10 #include "system/object-type-definition.h"
11 #include "target/projection-path-calculator.h"
12 #include "target/target-types.h"
13 #include "util/bit-flags-calculator.h"
14 #include "util/sort.h"
15 #include "window/main-window-util.h"
18 * Determine is a monster makes a reasonable target
20 * The concept of "targeting" was stolen from "Morgul" (?)
22 * The player can target any location, or any "target-able" monster.
24 * Currently, a monster is "target_able" if it is visible, and if
25 * the player can hit it with a projection, and the player is not
26 * hallucinating. This allows use of "use closest target" macros.
28 * Future versions may restrict the ability to target "trappers"
29 * and "mimics", but the semantics is a little bit weird.
31 bool target_able(player_type *creature_ptr, MONSTER_IDX m_idx)
33 floor_type *floor_ptr = creature_ptr->current_floor_ptr;
34 monster_type *m_ptr = &floor_ptr->m_list[m_idx];
35 if (!monster_is_valid(m_ptr))
38 if (creature_ptr->image)
44 if (creature_ptr->riding && (creature_ptr->riding == m_idx))
47 if (!projectable(creature_ptr, creature_ptr->y, creature_ptr->x, m_ptr->fy, m_ptr->fx))
54 * Determine if a given location is "interesting"
56 static bool target_set_accept(player_type *creature_ptr, POSITION y, POSITION x)
58 floor_type *floor_ptr = creature_ptr->current_floor_ptr;
59 if (!(in_bounds(floor_ptr, y, x)))
62 if (player_bold(creature_ptr, y, x))
65 if (creature_ptr->image)
69 g_ptr = &floor_ptr->grid_array[y][x];
71 monster_type *m_ptr = &floor_ptr->m_list[g_ptr->m_idx];
76 OBJECT_IDX next_o_idx = 0;
77 for (OBJECT_IDX this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) {
79 o_ptr = &floor_ptr->o_list[this_o_idx];
80 next_o_idx = o_ptr->next_o_idx;
81 if (o_ptr->marked & OM_FOUND)
85 if (g_ptr->info & (CAVE_MARK)) {
86 if (g_ptr->info & CAVE_OBJECT)
89 if (has_flag(f_info[get_feat_mimic(g_ptr)].flags, FF_NOTICE))
97 * Prepare the "temp" array for "target_set"
99 * Return the number of target_able monsters in the set.
101 void target_set_prepare(player_type *creature_ptr, BIT_FLAGS mode)
103 POSITION min_hgt, max_hgt, min_wid, max_wid;
104 if (mode & TARGET_KILL) {
105 min_hgt = MAX((creature_ptr->y - get_max_range(creature_ptr)), 0);
106 max_hgt = MIN((creature_ptr->y + get_max_range(creature_ptr)), creature_ptr->current_floor_ptr->height - 1);
107 min_wid = MAX((creature_ptr->x - get_max_range(creature_ptr)), 0);
108 max_wid = MIN((creature_ptr->x + get_max_range(creature_ptr)), creature_ptr->current_floor_ptr->width - 1);
110 min_hgt = panel_row_min;
111 max_hgt = panel_row_max;
112 min_wid = panel_col_min;
113 max_wid = panel_col_max;
117 for (POSITION y = min_hgt; y <= max_hgt; y++) {
118 for (POSITION x = min_wid; x <= max_wid; x++) {
120 if (!target_set_accept(creature_ptr, y, x))
123 g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
124 if ((mode & (TARGET_KILL)) && !target_able(creature_ptr, g_ptr->m_idx))
127 if ((mode & (TARGET_KILL)) && !target_pet && is_pet(&creature_ptr->current_floor_ptr->m_list[g_ptr->m_idx]))
130 tmp_pos.x[tmp_pos.n] = x;
131 tmp_pos.y[tmp_pos.n] = y;
136 if (mode & (TARGET_KILL)) {
137 ang_sort(creature_ptr, tmp_pos.x, tmp_pos.y, tmp_pos.n, ang_sort_comp_distance, ang_sort_swap_position);
139 ang_sort(creature_ptr, tmp_pos.x, tmp_pos.y, tmp_pos.n, ang_sort_comp_importance, ang_sort_swap_position);
142 if (creature_ptr->riding == 0 || !target_pet || (tmp_pos.n <= 1) || !(mode & (TARGET_KILL)))
145 POSITION tmp = tmp_pos.y[0];
146 tmp_pos.y[0] = tmp_pos.y[1];
149 tmp_pos.x[0] = tmp_pos.x[1];
153 void target_sensing_monsters_prepare(player_type *creature_ptr)
158 if (creature_ptr->image)
161 for (int i = 1; i < creature_ptr->current_floor_ptr->m_max; i++) {
162 monster_type *m_ptr = &creature_ptr->current_floor_ptr->m_list[i];
163 if (!monster_is_valid(m_ptr) || !m_ptr->ml || is_pet(m_ptr))
166 tmp_pos.x[tmp_pos.n] = m_ptr->fx;
167 tmp_pos.y[tmp_pos.n] = m_ptr->fy;
171 ang_sort(creature_ptr, tmp_pos.x, tmp_pos.y, tmp_pos.n, ang_sort_comp_importance, ang_sort_swap_position);