OSDN Git Service

[Refactor] #40392 Reshaped birth-select-realm.c
[hengband/hengband.git] / src / birth / birth-select-realm.c
1 #include "system/angband.h"
2 #include "birth/birth-select-realm.h"
3 #include "term/gameterm.h"
4 #include "birth/birth-explanations-table.h"
5 #include "birth/birth-util.h"
6
7 static byte count_realm_selection(s32b choices, int* count)
8 {
9     byte auto_select = REALM_NONE;
10     if (choices & CH_LIFE) {
11         (*count)++;
12         auto_select = REALM_LIFE;
13     }
14
15     if (choices & CH_SORCERY) {
16         (*count)++;
17         auto_select = REALM_SORCERY;
18     }
19
20     if (choices & CH_NATURE) {
21         (*count)++;
22         auto_select = REALM_NATURE;
23     }
24
25     if (choices & CH_CHAOS) {
26         (*count)++;
27         auto_select = REALM_CHAOS;
28     }
29
30     if (choices & CH_DEATH) {
31         (*count)++;
32         auto_select = REALM_DEATH;
33     }
34
35     if (choices & CH_TRUMP) {
36         (*count)++;
37         auto_select = REALM_TRUMP;
38     }
39
40     if (choices & CH_ARCANE) {
41         (*count)++;
42         auto_select = REALM_ARCANE;
43     }
44
45     if (choices & CH_ENCHANT) {
46         (*count)++;
47         auto_select = REALM_CRAFT;
48     }
49
50     if (choices & CH_DAEMON) {
51         (*count)++;
52         auto_select = REALM_DAEMON;
53     }
54
55     if (choices & CH_CRUSADE) {
56         (*count)++;
57         auto_select = REALM_CRUSADE;
58     }
59
60     if (choices & CH_MUSIC) {
61         (*count)++;
62         auto_select = REALM_MUSIC;
63     }
64
65     if (choices & CH_HISSATSU) {
66         (*count)++;
67         auto_select = REALM_HISSATSU;
68     }
69
70     if (choices & CH_HEX) {
71         (*count)++;
72         auto_select = REALM_HEX;
73     }
74
75     return auto_select;
76 }
77
78 /*!
79  * @brief プレイヤーの魔法領域を選択する / Choose from one of the available magical realms
80  * @param choices 選択可能な魔法領域のビット配列
81  * @param count 選択可能な魔法領域を返すポインタ群。
82  * @return 選択した魔法領域のID
83  */
84 static byte select_realm(player_type* creature_ptr, s32b choices, int* count)
85 {
86     byte auto_select = count_realm_selection(choices, count);
87     clear_from(10);
88
89     /* Auto-select the realm */
90     if ((*count) < 2)
91         return auto_select;
92
93     /* Constraint to the 1st realm */
94     if (creature_ptr->realm2 != 255) {
95         if (creature_ptr->pclass == CLASS_PRIEST) {
96             if (is_good_realm(creature_ptr->realm1)) {
97                 choices &= ~(CH_DEATH | CH_DAEMON);
98             } else {
99                 choices &= ~(CH_LIFE | CH_CRUSADE);
100             }
101         }
102     }
103
104     /* Extra info */
105     put_str(_("注意:魔法の領域の選択によりあなたが習得する呪文のタイプが決まります。",
106                 "Note: The realm of magic will determine which spells you can learn."),
107         23, 5);
108
109     int cs = 0;
110     int n = 0;
111     char p2 = ')';
112     char sym[VALID_REALM];
113     char buf[80];
114     int picks[VALID_REALM] = { 0 };
115     for (int i = 0; i < 32; i++) {
116         /* Analize realms */
117         if (choices & (1L << i)) {
118             if (creature_ptr->realm1 == i + 1) {
119                 if (creature_ptr->realm2 == 255)
120                     cs = n;
121                 else
122                     continue;
123             }
124             if (creature_ptr->realm2 == i + 1)
125                 cs = n;
126
127             sym[n] = I2A(n);
128
129             sprintf(buf, "%c%c %s", sym[n], p2, realm_names[i + 1]);
130             put_str(buf, 12 + (n / 5), 2 + 15 * (n % 5));
131             picks[n++] = i + 1;
132         }
133     }
134
135     char cur[80];
136     sprintf(cur, "%c%c %s", '*', p2, _("ランダム", "Random"));
137
138     /* Get a realm */
139     int k = -1;
140     int os = n;
141     while (TRUE) {
142         /* Move Cursol */
143         if (cs != os) {
144             c_put_str(TERM_WHITE, cur, 12 + (os / 5), 2 + 15 * (os % 5));
145
146             if (cs == n) {
147                 sprintf(cur, "%c%c %s", '*', p2, _("ランダム", "Random"));
148             } else {
149                 sprintf(cur, "%c%c %s", sym[cs], p2, realm_names[picks[cs]]);
150                 sprintf(buf, "%s", realm_names[picks[cs]]);
151                 c_put_str(TERM_L_BLUE, buf, 3, 40);
152                 prt(_("の特徴", ": Characteristic"), 3, 40 + strlen(buf));
153                 prt(realm_subinfo[technic2magic(picks[cs]) - 1], 4, 40);
154             }
155             c_put_str(TERM_YELLOW, cur, 12 + (cs / 5), 2 + 15 * (cs % 5));
156             os = cs;
157         }
158
159         if (k >= 0)
160             break;
161
162         sprintf(buf, _("領域を選んで下さい(%c-%c) ('='初期オプション設定): ", "Choose a realm (%c-%c) ('=' for options): "), sym[0], sym[n - 1]);
163
164         put_str(buf, 10, 10);
165         char c = inkey();
166         if (c == 'Q')
167             birth_quit();
168
169         if (c == 'S')
170             return 255;
171
172         if (c == ' ' || c == '\r' || c == '\n') {
173             if (cs == n) {
174                 k = randint0(n);
175                 break;
176             } else {
177                 k = cs;
178                 break;
179             }
180         }
181
182         if (c == '*') {
183             k = randint0(n);
184             break;
185         }
186
187         if (c == '8') {
188             if (cs >= 5)
189                 cs -= 5;
190         }
191
192         if (c == '4') {
193             if (cs > 0)
194                 cs--;
195         }
196
197         if (c == '6') {
198             if (cs < n)
199                 cs++;
200         }
201
202         if (c == '2') {
203             if ((cs + 5) <= n)
204                 cs += 5;
205         }
206
207         k = (islower(c) ? A2I(c) : -1);
208         if ((k >= 0) && (k < n)) {
209             cs = k;
210             continue;
211         }
212
213         k = (isupper(c) ? (26 + c - 'A') : -1);
214         if ((k >= 26) && (k < n)) {
215             cs = k;
216             continue;
217         } else
218             k = -1;
219
220         if (c == '?') {
221             show_help(creature_ptr, _("jmagic.txt#MagicRealms", "magic.txt#MagicRealms"));
222         } else if (c == '=') {
223             screen_save();
224             do_cmd_options_aux(OPT_PAGE_BIRTH, _("初期オプション((*)はスコアに影響)", "Birth option((*)s effect score)"));
225
226             screen_load();
227         } else if (c != '2' && c != '4' && c != '6' && c != '8')
228             bell();
229     }
230
231     clear_from(10);
232     return (byte)(picks[k]);
233 }
234
235 /*!
236  * @brief 選択した魔法領域の解説を表示する / Choose the magical realms
237  * @return ユーザが魔法領域の確定を選んだらTRUEを返す。
238  */
239 bool get_player_realms(player_type* creature_ptr)
240 {
241     /* Clean up infomation of modifications */
242     put_str("                                   ", 3, 40);
243     put_str("                                   ", 4, 40);
244     put_str("                                   ", 5, 40);
245
246     /* Select the first realm */
247     creature_ptr->realm1 = REALM_NONE;
248     creature_ptr->realm2 = 255;
249     while (TRUE) {
250         char temp[80 * 10];
251         concptr t;
252         int count = 0;
253         creature_ptr->realm1 = select_realm(creature_ptr, realm_choices1[creature_ptr->pclass], &count);
254
255         if (255 == creature_ptr->realm1)
256             return FALSE;
257         if (!creature_ptr->realm1)
258             break;
259
260         /* Clean up*/
261         clear_from(10);
262         put_str("                                   ", 3, 40);
263         put_str("                                   ", 4, 40);
264         put_str("                                   ", 5, 40);
265
266         roff_to_buf(realm_explanations[technic2magic(creature_ptr->realm1) - 1], 74, temp, sizeof(temp));
267         t = temp;
268         for (int i = 0; i < 10; i++) {
269             if (t[0] == 0)
270                 break;
271             else {
272                 prt(t, 12 + i, 3);
273                 t += strlen(t) + 1;
274             }
275         }
276
277         if (count < 2) {
278             prt(_("何かキーを押してください", "Hit any key."), 0, 0);
279             (void)inkey();
280             prt("", 0, 0);
281             break;
282         } else if (get_check_strict(_("よろしいですか?", "Are you sure? "), CHECK_DEFAULT_Y))
283             break;
284     }
285
286     /* Select the second realm */
287     creature_ptr->realm2 = REALM_NONE;
288     if (creature_ptr->realm1) {
289         /* Print the realm */
290         put_str(_("魔法        :", "Magic       :"), 6, 1);
291         c_put_str(TERM_L_BLUE, realm_names[creature_ptr->realm1], 6, 15);
292
293         /* Select the second realm */
294         while (TRUE) {
295             char temp[80 * 8];
296             concptr t;
297
298             int count = 0;
299             creature_ptr->realm2 = select_realm(creature_ptr, realm_choices2[creature_ptr->pclass], &count);
300
301             if (255 == creature_ptr->realm2)
302                 return FALSE;
303             if (!creature_ptr->realm2)
304                 break;
305
306             /* Clean up*/
307             clear_from(10);
308             put_str("                                   ", 3, 40);
309             put_str("                                   ", 4, 40);
310             put_str("                                   ", 5, 40);
311
312             roff_to_buf(realm_explanations[technic2magic(creature_ptr->realm2) - 1], 74, temp, sizeof(temp));
313             t = temp;
314             for (int i = 0; i < A_MAX; i++) {
315                 if (t[0] == 0)
316                     break;
317                 else {
318                     prt(t, 12 + i, 3);
319                     t += strlen(t) + 1;
320                 }
321             }
322
323             if (count < 2) {
324                 prt(_("何かキーを押してください", "Hit any key."), 0, 0);
325                 (void)inkey();
326                 prt("", 0, 0);
327                 break;
328             } else if (get_check_strict(_("よろしいですか?", "Are you sure? "), CHECK_DEFAULT_Y))
329                 break;
330         }
331
332         if (creature_ptr->realm2) {
333             /* Print the realm */
334             c_put_str(TERM_L_BLUE, format("%s, %s", realm_names[creature_ptr->realm1], realm_names[creature_ptr->realm2]), 6, 15);
335         }
336     }
337
338     return TRUE;
339 }