OSDN Git Service

Since its used as an adverb, replace "much slower" with "much more slowly" in the...
[hengband/hengband.git] / src / cmd-action / cmd-move.c
1 #include "cmd-action/cmd-move.h"
2 #include "action/action-limited.h"
3 #include "action/movement-execution.h"
4 #include "action/run-execution.h"
5 #include "cmd-io/cmd-save.h"
6 #include "core/asking-player.h"
7 #include "core/disturbance.h"
8 #include "core/output-updater.h"
9 #include "core/player-redraw-types.h"
10 #include "core/player-update-types.h"
11 #include "dungeon/dungeon.h"
12 #include "dungeon/quest.h"
13 #include "floor/cave.h"
14 #include "floor/floor-mode-changer.h"
15 #include "floor/wild.h"
16 #include "game-option/birth-options.h"
17 #include "game-option/input-options.h"
18 #include "game-option/play-record-options.h"
19 #include "game-option/special-options.h"
20 #include "grid/grid.h"
21 #include "info-reader/fixed-map-parser.h"
22 #include "io/input-key-requester.h"
23 #include "io/write-diary.h"
24 #include "mind/mind-ninja.h"
25 #include "player-info/avatar.h"
26 #include "player/attack-defense-types.h"
27 #include "player/player-move.h"
28 #include "player/special-defense-types.h"
29 #include "spell-realm/spells-hex.h"
30 #include "status/action-setter.h"
31 #include "system/floor-type-definition.h"
32 #include "system/system-variables.h"
33 #include "target/target-getter.h"
34 #include "util/bit-flags-calculator.h"
35 #include "view/display-messages.h"
36
37 /*!
38  * @brief フロア脱出時に出戻りが不可能だった場合に警告を加える処理
39  * @param down_stair TRUEならば階段を降りる処理、FALSEなら階段を昇る処理による内容
40  * @return フロア移動を実際に行うならTRUE、キャンセルする場合はFALSE
41  */
42 static bool confirm_leave_level(player_type *creature_ptr, bool down_stair)
43 {
44     quest_type *q_ptr = &quest[creature_ptr->current_floor_ptr->inside_quest];
45     if (confirm_quest && creature_ptr->current_floor_ptr->inside_quest
46         && (q_ptr->type == QUEST_TYPE_RANDOM || (q_ptr->flags & QUEST_FLAG_ONCE && q_ptr->status != QUEST_STATUS_COMPLETED)
47             || (q_ptr->flags & QUEST_FLAG_TOWER
48                 && ((q_ptr->status != QUEST_STATUS_STAGE_COMPLETED) || (down_stair && (quest[QUEST_TOWER1].status != QUEST_STATUS_COMPLETED)))))) {
49         msg_print(_("この階を一度去ると二度と戻って来られません。", "You can't come back here once you leave this floor."));
50         return get_check(_("本当にこの階を去りますか?", "Really leave this floor? "));
51     }
52
53     return TRUE;
54 }
55
56 /*!
57  * @brief 階段を使って階層を昇る処理 / Go up one level
58  * @return なし
59  */
60 void do_cmd_go_up(player_type *creature_ptr)
61 {
62     bool go_up = FALSE;
63     grid_type *g_ptr = &creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x];
64     feature_type *f_ptr = &f_info[g_ptr->feat];
65     int up_num = 0;
66     if (creature_ptr->special_defense & KATA_MUSOU)
67         set_action(creature_ptr, ACTION_NONE);
68
69     if (!has_flag(f_ptr->flags, FF_LESS)) {
70         msg_print(_("ここには上り階段が見当たらない。", "I see no up staircase here."));
71         return;
72     }
73
74     if (has_flag(f_ptr->flags, FF_QUEST)) {
75         if (!confirm_leave_level(creature_ptr, FALSE))
76             return;
77
78         if (is_echizen(creature_ptr))
79             msg_print(_("なんだこの階段は!", "What's this STAIRWAY!"));
80         else
81             msg_print(_("上の階に登った。", "You enter the up staircase."));
82
83         leave_quest_check(creature_ptr);
84         creature_ptr->current_floor_ptr->inside_quest = g_ptr->special;
85         if (!quest[creature_ptr->current_floor_ptr->inside_quest].status) {
86             if (quest[creature_ptr->current_floor_ptr->inside_quest].type != QUEST_TYPE_RANDOM) {
87                 init_flags = INIT_ASSIGN;
88                 parse_fixed_map(creature_ptr, "q_info.txt", 0, 0, 0, 0);
89             }
90
91             quest[creature_ptr->current_floor_ptr->inside_quest].status = QUEST_STATUS_TAKEN;
92         }
93
94         if (!creature_ptr->current_floor_ptr->inside_quest)
95             creature_ptr->current_floor_ptr->dun_level = 0;
96
97         creature_ptr->leaving = TRUE;
98         creature_ptr->oldpx = 0;
99         creature_ptr->oldpy = 0;
100         take_turn(creature_ptr, 100);
101         return;
102     }
103
104     if (!creature_ptr->current_floor_ptr->dun_level)
105         go_up = TRUE;
106     else
107         go_up = confirm_leave_level(creature_ptr, FALSE);
108
109     if (!go_up)
110         return;
111
112     take_turn(creature_ptr, 100);
113
114     if (autosave_l)
115         do_cmd_save_game(creature_ptr, TRUE);
116
117     if (creature_ptr->current_floor_ptr->inside_quest && quest[creature_ptr->current_floor_ptr->inside_quest].type == QUEST_TYPE_RANDOM) {
118         leave_quest_check(creature_ptr);
119         creature_ptr->current_floor_ptr->inside_quest = 0;
120     }
121
122     if (creature_ptr->current_floor_ptr->inside_quest && quest[creature_ptr->current_floor_ptr->inside_quest].type != QUEST_TYPE_RANDOM) {
123         leave_quest_check(creature_ptr);
124         creature_ptr->current_floor_ptr->inside_quest = g_ptr->special;
125         creature_ptr->current_floor_ptr->dun_level = 0;
126         up_num = 0;
127     } else {
128         if (has_flag(f_ptr->flags, FF_SHAFT)) {
129             prepare_change_floor_mode(creature_ptr, CFM_SAVE_FLOORS | CFM_UP | CFM_SHAFT);
130             up_num = 2;
131         } else {
132             prepare_change_floor_mode(creature_ptr, CFM_SAVE_FLOORS | CFM_UP);
133             up_num = 1;
134         }
135
136         if (creature_ptr->current_floor_ptr->dun_level - up_num < d_info[creature_ptr->dungeon_idx].mindepth)
137             up_num = creature_ptr->current_floor_ptr->dun_level;
138     }
139
140     if (record_stair)
141         exe_write_diary(creature_ptr, DIARY_STAIR, 0 - up_num, _("階段を上った", "climbed up the stairs to"));
142
143     if (is_echizen(creature_ptr))
144         msg_print(_("なんだこの階段は!", "What's this STAIRWAY!"));
145     else if (up_num == creature_ptr->current_floor_ptr->dun_level)
146         msg_print(_("地上に戻った。", "You go back to the surface."));
147     else
148         msg_print(_("階段を上って新たなる迷宮へと足を踏み入れた。", "You enter a maze of up staircases."));
149
150     creature_ptr->leaving = TRUE;
151 }
152
153 /*!
154  * @brief 階段を使って階層を降りる処理 / Go down one level
155  * @param creature_ptr プレーヤーへの参照ポインタ
156  * @return なし
157  */
158 void do_cmd_go_down(player_type *creature_ptr)
159 {
160     bool fall_trap = FALSE;
161     int down_num = 0;
162     if (creature_ptr->special_defense & KATA_MUSOU)
163         set_action(creature_ptr, ACTION_NONE);
164
165     grid_type *g_ptr = &creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x];
166     feature_type *f_ptr = &f_info[g_ptr->feat];
167     if (!has_flag(f_ptr->flags, FF_MORE)) {
168         msg_print(_("ここには下り階段が見当たらない。", "I see no down staircase here."));
169         return;
170     }
171
172     if (has_flag(f_ptr->flags, FF_TRAP))
173         fall_trap = TRUE;
174
175     if (has_flag(f_ptr->flags, FF_QUEST_ENTER)) {
176         do_cmd_quest(creature_ptr);
177         return;
178     }
179
180     if (has_flag(f_ptr->flags, FF_QUEST)) {
181         if (!confirm_leave_level(creature_ptr, TRUE))
182             return;
183
184         if (is_echizen(creature_ptr))
185             msg_print(_("なんだこの階段は!", "What's this STAIRWAY!"));
186         else
187             msg_print(_("下の階に降りた。", "You enter the down staircase."));
188
189         leave_quest_check(creature_ptr);
190         leave_tower_check(creature_ptr);
191         creature_ptr->current_floor_ptr->inside_quest = g_ptr->special;
192         if (!quest[creature_ptr->current_floor_ptr->inside_quest].status) {
193             if (quest[creature_ptr->current_floor_ptr->inside_quest].type != QUEST_TYPE_RANDOM) {
194                 init_flags = INIT_ASSIGN;
195                 parse_fixed_map(creature_ptr, "q_info.txt", 0, 0, 0, 0);
196             }
197
198             quest[creature_ptr->current_floor_ptr->inside_quest].status = QUEST_STATUS_TAKEN;
199         }
200
201         if (!creature_ptr->current_floor_ptr->inside_quest)
202             creature_ptr->current_floor_ptr->dun_level = 0;
203
204         creature_ptr->leaving = TRUE;
205         creature_ptr->oldpx = 0;
206         creature_ptr->oldpy = 0;
207         take_turn(creature_ptr, 100);
208         return;
209     }
210
211     DUNGEON_IDX target_dungeon = 0;
212     if (!creature_ptr->current_floor_ptr->dun_level) {
213         target_dungeon = has_flag(f_ptr->flags, FF_ENTRANCE) ? g_ptr->special : DUNGEON_ANGBAND;
214         if (ironman_downward && (target_dungeon != DUNGEON_ANGBAND)) {
215             msg_print(_("ダンジョンの入口は塞がれている!", "The entrance of this dungeon is closed!"));
216             return;
217         }
218
219         if (!max_dlv[target_dungeon]) {
220             msg_format(_("ここには%sの入り口(%d階相当)があります", "There is the entrance of %s (Danger level: %d)"), d_name + d_info[target_dungeon].name,
221                 d_info[target_dungeon].mindepth);
222             if (!get_check(_("本当にこのダンジョンに入りますか?", "Do you really get in this dungeon? ")))
223                 return;
224         }
225
226         creature_ptr->oldpx = creature_ptr->x;
227         creature_ptr->oldpy = creature_ptr->y;
228         creature_ptr->dungeon_idx = target_dungeon;
229         prepare_change_floor_mode(creature_ptr, CFM_FIRST_FLOOR);
230     }
231
232     take_turn(creature_ptr, 100);
233     if (autosave_l)
234         do_cmd_save_game(creature_ptr, TRUE);
235
236     if (has_flag(f_ptr->flags, FF_SHAFT))
237         down_num += 2;
238     else
239         down_num += 1;
240
241     if (!creature_ptr->current_floor_ptr->dun_level) {
242         creature_ptr->enter_dungeon = TRUE;
243         down_num = d_info[creature_ptr->dungeon_idx].mindepth;
244     }
245
246     if (record_stair) {
247         if (fall_trap)
248             exe_write_diary(creature_ptr, DIARY_STAIR, down_num, _("落とし戸に落ちた", "fell through a trap door"));
249         else
250             exe_write_diary(creature_ptr, DIARY_STAIR, down_num, _("階段を下りた", "climbed down the stairs to"));
251     }
252
253     if (fall_trap) {
254         msg_print(_("わざと落とし戸に落ちた。", "You deliberately jump through the trap door."));
255     } else {
256         if (target_dungeon) {
257             msg_format(_("%sへ入った。", "You entered %s."), d_text + d_info[creature_ptr->dungeon_idx].text);
258         } else {
259             if (is_echizen(creature_ptr))
260                 msg_print(_("なんだこの階段は!", "What's this STAIRWAY!"));
261             else
262                 msg_print(_("階段を下りて新たなる迷宮へと足を踏み入れた。", "You enter a maze of down staircases."));
263         }
264     }
265
266     creature_ptr->leaving = TRUE;
267
268     if (fall_trap) {
269         prepare_change_floor_mode(creature_ptr, CFM_SAVE_FLOORS | CFM_DOWN | CFM_RAND_PLACE | CFM_RAND_CONNECT);
270         return;
271     }
272
273     if (has_flag(f_ptr->flags, FF_SHAFT))
274         prepare_change_floor_mode(creature_ptr, CFM_SAVE_FLOORS | CFM_DOWN | CFM_SHAFT);
275     else
276         prepare_change_floor_mode(creature_ptr, CFM_SAVE_FLOORS | CFM_DOWN);
277 }
278
279 /*!
280  * @brief 「歩く」動作コマンドのメインルーチン /
281  * Support code for the "Walk" and "Jump" commands
282  * @param creature_ptr プレーヤーへの参照ポインタ
283  * @param pickup アイテムの自動拾いを行うならTRUE
284  * @return なし
285  */
286 void do_cmd_walk(player_type *creature_ptr, bool pickup)
287 {
288     if (command_arg) {
289         command_rep = command_arg - 1;
290         creature_ptr->redraw |= PR_STATE;
291         command_arg = 0;
292     }
293
294     bool more = FALSE;
295     DIRECTION dir;
296     if (get_rep_dir(creature_ptr, &dir, FALSE)) {
297         take_turn(creature_ptr, 100);
298         if ((dir != 5) && (creature_ptr->special_defense & KATA_MUSOU))
299             set_action(creature_ptr, ACTION_NONE);
300
301         if (creature_ptr->wild_mode)
302             creature_ptr->energy_use *= ((MAX_HGT + MAX_WID) / 2);
303
304         if (creature_ptr->action == ACTION_HAYAGAKE)
305             creature_ptr->energy_use = creature_ptr->energy_use * (45 - (creature_ptr->lev / 2)) / 100;
306
307         exe_movement(creature_ptr, dir, pickup, FALSE);
308         more = TRUE;
309     }
310
311     if (creature_ptr->wild_mode && !cave_has_flag_bold(creature_ptr->current_floor_ptr, creature_ptr->y, creature_ptr->x, FF_TOWN)) {
312         int tmp = 120 + creature_ptr->lev * 10 - wilderness[creature_ptr->y][creature_ptr->x].level + 5;
313         if (tmp < 1)
314             tmp = 1;
315
316         if (((wilderness[creature_ptr->y][creature_ptr->x].level + 5) > (creature_ptr->lev / 2)) && randint0(tmp) < (21 - creature_ptr->skill_stl)) {
317             msg_print(_("襲撃だ!", "You are ambushed !"));
318             creature_ptr->oldpy = randint1(MAX_HGT - 2);
319             creature_ptr->oldpx = randint1(MAX_WID - 2);
320             change_wild_mode(creature_ptr, TRUE);
321             take_turn(creature_ptr, 100);
322         }
323     }
324
325     if (!more)
326         disturb(creature_ptr, FALSE, FALSE);
327 }
328
329 /*!
330  * @brief 「走る」動作コマンドのメインルーチン /
331  * Start running.
332  * @param creature_ptr プレーヤーへの参照ポインタ
333  * @return なし
334  */
335 void do_cmd_run(player_type *creature_ptr)
336 {
337     DIRECTION dir;
338     if (cmd_limit_confused(creature_ptr))
339         return;
340
341     if (creature_ptr->special_defense & KATA_MUSOU)
342         set_action(creature_ptr, ACTION_NONE);
343
344     if (get_rep_dir(creature_ptr, &dir, FALSE)) {
345         creature_ptr->running = (command_arg ? command_arg : 1000);
346         run_step(creature_ptr, dir);
347     }
348 }
349
350 /*!
351  * @brief 「留まる」動作コマンドのメインルーチン /
352  * Stay still.  Search.  Enter stores.
353  * Pick up treasure if "pickup" is true.
354  * @param creature_ptr プレーヤーへの参照ポインタ
355  * @param pickup アイテムの自動拾いを行うならTRUE
356  * @return なし
357  */
358 void do_cmd_stay(player_type *creature_ptr, bool pickup)
359 {
360     u32b mpe_mode = MPE_STAYING | MPE_ENERGY_USE;
361     if (command_arg) {
362         command_rep = command_arg - 1;
363         creature_ptr->redraw |= (PR_STATE);
364         command_arg = 0;
365     }
366
367     take_turn(creature_ptr, 100);
368     if (pickup)
369         mpe_mode |= MPE_DO_PICKUP;
370
371     (void)move_player_effect(creature_ptr, creature_ptr->y, creature_ptr->x, mpe_mode);
372 }
373
374 /*!
375  * @brief 「休む」動作コマンドのメインルーチン /
376  * Resting allows a player to safely restore his hp     -RAK-
377  * @param creature_ptr プレーヤーへの参照ポインタ
378  * @return なし
379  */
380 void do_cmd_rest(player_type *creature_ptr)
381 {
382     set_action(creature_ptr, ACTION_NONE);
383     if ((creature_ptr->pclass == CLASS_BARD) && (SINGING_SONG_EFFECT(creature_ptr) || INTERUPTING_SONG_EFFECT(creature_ptr)))
384         stop_singing(creature_ptr);
385
386     if (hex_spelling_any(creature_ptr))
387         stop_hex_spell_all(creature_ptr);
388
389     if (command_arg <= 0) {
390         concptr p = _("休憩 (0-9999, '*' で HP/MP全快, '&' で必要なだけ): ", "Rest (0-9999, '*' for HP/SP, '&' as needed): ");
391         char out_val[80];
392         strcpy(out_val, "&");
393         if (!get_string(p, out_val, 4))
394             return;
395
396         if (out_val[0] == '&') {
397             command_arg = COMMAND_ARG_REST_UNTIL_DONE;
398         } else if (out_val[0] == '*') {
399             command_arg = COMMAND_ARG_REST_FULL_HEALING;
400         } else {
401             command_arg = (COMMAND_ARG)atoi(out_val);
402             if (command_arg <= 0)
403                 return;
404         }
405     }
406
407     if (command_arg > 9999)
408         command_arg = 9999;
409
410     if (creature_ptr->special_defense & NINJA_S_STEALTH)
411         set_superstealth(creature_ptr, FALSE);
412
413     take_turn(creature_ptr, 100);
414     if (command_arg > 100)
415         chg_virtue(creature_ptr, V_DILIGENCE, -1);
416
417     if ((creature_ptr->chp == creature_ptr->mhp) && (creature_ptr->csp == creature_ptr->msp) && !creature_ptr->blind && !creature_ptr->confused
418         && !creature_ptr->poisoned && !creature_ptr->afraid && !creature_ptr->stun && !creature_ptr->cut && !creature_ptr->slow && !creature_ptr->paralyzed
419         && !creature_ptr->image && !creature_ptr->word_recall && !creature_ptr->alter_reality)
420         chg_virtue(creature_ptr, V_DILIGENCE, -1);
421
422     creature_ptr->resting = command_arg;
423     creature_ptr->action = ACTION_REST;
424     creature_ptr->update |= PU_BONUS;
425     update_creature(creature_ptr);
426     creature_ptr->redraw |= (PR_STATE);
427     update_output(creature_ptr);
428     if (need_term_fresh(creature_ptr))
429         term_fresh();
430 }