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 "player/player-realm.h"
7 #include "term/screen-processor.h"
8 #include "term/term-color-types.h"
9 #include "util/buffer-shaper.h"
10 #include "util/int-char-converter.h"
12 static const byte REALM_SELECT_CANCEL = 255;
14 typedef struct birth_realm_type {
18 char sym[VALID_REALM];
20 int picks[VALID_REALM];
26 static byte count_realm_selection(s32b choices, int *count)
28 byte auto_select = REALM_NONE;
29 if (choices & CH_LIFE) {
31 auto_select = REALM_LIFE;
34 if (choices & CH_SORCERY) {
36 auto_select = REALM_SORCERY;
39 if (choices & CH_NATURE) {
41 auto_select = REALM_NATURE;
44 if (choices & CH_CHAOS) {
46 auto_select = REALM_CHAOS;
49 if (choices & CH_DEATH) {
51 auto_select = REALM_DEATH;
54 if (choices & CH_TRUMP) {
56 auto_select = REALM_TRUMP;
59 if (choices & CH_ARCANE) {
61 auto_select = REALM_ARCANE;
64 if (choices & CH_ENCHANT) {
66 auto_select = REALM_CRAFT;
69 if (choices & CH_DAEMON) {
71 auto_select = REALM_DAEMON;
74 if (choices & CH_CRUSADE) {
76 auto_select = REALM_CRUSADE;
79 if (choices & CH_MUSIC) {
81 auto_select = REALM_MUSIC;
84 if (choices & CH_HISSATSU) {
86 auto_select = REALM_HISSATSU;
89 if (choices & CH_HEX) {
91 auto_select = REALM_HEX;
97 static birth_realm_type *initialize_birth_realm_type(birth_realm_type *birth_realm_ptr)
99 birth_realm_ptr->cs = 0;
100 birth_realm_ptr->n = 0;
101 birth_realm_ptr->p2 = ')';
102 for (int i = 0; i < VALID_REALM; i++)
103 birth_realm_ptr->picks[i] = 0;
105 birth_realm_ptr->k = -1;
106 return birth_realm_ptr;
109 static void impose_first_realm(player_type *creature_ptr, s32b choices)
111 if (creature_ptr->realm2 == REALM_SELECT_CANCEL)
114 if (creature_ptr->pclass != CLASS_PRIEST)
117 if (is_good_realm(creature_ptr->realm1)) {
118 choices &= ~(CH_DEATH | CH_DAEMON);
120 choices &= ~(CH_LIFE | CH_CRUSADE);
124 static void analyze_realms(player_type *creature_ptr, s32b choices, birth_realm_type *birth_realm_ptr)
126 for (int i = 0; i < 32; i++) {
127 if ((choices & (1L << i)) == 0)
130 if (creature_ptr->realm1 == i + 1) {
131 if (creature_ptr->realm2 == REALM_SELECT_CANCEL)
132 birth_realm_ptr->cs = birth_realm_ptr->n;
137 if (creature_ptr->realm2 == i + 1)
138 birth_realm_ptr->cs = birth_realm_ptr->n;
140 birth_realm_ptr->sym[birth_realm_ptr->n] = I2A(birth_realm_ptr->n);
142 sprintf(birth_realm_ptr->buf, "%c%c %s", birth_realm_ptr->sym[birth_realm_ptr->n], birth_realm_ptr->p2, realm_names[i + 1]);
143 put_str(birth_realm_ptr->buf, 12 + (birth_realm_ptr->n / 5), 2 + 15 * (birth_realm_ptr->n % 5));
144 birth_realm_ptr->picks[birth_realm_ptr->n++] = i + 1;
148 static void move_birth_realm_cursor(birth_realm_type *birth_realm_ptr)
150 if (birth_realm_ptr->cs == birth_realm_ptr->os)
153 c_put_str(TERM_WHITE, birth_realm_ptr->cur, 12 + (birth_realm_ptr->os / 5), 2 + 15 * (birth_realm_ptr->os % 5));
155 if (birth_realm_ptr->cs == birth_realm_ptr->n) {
156 sprintf(birth_realm_ptr->cur, "%c%c %s", '*', birth_realm_ptr->p2, _("ランダム", "Random"));
158 sprintf(birth_realm_ptr->cur, "%c%c %s", birth_realm_ptr->sym[birth_realm_ptr->cs], birth_realm_ptr->p2,
159 realm_names[birth_realm_ptr->picks[birth_realm_ptr->cs]]);
160 sprintf(birth_realm_ptr->buf, "%s", realm_names[birth_realm_ptr->picks[birth_realm_ptr->cs]]);
161 c_put_str(TERM_L_BLUE, birth_realm_ptr->buf, 3, 40);
162 prt(_("の特徴", ": Characteristic"), 3, 40 + strlen(birth_realm_ptr->buf));
163 prt(realm_subinfo[technic2magic(birth_realm_ptr->picks[birth_realm_ptr->cs]) - 1], 4, 40);
166 c_put_str(TERM_YELLOW, birth_realm_ptr->cur, 12 + (birth_realm_ptr->cs / 5), 2 + 15 * (birth_realm_ptr->cs % 5));
167 birth_realm_ptr->os = birth_realm_ptr->cs;
170 static void interpret_realm_select_key(birth_realm_type *birth_realm_ptr, char c)
176 if (birth_realm_ptr->cs >= 5)
177 birth_realm_ptr->cs -= 5;
181 if (birth_realm_ptr->cs > 0)
182 birth_realm_ptr->cs--;
186 if (birth_realm_ptr->cs < birth_realm_ptr->n)
187 birth_realm_ptr->cs++;
191 if ((birth_realm_ptr->cs + 5) <= birth_realm_ptr->n)
192 birth_realm_ptr->cs += 5;
196 static bool get_a_realm(player_type *creature_ptr, birth_realm_type *birth_realm_ptr)
198 birth_realm_ptr->os = birth_realm_ptr->n;
200 move_birth_realm_cursor(birth_realm_ptr);
201 if (birth_realm_ptr->k >= 0)
204 sprintf(birth_realm_ptr->buf, _("領域を選んで下さい(%c-%c) ('='初期オプション設定): ", "Choose a realm (%c-%c) ('=' for options): "),
205 birth_realm_ptr->sym[0], birth_realm_ptr->sym[birth_realm_ptr->n - 1]);
207 put_str(birth_realm_ptr->buf, 10, 10);
209 interpret_realm_select_key(birth_realm_ptr, c);
213 if (c == ' ' || c == '\r' || c == '\n') {
214 if (birth_realm_ptr->cs == birth_realm_ptr->n) {
215 birth_realm_ptr->k = randint0(birth_realm_ptr->n);
218 birth_realm_ptr->k = birth_realm_ptr->cs;
224 birth_realm_ptr->k = randint0(birth_realm_ptr->n);
228 birth_realm_ptr->k = (islower(c) ? A2I(c) : -1);
229 if ((birth_realm_ptr->k >= 0) && (birth_realm_ptr->k < birth_realm_ptr->n)) {
230 birth_realm_ptr->cs = birth_realm_ptr->k;
234 birth_realm_ptr->k = (isupper(c) ? (26 + c - 'A') : -1);
235 if ((birth_realm_ptr->k >= 26) && (birth_realm_ptr->k < birth_realm_ptr->n)) {
236 birth_realm_ptr->cs = birth_realm_ptr->k;
239 birth_realm_ptr->k = -1;
241 birth_help_option(creature_ptr, c, BK_REALM);
248 * @brief プレイヤーの魔法領域を選択する / Choose from one of the available magical realms
249 * @param choices 選択可能な魔法領域のビット配列
250 * @param count 選択可能な魔法領域を返すポインタ群。
251 * @return 選択した魔法領域のID
252 * @details 領域数が0 (戦士等)or 1 (観光客等)なら自動での値を返す
254 static byte select_realm(player_type *creature_ptr, s32b choices, int *count)
256 byte auto_select = count_realm_selection(choices, count);
261 impose_first_realm(creature_ptr, choices);
262 put_str(_("注意:魔法の領域の選択によりあなたが習得する呪文のタイプが決まります。", "Note: The realm of magic will determine which spells you can learn."),
265 birth_realm_type tmp_birth_realm;
266 birth_realm_type *birth_realm_ptr = initialize_birth_realm_type(&tmp_birth_realm);
267 analyze_realms(creature_ptr, choices, birth_realm_ptr);
268 sprintf(birth_realm_ptr->cur, "%c%c %s", '*', birth_realm_ptr->p2, _("ランダム", "Random"));
269 if (get_a_realm(creature_ptr, birth_realm_ptr))
270 return REALM_SELECT_CANCEL;
273 return (byte)(birth_realm_ptr->picks[birth_realm_ptr->k]);
276 static void cleanup_realm_selection_window(void)
285 * @brief 選んだ魔法領域で本当に良いか問い合わせる
286 * @param count 魔法領域の数
287 * @return 選んだ魔法領域で良ければTRUE、再選択ならばFALSE
289 static bool check_realm_selection(player_type *creature_ptr, int count)
292 prt(_("何かキーを押してください", "Hit any key."), 0, 0);
296 } else if (get_check_strict(creature_ptr, _("よろしいですか?", "Are you sure? "), CHECK_DEFAULT_Y))
303 * @brief 選択した魔法領域の解説を表示する / Choose the magical realms
304 * @return ユーザが魔法領域の確定を選んだらTRUEを返す。
306 bool get_player_realms(player_type *creature_ptr)
308 /* Clean up infomation of modifications */
313 /* Select the first realm */
314 creature_ptr->realm1 = REALM_NONE;
315 creature_ptr->realm2 = REALM_SELECT_CANCEL;
319 creature_ptr->realm1 = select_realm(creature_ptr, realm_choices1[creature_ptr->pclass], &count);
321 if (creature_ptr->realm1 == REALM_SELECT_CANCEL)
323 if (!creature_ptr->realm1)
326 cleanup_realm_selection_window();
327 shape_buffer(realm_explanations[technic2magic(creature_ptr->realm1) - 1], 74, temp, sizeof(temp));
329 for (int i = 0; i < 10; i++) {
338 if (check_realm_selection(creature_ptr, count))
342 /* Select the second realm */
343 creature_ptr->realm2 = REALM_NONE;
344 if (creature_ptr->realm1 == REALM_NONE)
347 /* Print the realm */
348 put_str(_("魔法 :", "Magic :"), 6, 1);
349 c_put_str(TERM_L_BLUE, realm_names[creature_ptr->realm1], 6, 15);
351 /* Select the second realm */
355 creature_ptr->realm2 = select_realm(creature_ptr, realm_choices2[creature_ptr->pclass], &count);
357 if (creature_ptr->realm2 == REALM_SELECT_CANCEL)
359 if (!creature_ptr->realm2)
362 cleanup_realm_selection_window();
363 shape_buffer(realm_explanations[technic2magic(creature_ptr->realm2) - 1], 74, temp, sizeof(temp));
365 for (int i = 0; i < A_MAX; i++) {
374 if (check_realm_selection(creature_ptr, count))
378 if (creature_ptr->realm2) {
379 /* Print the realm */
380 c_put_str(TERM_L_BLUE, format("%s, %s", realm_names[creature_ptr->realm1], realm_names[creature_ptr->realm2]), 6, 15);