OSDN Git Service

[Release] 3.0.0Alpha48
[hengbandforosx/hengbandosx.git] / src / cmd-action / cmd-others.cpp
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-base/player-class.h"
29 #include "player-info/samurai-data-type.h"
30 #include "player-status/player-energy.h"
31 #include "player/attack-defense-types.h"
32 #include "player/player-move.h"
33 #include "player/special-defense-types.h"
34 #include "status/action-setter.h"
35 #include "system/floor-type-definition.h"
36 #include "system/grid-type-definition.h"
37 #include "system/player-type-definition.h"
38 #include "target/target-getter.h"
39 #include "term/screen-processor.h"
40 #include "util/bit-flags-calculator.h"
41 #include "view/display-messages.h"
42 #include "world/world.h"
43
44 /*!
45  * @brief 探索コマンドのメインルーチン / Simple command to "search" for one turn
46  */
47 void do_cmd_search(PlayerType *player_ptr)
48 {
49     if (command_arg) {
50         command_rep = command_arg - 1;
51         player_ptr->redraw |= PR_STATE;
52         command_arg = 0;
53     }
54
55     PlayerEnergy(player_ptr).set_player_turn_energy(100);
56     search(player_ptr);
57
58     if (player_ptr->action == ACTION_SEARCH)
59         search(player_ptr);
60 }
61
62 static bool exe_alter(PlayerType *player_ptr)
63 {
64     DIRECTION dir;
65     if (!get_rep_dir(player_ptr, &dir, true))
66         return false;
67
68     POSITION y = player_ptr->y + ddy[dir];
69     POSITION x = player_ptr->x + ddx[dir];
70     grid_type *g_ptr;
71     g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
72     FEAT_IDX feat = g_ptr->get_feat_mimic();
73     feature_type *f_ptr;
74     f_ptr = &f_info[feat];
75     PlayerEnergy(player_ptr).set_player_turn_energy(100);
76     if (g_ptr->m_idx) {
77         do_cmd_attack(player_ptr, y, x, HISSATSU_NONE);
78         return false;
79     }
80     
81     if (f_ptr->flags.has(FloorFeatureType::OPEN))
82         return exe_open(player_ptr, y, x);
83     
84     if (f_ptr->flags.has(FloorFeatureType::BASH))
85         return exe_bash(player_ptr, y, x, dir);
86     
87     if (f_ptr->flags.has(FloorFeatureType::TUNNEL))
88         return exe_tunnel(player_ptr, y, x);
89     
90     if (f_ptr->flags.has(FloorFeatureType::CLOSE))
91         return exe_close(player_ptr, y, x);
92     
93     if (f_ptr->flags.has(FloorFeatureType::DISARM))
94         return exe_disarm(player_ptr, y, x, dir);
95
96     msg_print(_("何もない空中を攻撃した。", "You attack the empty air."));
97     return false;
98 }
99
100 /*!
101  * @brief 特定のマスに影響を及ぼすための汎用的コマンド / Manipulate an adjacent grid in some way
102  * @details
103  */
104 void do_cmd_alter(PlayerType *player_ptr)
105 {
106     PlayerClass(player_ptr).break_samurai_stance({ SamuraiStanceType::MUSOU });
107
108     if (command_arg) {
109         command_rep = command_arg - 1;
110         player_ptr->redraw |= PR_STATE;
111         command_arg = 0;
112     }
113
114     if (!exe_alter(player_ptr))
115         disturb(player_ptr, false, false);
116 }
117
118 /*!
119  * @brief 自殺/引退/切腹の確認
120  * @param なし
121  * @return 自殺/引退/切腹を実施するならTRUE、キャンセルならFALSE
122  */
123 static bool decide_suicide(void)
124 {
125     if (w_ptr->noscore)
126         return true;
127
128     prt(_("確認のため '@' を押して下さい。", "Please verify SUICIDE by typing the '@' sign: "), 0, 0);
129     flush();
130     int i = inkey();
131     prt("", 0, 0);
132     return i == '@';
133 }
134
135 static void accept_winner_message(PlayerType *player_ptr)
136 {
137     if (!w_ptr->total_winner || !last_words)
138         return;
139
140     char buf[1024] = "";
141     play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_WINNER);
142     do {
143         while (!get_string(_("*勝利*メッセージ: ", "*Winning* message: "), buf, sizeof(buf)))
144             ;
145     } while (!get_check_strict(player_ptr, _("よろしいですか?", "Are you sure? "), CHECK_NO_HISTORY));
146
147     if (buf[0]) {
148         player_ptr->last_message = string_make(buf);
149         msg_print(player_ptr->last_message);
150     }
151 }
152
153 /*!
154  * @brief 自殺するコマンドのメインルーチン
155  * commit suicide
156  * @details
157  */
158 void do_cmd_suicide(PlayerType *player_ptr)
159 {
160     flush();
161     if (w_ptr->total_winner) {
162         if (!get_check_strict(player_ptr, _("引退しますか? ", "Do you want to retire? "), CHECK_NO_HISTORY))
163             return;
164     } else {
165         if (!get_check(_("本当に自殺しますか?", "Do you really want to commit suicide? ")))
166             return;
167     }
168
169     if (!decide_suicide())
170         return;
171
172     if (player_ptr->last_message)
173         string_free(player_ptr->last_message);
174
175     player_ptr->last_message = nullptr;
176     player_ptr->playing = false;
177     player_ptr->is_dead = true;
178     player_ptr->leaving = true;
179     if (w_ptr->total_winner) {
180         accept_winner_message(player_ptr);
181         add_retired_class(player_ptr->pclass);
182     } else {
183         play_music(TERM_XTRA_MUSIC_BASIC, MUSIC_BASIC_GAMEOVER);
184         exe_write_diary(player_ptr, DIARY_DESCRIPTION, 0, _("ダンジョンの探索に絶望して自殺した。", "gave up all hope to commit suicide."));
185         exe_write_diary(player_ptr, DIARY_GAMESTART, 1, _("-------- ゲームオーバー --------", "--------   Game  Over   --------"));
186         exe_write_diary(player_ptr, DIARY_DESCRIPTION, 1, "\n\n\n\n");
187     }
188
189     (void)strcpy(player_ptr->died_from, _("途中終了", "Quitting"));
190 }