OSDN Git Service

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