2 * @file open-close-execution.cpp
8 #include "action/open-close-execution.h"
9 #include "action/movement-execution.h"
10 #include "combat/attack-power-table.h"
11 #include "game-option/disturbance-options.h"
12 #include "game-option/input-options.h"
13 #include "grid/feature.h"
14 #include "grid/grid.h"
15 #include "grid/trap.h"
16 #include "main/sound-definitions-table.h"
17 #include "main/sound-of-music.h"
18 #include "perception/object-perception.h"
19 #include "player-status/player-energy.h"
20 #include "player/player-status-table.h"
21 #include "specific-object/chest.h"
22 #include "status/bad-status-setter.h"
23 #include "status/experience.h"
24 #include "system/floor-type-definition.h"
25 #include "system/object-type-definition.h"
26 #include "system/player-type-definition.h"
27 #include "term/screen-processor.h"
28 #include "util/bit-flags-calculator.h"
29 #include "view/display-messages.h"
32 * @brief 「開ける」動作コマンドのサブルーチン /
33 * Perform the basic "open" command on doors
34 * @param y 対象を行うマスのY座標
35 * @param x 対象を行うマスのX座標
36 * @return 連続でコマンドを実行する時のみTRUE、1回きりの時はFALSE
38 bool exe_open(player_type *creature_ptr, POSITION y, POSITION x)
40 grid_type *g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
41 feature_type *f_ptr = &f_info[g_ptr->feat];
42 PlayerEnergy(creature_ptr).set_player_turn_energy(100);
43 if (!has_flag(f_ptr->flags, FF_OPEN)) {
44 msg_format(_("%sはがっちりと閉じられているようだ。", "The %s appears to be stuck."), f_info[get_feat_mimic(g_ptr)].name.c_str());
49 cave_alter_feat(creature_ptr, y, x, FF_OPEN);
50 sound(SOUND_OPENDOOR);
54 int i = creature_ptr->skill_dis;
55 if (creature_ptr->blind || no_lite(creature_ptr))
58 if (creature_ptr->confused || creature_ptr->image)
66 if (randint0(100) >= j) {
70 msg_print(_("鍵をはずせなかった。", "You failed to pick the lock."));
74 msg_print(_("鍵をはずした。", "You have picked the lock."));
75 cave_alter_feat(creature_ptr, y, x, FF_OPEN);
76 sound(SOUND_OPENDOOR);
77 gain_exp(creature_ptr, 1);
82 * @brief 「閉じる」動作コマンドのサブルーチン /
83 * Perform the basic "close" command
84 * @param y 対象を行うマスのY座標
85 * @param x 対象を行うマスのX座標
86 * @return 実際に処理が行われた場合TRUEを返す。
88 * Assume destination is an open/broken door
89 * Assume there is no monster blocking the destination
90 * Returns TRUE if repeated commands may continue
93 bool exe_close(player_type *creature_ptr, POSITION y, POSITION x)
95 grid_type *g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
96 FEAT_IDX old_feat = g_ptr->feat;
98 PlayerEnergy(creature_ptr).set_player_turn_energy(100);
99 if (!has_flag(f_info[old_feat].flags, FF_CLOSE))
102 s16b closed_feat = feat_state(creature_ptr->current_floor_ptr, old_feat, FF_CLOSE);
103 if ((g_ptr->o_idx || (g_ptr->info & CAVE_OBJECT)) && (closed_feat != old_feat) && !has_flag(f_info[closed_feat].flags, FF_DROP)) {
104 msg_print(_("何かがつっかえて閉まらない。", "Something prevents it from closing."));
106 cave_alter_feat(creature_ptr, y, x, FF_CLOSE);
107 if (old_feat == g_ptr->feat) {
108 msg_print(_("ドアは壊れてしまっている。", "The door appears to be broken."));
110 sound(SOUND_SHUTDOOR);
118 * @brief 移動処理による簡易な「開く」処理 /
120 * @return 開く処理が実際に試みられた場合TRUEを返す
123 * If there is a jammed/closed/locked door at the given location,
124 * then attempt to unlock/open it. Return TRUE if an attempt was
125 * made (successful or not), otherwise return FALSE.
127 * The code here should be nearly identical to that in
128 * do_cmd_open_test() and exe_open().
131 bool easy_open_door(player_type *creature_ptr, POSITION y, POSITION x)
134 grid_type *g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
135 feature_type *f_ptr = &f_info[g_ptr->feat];
136 if (!is_closed_door(creature_ptr, g_ptr->feat))
139 if (!has_flag(f_ptr->flags, FF_OPEN)) {
140 msg_format(_("%sはがっちりと閉じられているようだ。", "The %s appears to be stuck."), f_info[get_feat_mimic(g_ptr)].name.c_str());
141 } else if (f_ptr->power) {
142 i = creature_ptr->skill_dis;
143 if (creature_ptr->blind || no_lite(creature_ptr))
146 if (creature_ptr->confused || creature_ptr->image)
154 if (randint0(100) < j) {
155 msg_print(_("鍵をはずした。", "You have picked the lock."));
156 cave_alter_feat(creature_ptr, y, x, FF_OPEN);
157 sound(SOUND_OPENDOOR);
158 gain_exp(creature_ptr, 1);
163 msg_print(_("鍵をはずせなかった。", "You failed to pick the lock."));
166 cave_alter_feat(creature_ptr, y, x, FF_OPEN);
167 sound(SOUND_OPENDOOR);
174 * @brief 箱のトラップを解除する実行処理 /
175 * Perform the basic "disarm" command
176 * @param y 解除を行うマスのY座標
177 * @param x 解除を行うマスのX座標
178 * @param o_idx 箱のオブジェクトID
179 * @return ターンを消費する処理が行われた場合TRUEを返す
182 * Assume destination is a visible trap
183 * Assume there is no monster blocking the destination
184 * Returns TRUE if repeated commands may continue
187 bool exe_disarm_chest(player_type *creature_ptr, POSITION y, POSITION x, OBJECT_IDX o_idx)
190 object_type *o_ptr = &creature_ptr->current_floor_ptr->o_list[o_idx];
191 PlayerEnergy(creature_ptr).set_player_turn_energy(100);
192 int i = creature_ptr->skill_dis;
193 if (creature_ptr->blind || no_lite(creature_ptr))
196 if (creature_ptr->confused || creature_ptr->image)
199 int j = i - o_ptr->pval;
203 if (!object_is_known(o_ptr)) {
204 msg_print(_("トラップが見あたらない。", "I don't see any traps."));
205 } else if (o_ptr->pval <= 0) {
206 msg_print(_("箱にはトラップが仕掛けられていない。", "The chest is not trapped."));
207 } else if (!chest_traps[o_ptr->pval]) {
208 msg_print(_("箱にはトラップが仕掛けられていない。", "The chest is not trapped."));
209 } else if (randint0(100) < j) {
210 msg_print(_("箱に仕掛けられていたトラップを解除した。", "You have disarmed the chest."));
211 gain_exp(creature_ptr, o_ptr->pval);
212 o_ptr->pval = (0 - o_ptr->pval);
213 } else if ((i > 5) && (randint1(i) > 5)) {
218 msg_print(_("箱のトラップ解除に失敗した。", "You failed to disarm the chest."));
220 msg_print(_("トラップを作動させてしまった!", "You set off a trap!"));
222 chest_trap(creature_ptr, y, x, o_idx);
229 * @brief 箱のトラップを解除するコマンドのサブルーチン /
230 * Perform the basic "disarm" command
231 * @param y 解除を行うマスのY座標
232 * @param x 解除を行うマスのX座標
233 * @param dir プレイヤーからみた方向ID
234 * @return ターンを消費する処理が行われた場合TRUEを返す
237 * Assume destination is a visible trap
238 * Assume there is no monster blocking the destination
239 * Returns TRUE if repeated commands may continue
243 bool exe_disarm(player_type *creature_ptr, POSITION y, POSITION x, DIRECTION dir)
245 grid_type *g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
246 feature_type *f_ptr = &f_info[g_ptr->feat];
247 concptr name = f_ptr->name.c_str();
248 int power = f_ptr->power;
250 int i = creature_ptr->skill_dis;
251 PlayerEnergy(creature_ptr).set_player_turn_energy(100);
252 if (creature_ptr->blind || no_lite(creature_ptr))
255 if (creature_ptr->confused || creature_ptr->image)
262 if (randint0(100) < j) {
263 msg_format(_("%sを解除した。", "You have disarmed the %s."), name);
264 gain_exp(creature_ptr, power);
265 cave_alter_feat(creature_ptr, y, x, FF_DISARM);
266 exe_movement(creature_ptr, dir, easy_disarm, FALSE);
267 } else if ((i > 5) && (randint1(i) > 5)) {
271 msg_format(_("%sの解除に失敗した。", "You failed to disarm the %s."), name);
274 msg_format(_("%sを作動させてしまった!", "You set off the %s!"), name);
275 exe_movement(creature_ptr, dir, easy_disarm, FALSE);
282 * @brief 「打ち破る」動作コマンドのサブルーチン /
283 * Perform the basic "bash" command
284 * @param y 対象を行うマスのY座標
285 * @param x 対象を行うマスのX座標
286 * @param dir プレイヤーから見たターゲットの方角ID
287 * @return 実際に処理が行われた場合TRUEを返す。
290 * Assume destination is a closed/locked/jammed door
291 * Assume there is no monster blocking the destination
292 * Returns TRUE if repeated commands may continue
295 bool exe_bash(player_type *creature_ptr, POSITION y, POSITION x, DIRECTION dir)
297 grid_type *g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
298 feature_type *f_ptr = &f_info[g_ptr->feat];
299 int bash = adj_str_blow[creature_ptr->stat_index[A_STR]];
300 int temp = f_ptr->power;
302 concptr name = f_info[get_feat_mimic(g_ptr)].name.c_str();
303 PlayerEnergy(creature_ptr).set_player_turn_energy(100);
304 msg_format(_("%sに体当たりをした!", "You smash into the %s!"), name);
305 temp = (bash - (temp * 10));
306 if (creature_ptr->pclass == CLASS_BERSERKER)
312 if (randint0(100) < temp) {
313 msg_format(_("%sを壊した!", "The %s crashes open!"), name);
314 sound(has_flag(f_ptr->flags, FF_GLASS) ? SOUND_GLASS : SOUND_OPENDOOR);
315 if ((randint0(100) < 50) || (feat_state(creature_ptr->current_floor_ptr, g_ptr->feat, FF_OPEN) == g_ptr->feat) || has_flag(f_ptr->flags, FF_GLASS)) {
316 cave_alter_feat(creature_ptr, y, x, FF_BASH);
318 cave_alter_feat(creature_ptr, y, x, FF_OPEN);
321 exe_movement(creature_ptr, dir, FALSE, FALSE);
322 } else if (randint0(100) < adj_dex_safe[creature_ptr->stat_index[A_DEX]] + creature_ptr->lev) {
323 msg_format(_("この%sは頑丈だ。", "The %s holds firm."), name);
326 msg_print(_("体のバランスをくずしてしまった。", "You are off-balance."));
327 (void)set_paralyzed(creature_ptr, creature_ptr->paralyzed + 2 + randint0(2));