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 "system/floor-type-definition.h"
9 #include "target/grid-selector.h"
10 #include "view/display-messages.h"
11 #include "util/bit-flags-calculator.h"
13 #define TRAVEL_UNABLE 9999
16 * @brief トラベル処理中に地形に応じた移動コスト基準を返す
17 * @param creature_ptr プレーヤーへの参照ポインタ
22 static int travel_flow_cost(player_type *creature_ptr, POSITION y, POSITION x)
25 feature_type *f_ptr = &f_info[creature_ptr->current_floor_ptr->grid_array[y][x].feat];
26 if (has_flag(f_ptr->flags, FF_AVOID_RUN))
29 if (has_flag(f_ptr->flags, FF_WATER) && has_flag(f_ptr->flags, FF_DEEP) && !creature_ptr->levitation)
32 if (has_flag(f_ptr->flags, FF_LAVA)) {
34 if (!creature_ptr->resist_fire)
37 if (!creature_ptr->levitation)
40 if (has_flag(f_ptr->flags, FF_DEEP))
46 if (creature_ptr->current_floor_ptr->grid_array[y][x].info & (CAVE_MARK)) {
47 if (has_flag(f_ptr->flags, FF_DOOR))
50 if (has_flag(f_ptr->flags, FF_TRAP))
58 * @brief トラベル処理の到達地点までの行程を得る処理のサブルーチン
59 * @param creature_ptr プレーヤーへの参照ポインタ
63 * @param wall プレイヤーが壁の中にいるならばTRUE
66 static void travel_flow_aux(player_type *creature_ptr, POSITION y, POSITION x, int n, bool wall)
68 floor_type *floor_ptr = creature_ptr->current_floor_ptr;
69 grid_type *g_ptr = &floor_ptr->grid_array[y][x];
70 feature_type *f_ptr = &f_info[g_ptr->feat];
71 if (!in_bounds(floor_ptr, y, x))
74 if (floor_ptr->dun_level > 0 && !(g_ptr->info & CAVE_KNOWN))
78 int from_wall = (n / TRAVEL_UNABLE);
79 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)
80 || (!has_flag(f_ptr->flags, FF_MOVE) && has_flag(f_ptr->flags, FF_CAN_FLY) && !creature_ptr->levitation)) {
81 if (!wall || !from_wall)
84 add_cost += TRAVEL_UNABLE;
86 add_cost = travel_flow_cost(creature_ptr, y, x);
88 int base_cost = (n % TRAVEL_UNABLE);
89 int cost = base_cost + add_cost;
90 if (travel.cost[y][x] <= cost)
93 travel.cost[y][x] = cost;
94 int old_head = flow_head;
95 temp2_y[flow_head] = y;
96 temp2_x[flow_head] = x;
97 if (++flow_head == MAX_SHORT)
100 if (flow_head == flow_tail)
101 flow_head = old_head;
105 * @brief トラベル処理の到達地点までの行程を得る処理のメインルーチン
106 * @param creature_ptr プレーヤーへの参照ポインタ
111 static void travel_flow(player_type *creature_ptr, POSITION ty, POSITION tx)
113 flow_head = flow_tail = 0;
115 feature_type *f_ptr = &f_info[creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x].feat];
116 if (!has_flag(f_ptr->flags, FF_MOVE))
119 travel_flow_aux(creature_ptr, ty, tx, 0, wall);
121 while (flow_head != flow_tail) {
122 y = temp2_y[flow_tail];
123 x = temp2_x[flow_tail];
124 if (++flow_tail == MAX_SHORT)
127 for (DIRECTION d = 0; d < 8; d++)
128 travel_flow_aux(creature_ptr, y + ddy_ddd[d], x + ddx_ddd[d], travel.cost[y][x], wall);
131 flow_head = flow_tail = 0;
135 * @brief トラベル処理のメインルーチン
138 void do_cmd_travel(player_type *creature_ptr)
141 if (travel.x != 0 && travel.y != 0 && get_check(_("トラベルを継続しますか?", "Do you continue to travel?"))) {
144 } else if (!tgt_pt(creature_ptr, &x, &y))
147 if ((x == creature_ptr->x) && (y == creature_ptr->y)) {
148 msg_print(_("すでにそこにいます!", "You are already there!!"));
152 floor_type *floor_ptr = creature_ptr->current_floor_ptr;
154 f_ptr = &f_info[floor_ptr->grid_array[y][x].feat];
155 if ((floor_ptr->grid_array[y][x].info & CAVE_MARK)
156 && (has_flag(f_ptr->flags, FF_WALL) || has_flag(f_ptr->flags, FF_CAN_DIG)
157 || (has_flag(f_ptr->flags, FF_DOOR) && floor_ptr->grid_array[y][x].mimic))) {
158 msg_print(_("そこには行くことができません!", "You cannot travel there!"));
162 forget_travel_flow(creature_ptr->current_floor_ptr);
163 travel_flow(creature_ptr, y, x);
168 POSITION dx = abs(creature_ptr->x - x);
169 POSITION dy = abs(creature_ptr->y - y);
170 POSITION sx = ((x == creature_ptr->x) || (dx < dy)) ? 0 : ((x > creature_ptr->x) ? 1 : -1);
171 POSITION sy = ((y == creature_ptr->y) || (dy < dx)) ? 0 : ((y > creature_ptr->y) ? 1 : -1);
172 for (int i = 1; i <= 9; i++)
173 if ((sx == ddx[i]) && (sy == ddy[i]))