1 #include "cmd-action/cmd-travel.h"
2 #include "action/travel-execution.h"
3 #include "core/asking-player.h"
4 #include "floor/cave.h"
5 #include "grid/feature.h"
7 #include "player/player-move.h"
8 #include "player/player-status-flags.h"
9 #include "system/floor-type-definition.h"
10 #include "target/grid-selector.h"
11 #include "view/display-messages.h"
12 #include "util/bit-flags-calculator.h"
14 #define TRAVEL_UNABLE 9999
17 * @brief トラベル処理中に地形に応じた移動コスト基準を返す
18 * @param creature_ptr プレーヤーへの参照ポインタ
23 static int travel_flow_cost(player_type *creature_ptr, POSITION y, POSITION x)
26 feature_type *f_ptr = &f_info[creature_ptr->current_floor_ptr->grid_array[y][x].feat];
27 if (has_flag(f_ptr->flags, FF_AVOID_RUN))
30 if (has_flag(f_ptr->flags, FF_WATER) && has_flag(f_ptr->flags, FF_DEEP) && !creature_ptr->levitation)
33 if (has_flag(f_ptr->flags, FF_LAVA)) {
35 if (!has_resist_fire(creature_ptr))
38 if (!creature_ptr->levitation)
41 if (has_flag(f_ptr->flags, FF_DEEP))
47 if (creature_ptr->current_floor_ptr->grid_array[y][x].info & (CAVE_MARK)) {
48 if (has_flag(f_ptr->flags, FF_DOOR))
51 if (has_flag(f_ptr->flags, FF_TRAP))
59 * @brief トラベル処理の到達地点までの行程を得る処理のサブルーチン
60 * @param creature_ptr プレーヤーへの参照ポインタ
64 * @param wall プレイヤーが壁の中にいるならばTRUE
67 static void travel_flow_aux(player_type *creature_ptr, POSITION y, POSITION x, int n, bool wall)
69 floor_type *floor_ptr = creature_ptr->current_floor_ptr;
70 grid_type *g_ptr = &floor_ptr->grid_array[y][x];
71 feature_type *f_ptr = &f_info[g_ptr->feat];
72 if (!in_bounds(floor_ptr, y, x))
75 if (floor_ptr->dun_level > 0 && !(g_ptr->info & CAVE_KNOWN))
79 int from_wall = (n / TRAVEL_UNABLE);
80 if (has_flag(f_ptr->flags, FF_WALL) || has_flag(f_ptr->flags, FF_CAN_DIG) || (has_flag(f_ptr->flags, FF_DOOR) && floor_ptr->grid_array[y][x].mimic)
81 || (!has_flag(f_ptr->flags, FF_MOVE) && has_flag(f_ptr->flags, FF_CAN_FLY) && !creature_ptr->levitation)) {
82 if (!wall || !from_wall)
85 add_cost += TRAVEL_UNABLE;
87 add_cost = travel_flow_cost(creature_ptr, y, x);
89 int base_cost = (n % TRAVEL_UNABLE);
90 int cost = base_cost + add_cost;
91 if (travel.cost[y][x] <= cost)
94 travel.cost[y][x] = cost;
95 int old_head = flow_head;
96 temp2_y[flow_head] = y;
97 temp2_x[flow_head] = x;
98 if (++flow_head == MAX_SHORT)
101 if (flow_head == flow_tail)
102 flow_head = old_head;
106 * @brief トラベル処理の到達地点までの行程を得る処理のメインルーチン
107 * @param creature_ptr プレーヤーへの参照ポインタ
112 static void travel_flow(player_type *creature_ptr, POSITION ty, POSITION tx)
114 flow_head = flow_tail = 0;
116 feature_type *f_ptr = &f_info[creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x].feat];
117 if (!has_flag(f_ptr->flags, FF_MOVE))
120 travel_flow_aux(creature_ptr, ty, tx, 0, wall);
122 while (flow_head != flow_tail) {
123 y = temp2_y[flow_tail];
124 x = temp2_x[flow_tail];
125 if (++flow_tail == MAX_SHORT)
128 for (DIRECTION d = 0; d < 8; d++)
129 travel_flow_aux(creature_ptr, y + ddy_ddd[d], x + ddx_ddd[d], travel.cost[y][x], wall);
132 flow_head = flow_tail = 0;
136 * @brief トラベル処理のメインルーチン
139 void do_cmd_travel(player_type *creature_ptr)
142 if (travel.x != 0 && travel.y != 0 && get_check(_("トラベルを継続しますか?", "Do you continue to travel?"))) {
145 } else if (!tgt_pt(creature_ptr, &x, &y))
148 if ((x == creature_ptr->x) && (y == creature_ptr->y)) {
149 msg_print(_("すでにそこにいます!", "You are already there!!"));
153 floor_type *floor_ptr = creature_ptr->current_floor_ptr;
155 f_ptr = &f_info[floor_ptr->grid_array[y][x].feat];
156 if ((floor_ptr->grid_array[y][x].info & CAVE_MARK)
157 && (has_flag(f_ptr->flags, FF_WALL) || has_flag(f_ptr->flags, FF_CAN_DIG)
158 || (has_flag(f_ptr->flags, FF_DOOR) && floor_ptr->grid_array[y][x].mimic))) {
159 msg_print(_("そこには行くことができません!", "You cannot travel there!"));
163 forget_travel_flow(creature_ptr->current_floor_ptr);
164 travel_flow(creature_ptr, y, x);
169 POSITION dx = abs(creature_ptr->x - x);
170 POSITION dy = abs(creature_ptr->y - y);
171 POSITION sx = ((x == creature_ptr->x) || (dx < dy)) ? 0 : ((x > creature_ptr->x) ? 1 : -1);
172 POSITION sy = ((y == creature_ptr->y) || (dy < dx)) ? 0 : ((y > creature_ptr->y) ? 1 : -1);
173 for (int i = 1; i <= 9; i++)
174 if ((sx == ddx[i]) && (sy == ddy[i]))