OSDN Git Service

Merge pull request #3532 from sikabane-works/release/3.0.0.87-alpha
[hengbandforosx/hengbandosx.git] / src / action / tunnel-execution.cpp
1 /*!
2  * @file tunnel-execution.cpp
3  * @brief 掘削処理実装
4  */
5 #include "action/tunnel-execution.h"
6 #include "avatar/avatar.h"
7 #include "floor/cave.h"
8 #include "grid/grid.h"
9 #include "io/input-key-requester.h"
10 #include "main/sound-definitions-table.h"
11 #include "main/sound-of-music.h"
12 #include "player-status/player-energy.h"
13 #include "player/player-move.h"
14 #include "system/floor-type-definition.h"
15 #include "system/grid-type-definition.h"
16 #include "system/player-type-definition.h"
17 #include "system/redrawing-flags-updater.h"
18 #include "system/terrain-type-definition.h"
19 #include "util/bit-flags-calculator.h"
20 #include "view/display-messages.h"
21
22 /*!
23  * @brief 「掘る」コマンドを該当のマスに行えるかの判定と結果メッセージの表示 /
24  * Determine if a given grid may be "tunneled"
25  * @param y 対象を行うマスのY座標
26  * @param x 対象を行うマスのX座標
27  * @return
28  */
29 static bool do_cmd_tunnel_test(FloorType *floor_ptr, POSITION y, POSITION x)
30 {
31     auto *g_ptr = &floor_ptr->grid_array[y][x];
32     if (!g_ptr->is_mark()) {
33         msg_print(_("そこには何も見当たらない。", "You see nothing there."));
34         return false;
35     }
36
37     if (!g_ptr->cave_has_flag(TerrainCharacteristics::TUNNEL)) {
38         msg_print(_("そこには掘るものが見当たらない。", "You see nothing there to tunnel."));
39         return false;
40     }
41
42     return true;
43 }
44
45 /*!
46  * @brief 「掘る」動作コマンドのサブルーチン /
47  * Perform the basic "tunnel" command
48  * @param y 対象を行うマスのY座標
49  * @param x 対象を行うマスのX座標
50  * @return 実際に処理が行われた場合TRUEを返す。
51  * @details
52  * Assumes that no monster is blocking the destination
53  * Do not use twall anymore
54  * Returns TRUE if repeated commands may continue
55  */
56 bool exe_tunnel(PlayerType *player_ptr, POSITION y, POSITION x)
57 {
58     grid_type *g_ptr;
59     TerrainType *f_ptr, *mimic_f_ptr;
60     int power;
61     concptr name;
62     bool more = false;
63     if (!do_cmd_tunnel_test(player_ptr->current_floor_ptr, y, x)) {
64         return false;
65     }
66
67     PlayerEnergy(player_ptr).set_player_turn_energy(100);
68     g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
69     f_ptr = &terrains_info[g_ptr->feat];
70     power = f_ptr->power;
71     mimic_f_ptr = &terrains_info[g_ptr->get_feat_mimic()];
72     name = mimic_f_ptr->name.data();
73     if (command_rep == 0) {
74         sound(SOUND_DIG);
75     }
76     if (f_ptr->flags.has(TerrainCharacteristics::PERMANENT)) {
77         if (mimic_f_ptr->flags.has(TerrainCharacteristics::PERMANENT)) {
78             msg_print(_("この岩は硬すぎて掘れないようだ。", "This seems to be permanent rock."));
79         } else {
80             msg_print(_("そこは掘れない!", "You can't tunnel through that!"));
81         }
82     } else if (f_ptr->flags.has(TerrainCharacteristics::CAN_DIG)) {
83         if (player_ptr->skill_dig > randint0(20 * power)) {
84             sound(SOUND_DIG_THROUGH);
85             msg_format(_("%sをくずした。", "You have removed the %s."), name);
86             cave_alter_feat(player_ptr, y, x, TerrainCharacteristics::TUNNEL);
87             RedrawingFlagsUpdater::get_instance().set_flag(StatusRecalculatingFlag::FLOW);
88         } else {
89             msg_format(_("%sをくずしている。", "You dig into the %s."), name);
90             more = true;
91         }
92     } else {
93         bool tree = mimic_f_ptr->flags.has(TerrainCharacteristics::TREE);
94         if (player_ptr->skill_dig > power + randint0(40 * power)) {
95             sound(SOUND_DIG_THROUGH);
96             if (tree) {
97                 msg_format(_("%sを切り払った。", "You have cleared away the %s."), name);
98             } else {
99                 msg_print(_("穴を掘り終えた。", "You have finished the tunnel."));
100                 RedrawingFlagsUpdater::get_instance().set_flag(StatusRecalculatingFlag::FLOW);
101             }
102
103             if (f_ptr->flags.has(TerrainCharacteristics::GLASS)) {
104                 sound(SOUND_GLASS);
105             }
106
107             cave_alter_feat(player_ptr, y, x, TerrainCharacteristics::TUNNEL);
108             chg_virtue(player_ptr, Virtue::DILIGENCE, 1);
109             chg_virtue(player_ptr, Virtue::NATURE, -1);
110         } else {
111             if (tree) {
112                 msg_format(_("%sを切っている。", "You chop away at the %s."), name);
113                 if (randint0(100) < 25) {
114                     search(player_ptr);
115                 }
116             } else {
117                 msg_format(_("%sに穴を掘っている。", "You tunnel into the %s."), name);
118             }
119
120             more = true;
121         }
122     }
123
124     if (is_hidden_door(player_ptr, g_ptr) && (randint0(100) < 25)) {
125         search(player_ptr);
126     }
127
128     return more;
129 }