OSDN Git Service

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