OSDN Git Service

35bc1b081fd181d641b3b7885a9b0c411e32dcf9
[hengbandforosx/hengbandosx.git] / src / cmd-action / cmd-others.c
1 /*!
2  * @brief その他の小さなコマンド処理群 (探索、汎用グリッド処理、自殺/引退/切腹)
3  * @date 2014/01/02
4  * @author
5  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
6  *
7  * This software may be copied and distributed for educational, research,
8  * and not for profit purposes provided that this copyright and statement
9  * are included in all such copies.  Other copyrights may also apply.
10  */
11
12 #include "cmd-action/cmd-others.h"
13 #include "action/open-close-execution.h"
14 #include "action/tunnel-execution.h"
15 #include "cmd-action/cmd-attack.h"
16 #include "core/asking-player.h"
17 #include "core/disturbance.h"
18 #include "core/player-redraw-types.h"
19 #include "floor/geometry.h"
20 #include "game-option/game-play-options.h"
21 #include "grid/feature.h"
22 #include "grid/grid.h"
23 #include "io/input-key-acceptor.h"
24 #include "io/input-key-requester.h"
25 #include "io/write-diary.h"
26 #include "main/music-definitions-table.h"
27 #include "main/sound-of-music.h"
28 #include "player/attack-defense-types.h"
29 #include "player/player-move.h"
30 #include "player/special-defense-types.h"
31 #include "status/action-setter.h"
32 #include "system/floor-type-definition.h"
33 #include "target/target-getter.h"
34 #include "term/screen-processor.h"
35 #include "util/bit-flags-calculator.h"
36 #include "view/display-messages.h"
37 #include "world/world.h"
38
39 /*!
40  * @brief 探索コマンドのメインルーチン / Simple command to "search" for one turn
41  * @return なし
42  */
43 void do_cmd_search(player_type *creature_ptr)
44 {
45     if (command_arg) {
46         command_rep = command_arg - 1;
47         creature_ptr->redraw |= PR_STATE;
48         command_arg = 0;
49     }
50
51     take_turn(creature_ptr, 100);
52     search(creature_ptr);
53 }
54
55 static bool exe_alter(player_type *creature_ptr)
56 {
57     DIRECTION dir;
58     if (!get_rep_dir(creature_ptr, &dir, TRUE))
59         return FALSE;
60
61     POSITION y = creature_ptr->y + ddy[dir];
62     POSITION x = creature_ptr->x + ddx[dir];
63     grid_type *g_ptr;
64     g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
65     FEAT_IDX feat = get_feat_mimic(g_ptr);
66     feature_type *f_ptr;
67     f_ptr = &f_info[feat];
68     take_turn(creature_ptr, 100);
69     if (g_ptr->m_idx) {
70         do_cmd_attack(creature_ptr, y, x, 0);
71         return FALSE;
72     }
73     
74     if (has_flag(f_ptr->flags, FF_OPEN))
75         return exe_open(creature_ptr, y, x);
76     
77     if (has_flag(f_ptr->flags, FF_BASH))
78         return exe_bash(creature_ptr, y, x, dir);
79     
80     if (has_flag(f_ptr->flags, FF_TUNNEL))
81         return exe_tunnel(creature_ptr, y, x);
82     
83     if (has_flag(f_ptr->flags, FF_CLOSE))
84         return exe_close(creature_ptr, y, x);
85     
86     if (has_flag(f_ptr->flags, FF_DISARM))
87         return exe_disarm(creature_ptr, y, x, dir);
88
89     msg_print(_("何もない空中を攻撃した。", "You attack the empty air."));
90     return FALSE;
91 }
92
93 /*!
94  * @brief 特定のマスに影響を及ぼすための汎用的コマンド / Manipulate an adjacent grid in some way
95  * @return なし
96  * @details
97  */
98 void do_cmd_alter(player_type *creature_ptr)
99 {
100     if (creature_ptr->special_defense & KATA_MUSOU)
101         set_action(creature_ptr, ACTION_NONE);
102
103     if (command_arg) {
104         command_rep = command_arg - 1;
105         creature_ptr->redraw |= PR_STATE;
106         command_arg = 0;
107     }
108
109     if (!exe_alter(creature_ptr))
110         disturb(creature_ptr, FALSE, FALSE);
111 }
112
113 /*!
114  * @brief 自殺/引退/切腹の確認
115  * @param なし
116  * @return 自殺/引退/切腹を実施するならTRUE、キャンセルならFALSE
117  */
118 static bool decide_suicide(void)
119 {
120     if (current_world_ptr->noscore)
121         return TRUE;
122
123     prt(_("確認のため '@' を押して下さい。", "Please verify SUICIDE by typing the '@' sign: "), 0, 0);
124     flush();
125     int i = inkey();
126     prt("", 0, 0);
127     return i == '@';
128 }
129
130 static void accept_winner_message(player_type *creature_ptr)
131 {
132     if (!current_world_ptr->total_winner || !last_words)
133         return;
134
135     char buf[1024] = "";
136     play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_WINNER);
137     do {
138         while (!get_string(_("*勝利*メッセージ: ", "*Winning* message: "), buf, sizeof(buf)))
139             ;
140     } while (!get_check_strict(creature_ptr, _("よろしいですか?", "Are you sure? "), CHECK_NO_HISTORY));
141
142     if (buf[0]) {
143         creature_ptr->last_message = string_make(buf);
144         msg_print(creature_ptr->last_message);
145     }
146 }
147
148 /*!
149  * @brief 自殺するコマンドのメインルーチン
150  * commit suicide
151  * @return なし
152  * @details
153  */
154 void do_cmd_suicide(player_type *creature_ptr)
155 {
156     flush();
157     if (current_world_ptr->total_winner) {
158         if (!get_check_strict(creature_ptr, _("引退しますか? ", "Do you want to retire? "), CHECK_NO_HISTORY))
159             return;
160     } else {
161         if (!get_check(_("本当に自殺しますか?", "Do you really want to commit suicide? ")))
162             return;
163     }
164
165     if (!decide_suicide())
166         return;
167
168     if (creature_ptr->last_message)
169         string_free(creature_ptr->last_message);
170
171     creature_ptr->last_message = NULL;
172     accept_winner_message(creature_ptr);
173     creature_ptr->playing = FALSE;
174     creature_ptr->is_dead = TRUE;
175     creature_ptr->leaving = TRUE;
176     if (!current_world_ptr->total_winner) {
177         exe_write_diary(creature_ptr, DIARY_DESCRIPTION, 0, _("ダンジョンの探索に絶望して自殺した。", "gave up all hope to commit suicide."));
178         exe_write_diary(creature_ptr, DIARY_GAMESTART, 1, _("-------- ゲームオーバー --------", "--------   Game  Over   --------"));
179         exe_write_diary(creature_ptr, DIARY_DESCRIPTION, 1, "\n\n\n\n");
180     }
181
182     (void)strcpy(creature_ptr->died_from, _("途中終了", "Quitting"));
183 }