1 #include "target/target-preparation.h"
2 #include "floor/cave.h"
3 #include "floor/floor.h" // todo projectable() が相互依存.
4 #include "game-option/input-options.h"
5 #include "grid/feature.h"
7 #include "monster/monster-info.h"
8 #include "monster/monster-status.h"
9 #include "object/object-mark-types.h"
10 #include "system/floor-type-definition.h"
11 #include "system/object-type-definition.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 * @briefプレイヤーの攻撃射程(マス) / Maximum range (spells, etc)
55 * @param creature_ptr プレーヤーへの参照ポインタ
58 int get_max_range(player_type *creature_ptr) { return creature_ptr->phase_out ? 36 : 18; }
61 * Determine if a given location is "interesting"
63 static bool target_set_accept(player_type *creature_ptr, POSITION y, POSITION x)
65 floor_type *floor_ptr = creature_ptr->current_floor_ptr;
66 if (!(in_bounds(floor_ptr, y, x)))
69 if (player_bold(creature_ptr, y, x))
72 if (creature_ptr->image)
76 g_ptr = &floor_ptr->grid_array[y][x];
78 monster_type *m_ptr = &floor_ptr->m_list[g_ptr->m_idx];
83 OBJECT_IDX next_o_idx = 0;
84 for (OBJECT_IDX this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx) {
86 o_ptr = &floor_ptr->o_list[this_o_idx];
87 next_o_idx = o_ptr->next_o_idx;
88 if (o_ptr->marked & OM_FOUND)
92 if (g_ptr->info & (CAVE_MARK)) {
93 if (g_ptr->info & CAVE_OBJECT)
96 if (have_flag(f_info[get_feat_mimic(g_ptr)].flags, FF_NOTICE))
104 * Prepare the "temp" array for "target_set"
106 * Return the number of target_able monsters in the set.
108 void target_set_prepare(player_type *creature_ptr, BIT_FLAGS mode)
110 POSITION min_hgt, max_hgt, min_wid, max_wid;
111 if (mode & TARGET_KILL) {
112 min_hgt = MAX((creature_ptr->y - get_max_range(creature_ptr)), 0);
113 max_hgt = MIN((creature_ptr->y + get_max_range(creature_ptr)), creature_ptr->current_floor_ptr->height - 1);
114 min_wid = MAX((creature_ptr->x - get_max_range(creature_ptr)), 0);
115 max_wid = MIN((creature_ptr->x + get_max_range(creature_ptr)), creature_ptr->current_floor_ptr->width - 1);
117 min_hgt = panel_row_min;
118 max_hgt = panel_row_max;
119 min_wid = panel_col_min;
120 max_wid = panel_col_max;
124 for (POSITION y = min_hgt; y <= max_hgt; y++) {
125 for (POSITION x = min_wid; x <= max_wid; x++) {
127 if (!target_set_accept(creature_ptr, y, x))
130 g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
131 if ((mode & (TARGET_KILL)) && !target_able(creature_ptr, g_ptr->m_idx))
134 if ((mode & (TARGET_KILL)) && !target_pet && is_pet(&creature_ptr->current_floor_ptr->m_list[g_ptr->m_idx]))
137 tmp_pos.x[tmp_pos.n] = x;
138 tmp_pos.y[tmp_pos.n] = y;
143 if (mode & (TARGET_KILL)) {
144 ang_sort(creature_ptr, tmp_pos.x, tmp_pos.y, tmp_pos.n, ang_sort_comp_distance, ang_sort_swap_distance);
146 ang_sort(creature_ptr, tmp_pos.x, tmp_pos.y, tmp_pos.n, ang_sort_comp_importance, ang_sort_swap_distance);
149 if (creature_ptr->riding == 0 || !target_pet || (tmp_pos.n <= 1) || !(mode & (TARGET_KILL)))
152 POSITION tmp = tmp_pos.y[0];
153 tmp_pos.y[0] = tmp_pos.y[1];
156 tmp_pos.x[0] = tmp_pos.x[1];