OSDN Git Service

[Refactor] Grid::has_monster()の定義
[hengbandforosx/hengbandosx.git] / src / action / travel-execution.cpp
1 /*!
2  * @file travel-execution.cpp
3  * @brief トラベル移動処理実装
4  */
5
6 #include "action/travel-execution.h"
7 #include "action/movement-execution.h"
8 #include "action/run-execution.h"
9 #include "core/disturbance.h"
10 #include "floor/geometry.h"
11 #include "game-option/disturbance-options.h"
12 #include "game-option/input-options.h"
13 #include "game-option/special-options.h"
14 #include "grid/feature.h"
15 #include "grid/grid.h"
16 #include "player-status/player-energy.h"
17 #include "player/player-move.h"
18 #include "system/floor-type-definition.h"
19 #include "system/grid-type-definition.h"
20 #include "system/monster-entity.h"
21 #include "system/player-type-definition.h"
22 #include "timed-effect/player-blindness.h"
23 #include "timed-effect/timed-effects.h"
24 #include "view/display-messages.h"
25
26 travel_type travel;
27
28 /*!
29  * @brief トラベル機能の判定処理 /
30  * Test for traveling
31  * @param player_ptr    プレイヤーへの参照ポインタ
32  * @param prev_dir 前回移動を行った元の方角ID
33  * @return 次の方向
34  */
35 static DIRECTION travel_test(PlayerType *player_ptr, DIRECTION prev_dir)
36 {
37     const auto blindness = player_ptr->effects()->blindness();
38     if (blindness->is_blind() || no_lite(player_ptr)) {
39         msg_print(_("目が見えない!", "You cannot see!"));
40         return 0;
41     }
42
43     auto *floor_ptr = player_ptr->current_floor_ptr;
44     if ((disturb_trap_detect || alert_trap_detect) && player_ptr->dtrap && !(floor_ptr->grid_array[player_ptr->y][player_ptr->x].info & CAVE_IN_DETECT)) {
45         player_ptr->dtrap = false;
46         if (!(floor_ptr->grid_array[player_ptr->y][player_ptr->x].info & CAVE_UNSAFE)) {
47             if (alert_trap_detect) {
48                 msg_print(_("* 注意:この先はトラップの感知範囲外です! *", "*Leaving trap detect region!*"));
49             }
50
51             if (disturb_trap_detect) {
52                 return 0;
53             }
54         }
55     }
56
57     int max = (prev_dir & 0x01) + 1;
58     const Grid *g_ptr;
59     for (int i = -max; i <= max; i++) {
60         DIRECTION dir = cycle[chome[prev_dir] + i];
61         POSITION row = player_ptr->y + ddy[dir];
62         POSITION col = player_ptr->x + ddx[dir];
63         g_ptr = &floor_ptr->grid_array[row][col];
64         if (g_ptr->has_monster()) {
65             auto *m_ptr = &floor_ptr->m_list[g_ptr->m_idx];
66             if (m_ptr->ml) {
67                 return 0;
68             }
69         }
70     }
71
72     int cost = travel.cost[player_ptr->y][player_ptr->x];
73     DIRECTION new_dir = 0;
74     for (int i = 0; i < 8; ++i) {
75         int dir_cost = travel.cost[player_ptr->y + ddy_ddd[i]][player_ptr->x + ddx_ddd[i]];
76         if (dir_cost < cost) {
77             new_dir = ddd[i];
78             cost = dir_cost;
79         }
80     }
81
82     if (!new_dir) {
83         return 0;
84     }
85
86     g_ptr = &floor_ptr->grid_array[player_ptr->y + ddy[new_dir]][player_ptr->x + ddx[new_dir]];
87     if (!easy_open && is_closed_door(player_ptr, g_ptr->feat)) {
88         return 0;
89     }
90
91     if (!g_ptr->mimic && !trap_can_be_ignored(player_ptr, g_ptr->feat)) {
92         return 0;
93     }
94
95     return new_dir;
96 }
97
98 /*!
99  * @brief トラベル機能の実装 /
100  * Travel command
101  * @param player_ptr    プレイヤーへの参照ポインタ
102  */
103 void travel_step(PlayerType *player_ptr)
104 {
105     travel.dir = travel_test(player_ptr, travel.dir);
106     if (!travel.dir) {
107         if (travel.run == 255) {
108             msg_print(_("道筋が見つかりません!", "No route is found!"));
109             travel.y = travel.x = 0;
110         }
111
112         disturb(player_ptr, false, true);
113         return;
114     }
115
116     PlayerEnergy(player_ptr).set_player_turn_energy(100);
117     exe_movement(player_ptr, travel.dir, always_pickup, false);
118     if ((player_ptr->y == travel.y) && (player_ptr->x == travel.x)) {
119         travel.run = 0;
120         travel.y = travel.x = 0;
121     } else if (travel.run > 0) {
122         travel.run--;
123     }
124
125     term_xtra(TERM_XTRA_DELAY, delay_factor);
126 }
127
128 /*!
129  * @brief トラベル処理の記憶配列を初期化する Hack: forget the "flow" information
130  * @param player_ptr    プレイヤーへの参照ポインタ
131  */
132 void forget_travel_flow(FloorType *floor_ptr)
133 {
134     for (POSITION y = 0; y < floor_ptr->height; y++) {
135         for (POSITION x = 0; x < floor_ptr->width; x++) {
136             travel.cost[y][x] = MAX_SHORT;
137         }
138     }
139
140     travel.y = travel.x = 0;
141 }