1 #include "cmd-action/cmd-open-close.h"
2 #include "action/open-close-execution.h"
3 #include "action/open-util.h"
4 #include "cmd-action/cmd-attack.h"
5 #include "core/disturbance.h"
6 #include "core/player-redraw-types.h"
7 #include "game-option/disturbance-options.h"
8 #include "game-option/input-options.h"
9 #include "grid/feature.h"
10 #include "grid/grid.h"
11 #include "inventory/inventory-object.h"
12 #include "inventory/inventory-slot-types.h"
13 #include "io/input-key-requester.h"
14 #include "player/attack-defense-types.h"
15 #include "player/special-defense-types.h"
16 #include "specific-object/chest.h"
17 #include "status/action-setter.h"
18 #include "status/experience.h"
19 #include "system/floor-type-definition.h"
20 #include "system/object-type-definition.h"
21 #include "target/target-getter.h"
22 #include "term/screen-processor.h"
23 #include "util/bit-flags-calculator.h"
24 #include "view/display-messages.h"
28 * Attempt to open the given chest at the given location
29 * @param y 箱の存在するマスのY座標
30 * @param x 箱の存在するマスのX座標
31 * @param o_idx 箱のオブジェクトID
32 * @return 箱が開かなかった場合TRUE / Returns TRUE if repeated commands may continue
34 * Assume there is no monster blocking the destination
36 static bool exe_open_chest(player_type *creature_ptr, POSITION y, POSITION x, OBJECT_IDX o_idx)
40 object_type *o_ptr = &creature_ptr->current_floor_ptr->o_list[o_idx];
41 take_turn(creature_ptr, 100);
42 if (o_ptr->pval > 0) {
44 int i = creature_ptr->skill_dis;
45 if (creature_ptr->blind || no_lite(creature_ptr))
48 if (creature_ptr->confused || creature_ptr->image)
51 int j = i - o_ptr->pval;
55 if (randint0(100) < j) {
56 msg_print(_("鍵をはずした。", "You have picked the lock."));
57 gain_exp(creature_ptr, 1);
64 msg_print(_("鍵をはずせなかった。", "You failed to pick the lock."));
69 chest_trap(creature_ptr, y, x, o_idx);
70 chest_death(creature_ptr, FALSE, y, x, o_idx);
77 * @brief 「開ける」コマンドのメインルーチン /
78 * Open a closed/locked/jammed door or a closed/locked chest.
81 * Unlocking a locked door/chest is worth one experience point.
83 void do_cmd_open(player_type *creature_ptr)
89 if (creature_ptr->wild_mode)
92 if (creature_ptr->special_defense & KATA_MUSOU)
93 set_action(creature_ptr, ACTION_NONE);
96 int num_doors = count_dt(creature_ptr, &y, &x, is_closed_door, FALSE);
97 int num_chests = count_chests(creature_ptr, &y, &x, FALSE);
98 if (num_doors || num_chests) {
99 bool too_many = (num_doors && num_chests) || (num_doors > 1) || (num_chests > 1);
101 command_dir = coords_to_dir(creature_ptr, y, x);
106 command_rep = command_arg - 1;
107 creature_ptr->redraw |= PR_STATE;
111 if (get_rep_dir(creature_ptr, &dir, TRUE)) {
114 y = creature_ptr->y + ddy[dir];
115 x = creature_ptr->x + ddx[dir];
116 g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
117 feat = get_feat_mimic(g_ptr);
118 o_idx = chest_check(creature_ptr->current_floor_ptr, y, x, FALSE);
119 if (!has_flag(f_info[feat].flags, FF_OPEN) && !o_idx) {
120 msg_print(_("そこには開けるものが見当たらない。", "You see nothing there to open."));
121 } else if (g_ptr->m_idx && creature_ptr->riding != g_ptr->m_idx) {
122 take_turn(creature_ptr, 100);
123 msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
124 do_cmd_attack(creature_ptr, y, x, HISSATSU_NONE);
126 more = exe_open_chest(creature_ptr, y, x, o_idx);
128 more = exe_open(creature_ptr, y, x);
133 disturb(creature_ptr, FALSE, FALSE);
137 * @brief 「閉じる」コマンドのメインルーチン /
138 * Close an open door.
141 * Unlocking a locked door/chest is worth one experience point.
143 void do_cmd_close(player_type *creature_ptr)
148 if (creature_ptr->wild_mode)
151 if (creature_ptr->special_defense & KATA_MUSOU)
152 set_action(creature_ptr, ACTION_NONE);
154 if (easy_open && (count_dt(creature_ptr, &y, &x, is_open, FALSE) == 1))
155 command_dir = coords_to_dir(creature_ptr, y, x);
158 command_rep = command_arg - 1;
159 creature_ptr->redraw |= (PR_STATE);
163 if (get_rep_dir(creature_ptr, &dir, FALSE)) {
166 y = creature_ptr->y + ddy[dir];
167 x = creature_ptr->x + ddx[dir];
168 g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
169 feat = get_feat_mimic(g_ptr);
170 if (!has_flag(f_info[feat].flags, FF_CLOSE)) {
171 msg_print(_("そこには閉じるものが見当たらない。", "You see nothing there to close."));
172 } else if (g_ptr->m_idx) {
173 take_turn(creature_ptr, 100);
174 msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
175 do_cmd_attack(creature_ptr, y, x, HISSATSU_NONE);
177 more = exe_close(creature_ptr, y, x);
182 disturb(creature_ptr, FALSE, FALSE);
186 * @brief 箱、床のトラップ解除処理双方の統合メインルーチン /
187 * Disarms a trap, or chest
190 void do_cmd_disarm(player_type *creature_ptr)
196 if (creature_ptr->wild_mode)
199 if (creature_ptr->special_defense & KATA_MUSOU)
200 set_action(creature_ptr, ACTION_NONE);
203 int num_traps = count_dt(creature_ptr, &y, &x, is_trap, TRUE);
204 int num_chests = count_chests(creature_ptr, &y, &x, TRUE);
205 if (num_traps || num_chests) {
206 bool too_many = (num_traps && num_chests) || (num_traps > 1) || (num_chests > 1);
208 command_dir = coords_to_dir(creature_ptr, y, x);
213 command_rep = command_arg - 1;
214 creature_ptr->redraw |= (PR_STATE);
218 if (get_rep_dir(creature_ptr, &dir, TRUE)) {
221 y = creature_ptr->y + ddy[dir];
222 x = creature_ptr->x + ddx[dir];
223 g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
224 feat = get_feat_mimic(g_ptr);
225 o_idx = chest_check(creature_ptr->current_floor_ptr, y, x, TRUE);
226 if (!is_trap(creature_ptr, feat) && !o_idx) {
227 msg_print(_("そこには解除するものが見当たらない。", "You see nothing there to disarm."));
228 } else if (g_ptr->m_idx && creature_ptr->riding != g_ptr->m_idx) {
229 msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
230 do_cmd_attack(creature_ptr, y, x, HISSATSU_NONE);
232 more = exe_disarm_chest(creature_ptr, y, x, o_idx);
234 more = exe_disarm(creature_ptr, y, x, dir);
239 disturb(creature_ptr, FALSE, FALSE);
243 * @brief 「打ち破る」動作コマンドのメインルーチン /
244 * Bash open a door, success based on character strength
248 * For a closed door, pval is positive if locked; negative if stuck.
250 * For an open door, pval is positive for a broken door.
252 * A closed door can be opened - harder if locked. Any door might be
253 * bashed open (and thereby broken). Bashing a door is (potentially)
254 * faster! You move into the door way. To open a stuck door, it must
255 * be bashed. A closed door can be jammed (see do_cmd_spike()).
257 * Creatures can also open or bash doors, see elsewhere.
260 void do_cmd_bash(player_type *creature_ptr)
266 if (creature_ptr->wild_mode)
269 if (creature_ptr->special_defense & KATA_MUSOU)
270 set_action(creature_ptr, ACTION_NONE);
273 command_rep = command_arg - 1;
274 creature_ptr->redraw |= (PR_STATE);
278 if (get_rep_dir(creature_ptr, &dir, FALSE)) {
280 y = creature_ptr->y + ddy[dir];
281 x = creature_ptr->x + ddx[dir];
282 g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
283 feat = get_feat_mimic(g_ptr);
284 if (!has_flag(f_info[feat].flags, FF_BASH)) {
285 msg_print(_("そこには体当たりするものが見当たらない。", "You see nothing there to bash."));
286 } else if (g_ptr->m_idx) {
287 take_turn(creature_ptr, 100);
288 msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
289 do_cmd_attack(creature_ptr, y, x, HISSATSU_NONE);
291 more = exe_bash(creature_ptr, y, x, dir);
296 disturb(creature_ptr, FALSE, FALSE);
301 * @brief 「くさびを打つ」ために必要なオブジェクトを所持しているかどうかの判定を返す /
302 * Find the index of some "spikes", if possible.
303 * @param ip くさびとして打てるオブジェクトのID
304 * @return オブジェクトがある場合TRUEを返す
307 * Let user choose a pile of spikes, perhaps?
310 static bool get_spike(player_type *creature_ptr, INVENTORY_IDX *ip)
312 for (INVENTORY_IDX i = 0; i < INVEN_PACK; i++) {
313 object_type *o_ptr = &creature_ptr->inventory_list[i];
317 if (o_ptr->tval == TV_SPIKE) {
327 * @brief 「くさびを打つ」動作コマンドのメインルーチン /
328 * Jam a closed door with a spike
329 * @param creature_ptr プレーヤーへの参照ポインタ
333 * This command may NOT be repeated
336 void do_cmd_spike(player_type *creature_ptr)
339 if (creature_ptr->wild_mode)
342 if (creature_ptr->special_defense & KATA_MUSOU)
343 set_action(creature_ptr, ACTION_NONE);
345 if (!get_rep_dir(creature_ptr, &dir, FALSE))
348 POSITION y = creature_ptr->y + ddy[dir];
349 POSITION x = creature_ptr->x + ddx[dir];
351 g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
352 FEAT_IDX feat = get_feat_mimic(g_ptr);
354 if (!has_flag(f_info[feat].flags, FF_SPIKE)) {
355 msg_print(_("そこにはくさびを打てるものが見当たらない。", "You see nothing there to spike."));
356 } else if (!get_spike(creature_ptr, &item)) {
357 msg_print(_("くさびを持っていない!", "You have no spikes!"));
358 } else if (g_ptr->m_idx) {
359 take_turn(creature_ptr, 100);
360 msg_print(_("モンスターが立ちふさがっている!", "There is a monster in the way!"));
361 do_cmd_attack(creature_ptr, y, x, HISSATSU_NONE);
363 take_turn(creature_ptr, 100);
364 msg_format(_("%sにくさびを打ち込んだ。", "You jam the %s with a spike."), f_name + f_info[feat].name);
365 cave_alter_feat(creature_ptr, y, x, FF_SPIKE);
366 vary_item(creature_ptr, item, -1);