1 #include "birth/birth-select-realm.h"
2 #include "birth/birth-explanations-table.h"
3 #include "birth/birth-util.h"
4 #include "core/asking-player.h"
5 #include "io/input-key-acceptor.h"
6 #include "mind/mind-elementalist.h"
7 #include "player/player-realm.h"
8 #include "term/screen-processor.h"
9 #include "term/term-color-types.h"
10 #include "util/buffer-shaper.h"
11 #include "util/int-char-converter.h"
13 static const byte REALM_SELECT_CANCEL = 255;
15 typedef struct birth_realm_type {
19 char sym[VALID_REALM];
21 int picks[VALID_REALM];
27 static byte count_realm_selection(const u32b choices, int *count)
29 byte auto_select = REALM_NONE;
30 if (choices & CH_LIFE) {
32 auto_select = REALM_LIFE;
35 if (choices & CH_SORCERY) {
37 auto_select = REALM_SORCERY;
40 if (choices & CH_NATURE) {
42 auto_select = REALM_NATURE;
45 if (choices & CH_CHAOS) {
47 auto_select = REALM_CHAOS;
50 if (choices & CH_DEATH) {
52 auto_select = REALM_DEATH;
55 if (choices & CH_TRUMP) {
57 auto_select = REALM_TRUMP;
60 if (choices & CH_ARCANE) {
62 auto_select = REALM_ARCANE;
65 if (choices & CH_ENCHANT) {
67 auto_select = REALM_CRAFT;
70 if (choices & CH_DAEMON) {
72 auto_select = REALM_DAEMON;
75 if (choices & CH_CRUSADE) {
77 auto_select = REALM_CRUSADE;
80 if (choices & CH_MUSIC) {
82 auto_select = REALM_MUSIC;
85 if (choices & CH_HISSATSU) {
87 auto_select = REALM_HISSATSU;
90 if (choices & CH_HEX) {
92 auto_select = REALM_HEX;
98 static birth_realm_type *initialize_birth_realm_type(birth_realm_type *birth_realm_ptr)
100 birth_realm_ptr->cs = 0;
101 birth_realm_ptr->n = 0;
102 birth_realm_ptr->p2 = ')';
103 for (int i = 0; i < VALID_REALM; i++)
104 birth_realm_ptr->picks[i] = 0;
106 birth_realm_ptr->k = -1;
107 return birth_realm_ptr;
110 static void impose_first_realm(const player_type *creature_ptr, u32b *choices)
112 if (creature_ptr->realm2 == REALM_SELECT_CANCEL)
115 if (creature_ptr->pclass != CLASS_PRIEST)
118 if (is_good_realm(creature_ptr->realm1)) {
119 *choices &= ~(CH_DEATH | CH_DAEMON);
121 *choices &= ~(CH_LIFE | CH_CRUSADE);
125 static void analyze_realms(const player_type *creature_ptr, const u32b choices, birth_realm_type *birth_realm_ptr)
127 for (int i = 0; i < 32; i++) {
128 if ((choices & (1UL << i)) == 0)
131 if (creature_ptr->realm1 == i + 1) {
132 if (creature_ptr->realm2 == REALM_SELECT_CANCEL)
133 birth_realm_ptr->cs = birth_realm_ptr->n;
138 if (creature_ptr->realm2 == i + 1)
139 birth_realm_ptr->cs = birth_realm_ptr->n;
141 birth_realm_ptr->sym[birth_realm_ptr->n] = I2A(birth_realm_ptr->n);
143 sprintf(birth_realm_ptr->buf, "%c%c %s", birth_realm_ptr->sym[birth_realm_ptr->n], birth_realm_ptr->p2, realm_names[i + 1]);
144 put_str(birth_realm_ptr->buf, 12 + (birth_realm_ptr->n / 5), 2 + 15 * (birth_realm_ptr->n % 5));
145 birth_realm_ptr->picks[birth_realm_ptr->n++] = i + 1;
149 static void move_birth_realm_cursor(birth_realm_type *birth_realm_ptr)
151 if (birth_realm_ptr->cs == birth_realm_ptr->os)
154 c_put_str(TERM_WHITE, birth_realm_ptr->cur, 12 + (birth_realm_ptr->os / 5), 2 + 15 * (birth_realm_ptr->os % 5));
156 if (birth_realm_ptr->cs == birth_realm_ptr->n) {
157 sprintf(birth_realm_ptr->cur, "%c%c %s", '*', birth_realm_ptr->p2, _("ランダム", "Random"));
159 sprintf(birth_realm_ptr->cur, "%c%c %s", birth_realm_ptr->sym[birth_realm_ptr->cs], birth_realm_ptr->p2,
160 realm_names[birth_realm_ptr->picks[birth_realm_ptr->cs]]);
161 sprintf(birth_realm_ptr->buf, "%s", realm_names[birth_realm_ptr->picks[birth_realm_ptr->cs]]);
162 c_put_str(TERM_L_BLUE, birth_realm_ptr->buf, 3, 40);
163 prt(_("の特徴", ": Characteristic"), 3, 40 + strlen(birth_realm_ptr->buf));
164 prt(realm_subinfo[technic2magic(birth_realm_ptr->picks[birth_realm_ptr->cs]) - 1], 4, 40);
167 c_put_str(TERM_YELLOW, birth_realm_ptr->cur, 12 + (birth_realm_ptr->cs / 5), 2 + 15 * (birth_realm_ptr->cs % 5));
168 birth_realm_ptr->os = birth_realm_ptr->cs;
171 static void interpret_realm_select_key(birth_realm_type *birth_realm_ptr, char c)
177 if (birth_realm_ptr->cs >= 5)
178 birth_realm_ptr->cs -= 5;
182 if (birth_realm_ptr->cs > 0)
183 birth_realm_ptr->cs--;
187 if (birth_realm_ptr->cs < birth_realm_ptr->n)
188 birth_realm_ptr->cs++;
192 if ((birth_realm_ptr->cs + 5) <= birth_realm_ptr->n)
193 birth_realm_ptr->cs += 5;
197 static bool get_a_realm(player_type *creature_ptr, birth_realm_type *birth_realm_ptr)
199 birth_realm_ptr->os = birth_realm_ptr->n;
201 move_birth_realm_cursor(birth_realm_ptr);
202 if (birth_realm_ptr->k >= 0)
205 sprintf(birth_realm_ptr->buf, _("領域を選んで下さい(%c-%c) ('='初期オプション設定): ", "Choose a realm (%c-%c) ('=' for options): "),
206 birth_realm_ptr->sym[0], birth_realm_ptr->sym[birth_realm_ptr->n - 1]);
208 put_str(birth_realm_ptr->buf, 10, 10);
210 interpret_realm_select_key(birth_realm_ptr, c);
214 if (c == ' ' || c == '\r' || c == '\n') {
215 if (birth_realm_ptr->cs == birth_realm_ptr->n) {
216 birth_realm_ptr->k = randint0(birth_realm_ptr->n);
219 birth_realm_ptr->k = birth_realm_ptr->cs;
225 birth_realm_ptr->k = randint0(birth_realm_ptr->n);
229 birth_realm_ptr->k = (islower(c) ? A2I(c) : -1);
230 if ((birth_realm_ptr->k >= 0) && (birth_realm_ptr->k < birth_realm_ptr->n)) {
231 birth_realm_ptr->cs = birth_realm_ptr->k;
235 birth_realm_ptr->k = (isupper(c) ? (26 + c - 'A') : -1);
236 if ((birth_realm_ptr->k >= 26) && (birth_realm_ptr->k < birth_realm_ptr->n)) {
237 birth_realm_ptr->cs = birth_realm_ptr->k;
240 birth_realm_ptr->k = -1;
242 birth_help_option(creature_ptr, c, BK_REALM);
249 * @brief プレイヤーの魔法領域を選択する / Choose from one of the available magical realms
250 * @param choices 選択可能な魔法領域のビット配列
251 * @param count 選択可能な魔法領域を返すポインタ群。
252 * @return 選択した魔法領域のID
253 * @details 領域数が0 (戦士等)or 1 (観光客等)なら自動での値を返す
255 static byte select_realm(player_type *creature_ptr, u32b choices, int *count)
257 byte auto_select = count_realm_selection(choices, count);
262 impose_first_realm(creature_ptr, &choices);
263 put_str(_("注意:魔法の領域の選択によりあなたが習得する呪文のタイプが決まります。", "Note: The realm of magic will determine which spells you can learn."),
266 birth_realm_type tmp_birth_realm;
267 birth_realm_type *birth_realm_ptr = initialize_birth_realm_type(&tmp_birth_realm);
268 analyze_realms(creature_ptr, choices, birth_realm_ptr);
269 sprintf(birth_realm_ptr->cur, "%c%c %s", '*', birth_realm_ptr->p2, _("ランダム", "Random"));
270 if (get_a_realm(creature_ptr, birth_realm_ptr))
271 return REALM_SELECT_CANCEL;
274 return (byte)(birth_realm_ptr->picks[birth_realm_ptr->k]);
277 static void cleanup_realm_selection_window(void)
286 * @brief 選んだ魔法領域で本当に良いか問い合わせる
287 * @param count 魔法領域の数
288 * @return 選んだ魔法領域で良ければTRUE、再選択ならばFALSE
290 static bool check_realm_selection(player_type *creature_ptr, int count)
293 prt(_("何かキーを押してください", "Hit any key."), 0, 0);
297 } else if (get_check_strict(creature_ptr, _("よろしいですか?", "Are you sure? "), CHECK_DEFAULT_Y))
304 * @brief 選択した魔法領域の解説を表示する / Choose the magical realms
305 * @return ユーザが魔法領域の確定を選んだらTRUEを返す。
307 bool get_player_realms(player_type *creature_ptr)
309 /* Clean up infomation of modifications */
315 /* Select the first realm */
316 creature_ptr->realm1 = REALM_NONE;
317 creature_ptr->realm2 = REALM_NONE;
319 if (creature_ptr->pclass == CLASS_ELEMENTALIST) {
320 creature_ptr->element = select_element_realm(creature_ptr);
321 if (creature_ptr->element == REALM_SELECT_CANCEL)
324 put_str(_("魔法 :", "Magic :"), 6, 1);
325 c_put_str(TERM_L_BLUE, get_element_title(creature_ptr->element), 6, 15);
332 creature_ptr->realm1 = select_realm(creature_ptr, realm_choices1[creature_ptr->pclass], &count);
333 if (creature_ptr->realm1 == REALM_SELECT_CANCEL)
335 if (!creature_ptr->realm1)
338 cleanup_realm_selection_window();
339 shape_buffer(realm_explanations[technic2magic(creature_ptr->realm1) - 1], 74, temp, sizeof(temp));
341 for (int i = 0; i < 10; i++) {
350 if (check_realm_selection(creature_ptr, count))
354 /* Select the second realm */
355 creature_ptr->realm2 = REALM_NONE;
356 if (creature_ptr->realm1 == REALM_NONE)
359 /* Print the realm */
360 put_str(_("魔法 :", "Magic :"), 6, 1);
361 c_put_str(TERM_L_BLUE, realm_names[creature_ptr->realm1], 6, 15);
363 /* Select the second realm */
367 creature_ptr->realm2 = select_realm(creature_ptr, realm_choices2[creature_ptr->pclass], &count);
369 if (creature_ptr->realm2 == REALM_SELECT_CANCEL)
371 if (!creature_ptr->realm2)
374 cleanup_realm_selection_window();
375 shape_buffer(realm_explanations[technic2magic(creature_ptr->realm2) - 1], 74, temp, sizeof(temp));
377 for (int i = 0; i < A_MAX; i++) {
386 if (check_realm_selection(creature_ptr, count))
390 if (creature_ptr->realm2) {
391 /* Print the realm */
392 c_put_str(TERM_L_BLUE, format("%s, %s", realm_names[creature_ptr->realm1], realm_names[creature_ptr->realm2]), 6, 15);