OSDN Git Service

[Refactor] #40575 Separated input_racial_technique_selection() from do_cmd_racial_power()
[hengband/hengband.git] / src / cmd-action / cmd-racial.c
1 #include "cmd-action/cmd-racial.h"
2 #include "action/action-limited.h"
3 #include "action/mutation-execution.h"
4 #include "core/asking-player.h"
5 #include "core/player-redraw-types.h"
6 #include "core/player-update-types.h"
7 #include "core/window-redrawer.h"
8 #include "game-option/text-display-options.h"
9 #include "io/command-repeater.h"
10 #include "io/input-key-requester.h"
11 #include "main/sound-of-music.h"
12 #include "mutation/mutation-flag-types.h"
13 #include "player/attack-defense-types.h"
14 #include "player/player-damage.h"
15 #include "player/special-defense-types.h"
16 #include "racial/class-racial-switcher.h"
17 #include "racial/mutation-racial-selector.h"
18 #include "racial/race-racial-switcher.h"
19 #include "racial/racial-switcher.h"
20 #include "racial/racial-util.h"
21 #include "status/action-setter.h"
22 #include "term/screen-processor.h"
23 #include "util/int-char-converter.h"
24
25 static bool input_racial_technique_selection(player_type *creature_ptr, rc_type *rc_ptr)
26 {
27     switch (rc_ptr->choice) {
28     case '0':
29         screen_load();
30         free_turn(creature_ptr);
31         return TRUE;
32     case '8':
33     case 'k':
34     case 'K':
35         rc_ptr->menu_line += (rc_ptr->num - 1);
36         return FALSE;
37     case '2':
38     case 'j':
39     case 'J':
40         rc_ptr->menu_line++;
41         return FALSE;
42     case '6':
43     case 'l':
44     case 'L':
45     case '4':
46     case 'h':
47     case 'H':
48         if (rc_ptr->menu_line > 18)
49             rc_ptr->menu_line -= 18;
50         else if (rc_ptr->menu_line + 18 <= rc_ptr->num)
51             rc_ptr->menu_line += 18;
52
53         return FALSE;
54     case 'x':
55     case 'X':
56     case '\r':
57         rc_ptr->command_code = rc_ptr->menu_line - 1;
58         rc_ptr->ask = FALSE;
59         return FALSE;
60     default:
61         return FALSE;
62     }
63 }
64
65 /*!
66  * @brief レイシャル・パワーコマンドのメインルーチン / Allow user to choose a power (racial / mutation) to activate
67  * @param creature_ptr プレーヤーへの参照ポインタ
68  * @return なし
69  */
70 void do_cmd_racial_power(player_type *creature_ptr)
71 {
72     if (creature_ptr->wild_mode)
73         return;
74
75     if (cmd_limit_confused(creature_ptr)) {
76         free_turn(creature_ptr);
77         return;
78     }
79
80     if (creature_ptr->special_defense & (KATA_MUSOU | KATA_KOUKIJIN))
81         set_action(creature_ptr, ACTION_NONE);
82
83     rc_type tmp_rc;
84     rc_type *rc_ptr = initialize_rc_type(creature_ptr, &tmp_rc);
85     switch_class_racial(creature_ptr, rc_ptr);
86     if (creature_ptr->mimic_form)
87         switch_mimic_racial(creature_ptr, rc_ptr);
88     else
89         switch_race_racial(creature_ptr, rc_ptr);
90
91     select_mutation_racial(creature_ptr, rc_ptr);
92     rc_ptr->flag = FALSE;
93     rc_ptr->redraw = FALSE;
94
95     (void)strnfmt(rc_ptr->out_val, 78,
96         _("(特殊能力 %c-%c, *'で一覧, ESCで中断) どの特殊能力を使いますか?", "(Powers %c-%c, *=List, ESC=exit) Use which power? "),
97         I2A(0), (rc_ptr->num <= 26) ? I2A(rc_ptr->num - 1) : '0' + rc_ptr->num - 27);
98
99     if (!repeat_pull(&rc_ptr->command_code) || rc_ptr->command_code < 0 || rc_ptr->command_code >= rc_ptr->num) {
100         if (use_menu)
101             screen_save();
102
103         rc_ptr->choice = (always_show_list || use_menu) ? ESCAPE : 1;
104         while (!rc_ptr->flag) {
105             if (rc_ptr->choice == ESCAPE)
106                 rc_ptr->choice = ' ';
107             else if (!get_com(rc_ptr->out_val, &rc_ptr->choice, FALSE))
108                 break;
109
110             if (use_menu && rc_ptr->choice != ' ') {
111                 if (input_racial_technique_selection(creature_ptr, rc_ptr))
112                     return;
113
114                 if (rc_ptr->menu_line > rc_ptr->num)
115                     rc_ptr->menu_line -= rc_ptr->num;
116             }
117
118             if ((rc_ptr->choice == ' ') || (rc_ptr->choice == '*') || (rc_ptr->choice == '?') || (use_menu && rc_ptr->ask)) {
119                 if (!rc_ptr->redraw || use_menu) {
120                     byte y = 1;
121                     byte x = 0;
122                     int ctr = 0;
123                     char dummy[80];
124                     strcpy(dummy, "");
125                     rc_ptr->redraw = TRUE;
126                     if (!use_menu)
127                         screen_save();
128
129                     if (rc_ptr->num < 18)
130                         prt(_("                            Lv   MP 失率", "                            Lv Cost Fail"), y++, x);
131                     else
132                         prt(_("                            Lv   MP 失率                            Lv   MP 失率",
133                                 "                            Lv Cost Fail                            Lv Cost Fail"),
134                             y++, x);
135
136                     while (ctr < rc_ptr->num) {
137                         TERM_LEN x1 = ((ctr < 18) ? x : x + 40);
138                         TERM_LEN y1 = ((ctr < 18) ? y + ctr : y + ctr - 18);
139                         if (use_menu) {
140                             if (ctr == (rc_ptr->menu_line - 1))
141                                 strcpy(dummy, _(" 》 ", " >  "));
142                             else
143                                 strcpy(dummy, "    ");
144                         } else {
145                             char letter;
146                             if (ctr < 26)
147                                 letter = I2A(ctr);
148                             else
149                                 letter = '0' + ctr - 26;
150                             sprintf(dummy, " %c) ", letter);
151                         }
152
153                         strcat(dummy,
154                             format("%-23.23s %2d %4d %3d%%", rc_ptr->power_desc[ctr].racial_name, rc_ptr->power_desc[ctr].min_level, rc_ptr->power_desc[ctr].cost,
155                                 100 - racial_chance(creature_ptr, &rc_ptr->power_desc[ctr])));
156                         prt(dummy, y1, x1);
157                         ctr++;
158                     }
159                 } else {
160                     rc_ptr->redraw = FALSE;
161                     screen_load();
162                 }
163
164                 continue;
165             }
166
167             if (!use_menu) {
168                 if (rc_ptr->choice == '\r' && rc_ptr->num == 1)
169                     rc_ptr->choice = 'a';
170
171                 if (isalpha(rc_ptr->choice)) {
172                     rc_ptr->ask = (isupper(rc_ptr->choice));
173                     if (rc_ptr->ask)
174                         rc_ptr->choice = (char)tolower(rc_ptr->choice);
175
176                     rc_ptr->command_code = (islower(rc_ptr->choice) ? A2I(rc_ptr->choice) : -1);
177                 } else {
178                     rc_ptr->ask = FALSE;
179                     rc_ptr->command_code = rc_ptr->choice - '0' + 26;
180                 }
181             }
182
183             if ((rc_ptr->command_code < 0) || (rc_ptr->command_code >= rc_ptr->num)) {
184                 bell();
185                 continue;
186             }
187
188             if (rc_ptr->ask) {
189                 char tmp_val[160];
190                 (void)strnfmt(tmp_val, 78, _("%sを使いますか? ", "Use %s? "), rc_ptr->power_desc[rc_ptr->command_code].racial_name);
191                 if (!get_check(tmp_val))
192                     continue;
193             }
194
195             rc_ptr->flag = TRUE;
196         }
197
198         if (rc_ptr->redraw)
199             screen_load();
200
201         if (!rc_ptr->flag) {
202             free_turn(creature_ptr);
203             return;
204         }
205
206         repeat_push(rc_ptr->command_code);
207     }
208
209     switch (racial_aux(creature_ptr, &rc_ptr->power_desc[rc_ptr->command_code])) {
210     case 1:
211         if (rc_ptr->power_desc[rc_ptr->command_code].number < 0)
212             rc_ptr->cast = exe_racial_power(creature_ptr, rc_ptr->power_desc[rc_ptr->command_code].number);
213         else
214             rc_ptr->cast = exe_mutation_power(creature_ptr, rc_ptr->power_desc[rc_ptr->command_code].number);
215         break;
216     case 0:
217         rc_ptr->cast = FALSE;
218         break;
219     case -1:
220         rc_ptr->cast = TRUE;
221         break;
222     }
223
224     if (!rc_ptr->cast) {
225         free_turn(creature_ptr);
226         return;
227     }
228
229     int racial_cost = rc_ptr->power_desc[rc_ptr->command_code].racial_cost;
230     if (racial_cost == 0)
231         return;
232
233     int actual_racial_cost = racial_cost / 2 + randint1(racial_cost / 2);
234     if (creature_ptr->csp < actual_racial_cost) {
235         actual_racial_cost -= creature_ptr->csp;
236         creature_ptr->csp = 0;
237         take_hit(creature_ptr, DAMAGE_USELIFE, actual_racial_cost, _("過度の集中", "concentrating too hard"), -1);
238     } else
239         creature_ptr->csp -= actual_racial_cost;
240
241     creature_ptr->redraw |= PR_HP | PR_MANA;
242     creature_ptr->window |= PW_PLAYER | PW_SPELL;
243 }