1 #include "birth/birth-wizard.h"
2 #include "birth/auto-roller.h"
3 #include "birth/birth-body-spec.h"
4 #include "birth/birth-explanations-table.h"
5 #include "birth/birth-select-class.h"
6 #include "birth/birth-select-personality.h"
7 #include "birth/birth-select-race.h"
8 #include "birth/birth-select-realm.h"
9 #include "birth/birth-stat.h"
10 #include "birth/birth-util.h"
11 #include "birth/game-play-initializer.h"
12 #include "birth/history-editor.h"
13 #include "birth/history-generator.h"
14 #include "birth/quick-start.h"
15 #include "cmd-io/cmd-gameoption.h"
16 #include "cmd-io/cmd-help.h"
17 #include "core/asking-player.h"
18 #include "core/player-update-types.h"
19 #include "game-option/birth-options.h"
20 #include "io/input-key-acceptor.h"
21 #include "main/sound-definitions-table.h"
22 #include "main/sound-of-music.h"
23 #include "player-info/avatar.h"
24 #include "player/patron.h"
25 #include "player/player-class.h"
26 #include "player/player-race.h"
27 #include "player/player-sex.h"
28 #include "player/process-name.h"
29 #include "player/player-status-table.h"
30 #include "player/player-status.h"
31 #include "system/game-option-types.h"
32 #include "system/player-type-definition.h"
33 #include "term/screen-processor.h"
34 #include "term/term-color-types.h"
35 #include "util/buffer-shaper.h"
36 #include "util/int-char-converter.h"
37 #include "view/display-birth.h" // 暫定。後で消す予定。
38 #include "view/display-player.h" // 暫定。後で消す.
39 #include "world/world.h"
43 * How often the autoroller will update the display and pause
44 * to check for user interuptions.
45 * Bigger values will make the autoroller faster, but slower
46 * system may have problems because the user can't stop the
47 * autoroller for this number of rolls.
49 #define AUTOROLLER_STEP 54321L
51 static void display_initial_birth_message(player_type *creature_ptr)
54 put_str(_("名前 :", "Name :"), 1, 26);
55 put_str(_("性別 :", "Sex :"), 3, 1);
56 put_str(_("種族 :", "Race :"), 4, 1);
57 put_str(_("職業 :", "Class :"), 5, 1);
58 c_put_str(TERM_L_BLUE, creature_ptr->name, 1, 34);
59 put_str(_("キャラクターを作成します。('S'やり直す, 'Q'終了, '?'ヘルプ)", "Make your character. ('S' Restart, 'Q' Quit, '?' Help)"), 8, 10);
60 put_str(_("注意:《性別》の違いはゲーム上ほとんど影響を及ぼしません。", "Note: Your 'sex' does not have any significant gameplay effects."), 23, 5);
64 * @prief 性別選択画面でヘルプを表示させる
65 * @param creature_ptr プレーヤーへの参照ポインタ
67 * @details 他の関数名と被りそうだったので少し眺め
69 static void display_help_on_sex_select(player_type *creature_ptr, char c)
72 do_cmd_help(creature_ptr);
75 do_cmd_options_aux(creature_ptr, OPT_PAGE_BIRTH, _("初期オプション((*)はスコアに影響)", "Birth Options ((*)) affect score"));
77 } else if (c != '4' && c != '6')
82 * @brief プレイヤーの性別選択を行う / Player sex
83 * @param creature_ptr プレーヤーへの参照ポインタ
85 * @return やり直すならFALSE、それ以外はTRUE
87 static bool get_player_sex(player_type *creature_ptr, char *buf)
91 sprintf(cur, _("%c%c%s", "%c%c %s"), '*', p2, _("ランダム", "Random"));
97 put_str(cur, 12 + (os / 5), 2 + 15 * (os % 5));
99 sprintf(cur, _("%c%c%s", "%c%c %s"), '*', p2, _("ランダム", "Random"));
101 sp_ptr = &sex_info[cs];
102 concptr str = sp_ptr->title;
103 sprintf(cur, _("%c%c%s", "%c%c %s"), I2A(cs), p2, str);
106 c_put_str(TERM_YELLOW, cur, 12 + (cs / 5), 2 + 15 * (cs % 5));
113 sprintf(buf, _("性別を選んで下さい (%c-%c) ('='初期オプション設定): ", "Choose a sex (%c-%c) ('=' for options): "), I2A(0), I2A(1));
114 put_str(buf, 10, 10);
122 if (c == ' ' || c == '\r' || c == '\n') {
123 k = cs == MAX_SEXES ? randint0(MAX_SEXES) : cs;
128 k = randint0(MAX_SEXES);
142 k = (islower(c) ? A2I(c) : -1);
143 if ((k >= 0) && (k < MAX_SEXES)) {
149 display_help_on_sex_select(creature_ptr, c);
152 creature_ptr->psex = (byte)k;
153 sp_ptr = &sex_info[creature_ptr->psex];
154 c_put_str(TERM_L_BLUE, sp_ptr->title, 3, 15);
158 static bool let_player_select_race(player_type *creature_ptr)
161 creature_ptr->prace = RACE_HUMAN;
164 if (!get_player_race(creature_ptr))
168 shape_buffer(race_explanations[creature_ptr->prace], 74, temp, sizeof(temp));
170 for (int i = 0; i < 10; i++) {
178 if (get_check_strict(creature_ptr, _("よろしいですか?", "Are you sure? "), CHECK_DEFAULT_Y))
182 c_put_str(TERM_WHITE, " ", 4, 15);
188 static bool let_player_select_class(player_type *creature_ptr)
191 creature_ptr->pclass = CLASS_WARRIOR;
194 if (!get_player_class(creature_ptr))
198 shape_buffer(class_explanations[creature_ptr->pclass], 74, temp, sizeof(temp));
200 for (int i = 0; i < 9; i++) {
209 if (get_check_strict(creature_ptr, _("よろしいですか?", "Are you sure? "), CHECK_DEFAULT_Y))
212 c_put_str(TERM_WHITE, " ", 5, 15);
218 static bool let_player_select_personality(player_type *creature_ptr)
220 creature_ptr->pseikaku = PERSONALITY_ORDINARY;
223 if (!get_player_personality(creature_ptr))
227 shape_buffer(personality_explanations[creature_ptr->pseikaku], 74, temp, sizeof(temp));
229 for (int i = 0; i < A_MAX; i++) {
238 if (get_check_strict(creature_ptr, _("よろしいですか?", "Are you sure? "), CHECK_DEFAULT_Y))
241 c_put_str(TERM_L_BLUE, creature_ptr->name, 1, 34);
242 prt("", 1, 34 + strlen(creature_ptr->name));
248 static bool let_player_build_character(player_type *creature_ptr)
251 if (!get_player_sex(creature_ptr, buf))
254 if (!let_player_select_race(creature_ptr))
257 if (!let_player_select_class(creature_ptr))
260 if (!get_player_realms(creature_ptr))
263 if (!let_player_select_personality(creature_ptr))
269 static void display_initial_options(player_type *creature_ptr)
271 u16b expfact = get_expfact(creature_ptr) - 100;
273 for (int i = 0; i < A_MAX; i++) {
274 adj[i] = rp_ptr->r_adj[i] + cp_ptr->c_adj[i] + ap_ptr->a_adj[i];
279 put_str(_("修正の合計値", "Your total modification"), 3, 40);
280 put_str(_("腕力 知能 賢さ 器用 耐久 魅力 経験 ", "Str Int Wis Dex Con Chr EXP "), 4, 40);
281 sprintf(buf, "%+3d %+3d %+3d %+3d %+3d %+3d %+4d%% ", adj[0], adj[1], adj[2], adj[3], adj[4], adj[5], expfact);
282 c_put_str(TERM_L_BLUE, buf, 5, 40);
284 put_str("HD ", 6, 40);
285 sprintf(buf, "%2d", rp_ptr->r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp);
286 c_put_str(TERM_L_BLUE, buf, 6, 43);
288 put_str(_("隠密", "Stealth"), 6, 47);
289 if (creature_ptr->pclass == CLASS_BERSERKER)
292 sprintf(buf, "%+2d", rp_ptr->r_stl + cp_ptr->c_stl + ap_ptr->a_stl);
293 c_put_str(TERM_L_BLUE, buf, 6, _(52, 55));
295 put_str(_("赤外線視力", "Infra"), 6, _(56, 59));
296 sprintf(buf, _("%2dft", "%2dft"), 10 * rp_ptr->infra);
297 c_put_str(TERM_L_BLUE, buf, 6, _(67, 65));
301 do_cmd_options_aux(creature_ptr, OPT_PAGE_BIRTH, _("初期オプション((*)はスコアに影響)", "Birth Options ((*)) affect score"));
305 static void display_auto_roller_success_rate(const int col)
310 put_str(_("最小値", " Limit"), 2, col + 13);
311 put_str(_("現在値", " Roll"), 2, col + 24);
315 if (autoroll_chance >= 1)
316 sprintf(buf, _("確率 : 1/%8d00", "Prob : 1/%8d00"), autoroll_chance);
317 else if (autoroll_chance == -999)
318 sprintf(buf, _("確率 : 不可能", "Prob : Impossible"));
320 sprintf(buf, _("確率 : 1/10000以上", "Prob : >1/10000"));
321 put_str(buf, 11, col + 10);
324 "注意 : 体格等のオートローラを併用時は、上記確率より困難です。",
325 "Note : Prob may be lower when you use the 'autochara' option."
328 for (int i = 0; i < A_MAX; i++) {
329 put_str(stat_names[i], 3 + i, col + 8);
330 int j = rp_ptr->r_adj[i] + cp_ptr->c_adj[i] + ap_ptr->a_adj[i];
331 int m = adjust_stat(stat_limit[i], j);
333 c_put_str(TERM_L_BLUE, buf, 3 + i, col + 13);
337 static void auto_roller_count(void)
339 if (auto_round < 1000000000L)
349 static bool decide_initial_stat(player_type *creature_ptr)
355 for (int i = 0; i < A_MAX; i++) {
356 if (creature_ptr->stat_max[i] < stat_limit[i]) {
365 static bool decide_body_spec(player_type *creature_ptr, chara_limit_type chara_limit, bool *accept)
370 get_ahw(creature_ptr);
371 get_history(creature_ptr);
374 if ((creature_ptr->age < chara_limit.agemin) || (creature_ptr->age > chara_limit.agemax))
376 if ((creature_ptr->ht < chara_limit.htmin) || (creature_ptr->ht > chara_limit.htmax))
378 if ((creature_ptr->wt < chara_limit.wtmin) || (creature_ptr->wt > chara_limit.wtmax))
380 if ((creature_ptr->sc < chara_limit.scmin) || (creature_ptr->sc > chara_limit.scmax))
387 static bool display_auto_roller_count(player_type *creature_ptr, const int col)
389 if ((auto_round % AUTOROLLER_STEP) != 0)
392 birth_put_stats(creature_ptr);
393 if (auto_upper_round)
394 put_str(format("%ld%09ld", auto_upper_round, auto_round), 10, col + 20);
396 put_str(format("%10ld", auto_round), 10, col + 20);
400 get_ahw(creature_ptr);
401 get_history(creature_ptr);
408 static void exe_auto_roller(player_type *creature_ptr, chara_limit_type chara_limit, const int col)
410 while (autoroller || autochara) {
411 get_stats(creature_ptr);
414 bool accept = decide_initial_stat(creature_ptr);
415 if (decide_body_spec(creature_ptr, chara_limit, &accept))
418 if (display_auto_roller_count(creature_ptr, col))
423 static bool display_auto_roller_result(player_type *creature_ptr, bool prev, char *c)
427 creature_ptr->update |= (PU_BONUS | PU_HP);
428 update_creature(creature_ptr);
429 creature_ptr->chp = creature_ptr->mhp;
430 creature_ptr->csp = creature_ptr->msp;
431 display_player(creature_ptr, mode);
434 term_addch(TERM_WHITE, b1);
435 term_addstr(-1, TERM_WHITE, _("'r' 次の数値", "'r'eroll"));
437 term_addstr(-1, TERM_WHITE, _(", 'p' 前の数値", "'p'previous"));
440 term_addstr(-1, TERM_WHITE, _(", 'h' その他の情報", ", 'h' Misc."));
442 term_addstr(-1, TERM_WHITE, _(", 'h' 生い立ちを表示", ", 'h'istory"));
444 term_addstr(-1, TERM_WHITE, _(", Enter この数値に決定", ", or Enter to accept"));
446 term_addch(TERM_WHITE, b2);
454 if (*c == '\r' || *c == '\n' || *c == ESCAPE)
457 if ((*c == ' ') || (*c == 'r'))
460 if (prev && (*c == 'p')) {
461 load_prev_data(creature_ptr, true);
465 if ((*c == 'H') || (*c == 'h')) {
466 mode = ((mode != 0) ? 0 : 1);
470 birth_help_option(creature_ptr, *c, BK_AUTO_ROLLER);
478 * @brief オートロールを回して結果を表示し、その数値に決めるかさらに回すか確認する。
479 * @param creature_ptr プレーヤーへの参照ポインタ
480 * @param chara_limit 社会的地位の要求水準
481 * @details 2つめの結果以降は、'p'キーで1つ前のロール結果に戻せる。
483 static bool display_auto_roller(player_type *creature_ptr, chara_limit_type chara_limit)
489 if (autoroller || autochara) {
491 put_str(_("回数 :", "Round:"), 10, col + 10);
492 put_str(_("(ESCで停止)", "(Hit ESC to stop)"), 13, col + 13);
494 get_stats(creature_ptr);
495 get_ahw(creature_ptr);
496 get_history(creature_ptr);
499 display_auto_roller_success_rate(col);
500 exe_auto_roller(creature_ptr, chara_limit, col);
501 if (autoroller || autochara)
506 get_extra(creature_ptr, true);
507 get_money(creature_ptr);
508 creature_ptr->chaos_patron = (s16b)randint0(MAX_PATRON);
511 if (!display_auto_roller_result(creature_ptr, prev, &c))
514 if (c == '\r' || c == '\n' || c == ESCAPE)
517 save_prev_data(creature_ptr, &previous_char);
518 previous_char.quick_ok = false;
526 * @brief 名前と生い立ちを設定する
527 * @param creature_ptr プレーヤーへの参照ポインタ
528 * @details ついでにステータス限界もここで決めている
530 static void set_name_history(player_type *creature_ptr)
533 get_name(creature_ptr);
534 process_player_name(creature_ptr, current_world_ptr->creating_savefile);
535 edit_history(creature_ptr);
536 get_max_stats(creature_ptr);
537 get_virtues(creature_ptr);
538 prt(_("[ 'Q' 中断, 'S' 初めから, Enter ゲーム開始 ]", "['Q'uit, 'S'tart over, or Enter to continue]"), 23, _(14, 10));
542 * @brief プレーヤーキャラ作成ウィザード
544 * The delay may be reduced, but is recommended to keep players
545 * from continuously rolling up characters, which can be VERY
546 * expensive CPU wise. And it cuts down on player stupidity.
548 bool player_birth_wizard(player_type *creature_ptr)
550 display_initial_birth_message(creature_ptr);
553 for (int n = 0; n < MAX_SEXES; n++) {
554 sp_ptr = &sex_info[n];
555 sprintf(buf, _("%c%c%s", "%c%c %s"), I2A(n), p2, sp_ptr->title);
556 put_str(buf, 12 + (n / 5), 2 + 15 * (n % 5));
559 if (!let_player_build_character(creature_ptr))
562 display_initial_options(creature_ptr);
563 if (autoroller || autochara) {
565 auto_upper_round = 0L;
566 autoroll_chance = 0L;
570 if (!get_stat_limits(creature_ptr))
573 chara_limit_type chara_limit;
574 initialize_chara_limit(&chara_limit);
576 if (!get_chara_limits(creature_ptr, &chara_limit))
580 init_turn(creature_ptr);
581 if (!display_auto_roller(creature_ptr, chara_limit))
584 set_name_history(creature_ptr);
592 init_dungeon_quests(creature_ptr);
593 save_prev_data(creature_ptr, &previous_char);
594 previous_char.quick_ok = true;