OSDN Git Service

c19164f9f8f6ddc83bbe47ff1c26b73f8fc78b8d
[hengbandforosx/hengbandosx.git] / src / birth / birth-select-class.cpp
1 #include "birth/birth-select-class.h"
2 #include "birth/birth-util.h"
3 #include "io/input-key-acceptor.h"
4 #include "player-info/race-info.h"
5 #include "player/player-class.h"
6 #include "system/player-type-definition.h"
7 #include "term/screen-processor.h"
8 #include "term/term-color-types.h"
9 #include "util/int-char-converter.h"
10 #include "world/world.h"
11
12 static const char p2 = ')';
13
14 static TERM_COLOR birth_class_color(int cs)
15 {
16     if (cs < MAX_CLASS) {
17         if (is_retired_class(static_cast<player_class_type>(cs)))
18             return TERM_L_DARK;
19         if (is_winner_class(static_cast<player_class_type>(cs)))
20             return TERM_SLATE;
21     }
22     return TERM_WHITE;
23 }
24
25 static void enumerate_class_list(char *sym)
26 {
27     for (int n = 0; n < MAX_CLASS; n++) {
28         cp_ptr = &class_info[n];
29         mp_ptr = &m_info[n];
30         concptr str = cp_ptr->title;
31         if (n < 26)
32             sym[n] = I2A(n);
33         else
34             sym[n] = ('A' + n - 26);
35
36         char buf[80];
37         if (!(rp_ptr->choice & (1UL << n)))
38             sprintf(buf, "%c%c(%s)", sym[n], p2, str);
39         else
40             sprintf(buf, "%c%c%s", sym[n], p2, str);
41
42         c_put_str(birth_class_color(n), buf, 13 + (n / 4), 2 + 19 * (n % 4));
43     }
44 }
45
46 static void display_class_stat(int cs, int *os, char *cur, char *sym)
47 {
48     if (cs == *os)
49         return;
50
51     c_put_str(birth_class_color(*os), cur, 13 + (*os / 4), 2 + 19 * (*os % 4));
52     put_str("                                   ", 3, 40);
53     if (cs == MAX_CLASS) {
54         sprintf(cur, "%c%c%s", '*', p2, _("ランダム", "Random"));
55         put_str("                                   ", 4, 40);
56         put_str("                                   ", 5, 40);
57         put_str("                                   ", 6, 40);
58     } else {
59         cp_ptr = &class_info[cs];
60         mp_ptr = &m_info[cs];
61         concptr str = cp_ptr->title;
62         if (!(rp_ptr->choice & (1UL << cs)))
63             sprintf(cur, "%c%c(%s)", sym[cs], p2, str);
64         else
65             sprintf(cur, "%c%c%s", sym[cs], p2, str);
66
67         c_put_str(TERM_L_BLUE, cp_ptr->title, 3, 40);
68         put_str(_("の職業修正", ": Class modification"), 3, 40 + strlen(cp_ptr->title));
69         put_str(_("腕力 知能 賢さ 器用 耐久 魅力 経験 ", "Str  Int  Wis  Dex  Con  Chr   EXP "), 4, 40);
70         char buf[80];
71         sprintf(buf, "%+3d  %+3d  %+3d  %+3d  %+3d  %+3d %+4d%% ", cp_ptr->c_adj[0], cp_ptr->c_adj[1], cp_ptr->c_adj[2], cp_ptr->c_adj[3], cp_ptr->c_adj[4],
72             cp_ptr->c_adj[5], cp_ptr->c_exp);
73         c_put_str(TERM_L_BLUE, buf, 5, 40);
74
75         put_str("HD", 6, 40);
76         sprintf(buf, "%+3d", cp_ptr->c_mhp);
77         c_put_str(TERM_L_BLUE, buf, 6, 42);
78
79         put_str(_("隠密", "Stealth"), 6, 47);
80         if (cs == CLASS_BERSERKER)
81             strcpy(buf, " xx");
82         else
83             sprintf(buf, " %+2d", cp_ptr->c_stl);
84         c_put_str(TERM_L_BLUE, buf, 6, _(51, 54));
85     }
86
87     c_put_str(TERM_YELLOW, cur, 13 + (cs / 4), 2 + 19 * (cs % 4));
88     *os = cs;
89 }
90
91 static void interpret_class_select_key_move(char c, int *cs)
92 {
93     if (c == '8') {
94         if (*cs >= 4)
95             *cs -= 4;
96     }
97
98     if (c == '4') {
99         if (*cs > 0)
100             (*cs)--;
101     }
102
103     if (c == '6') {
104         if (*cs < MAX_CLASS)
105             (*cs)++;
106     }
107
108     if (c == '2') {
109         if ((*cs + 4) <= MAX_CLASS)
110             *cs += 4;
111     }
112 }
113
114 static bool select_class(player_type *creature_ptr, char *cur, char *sym, int *k)
115 {
116     int cs = creature_ptr->pclass;
117     int os = MAX_CLASS;
118     while (true) {
119         display_class_stat(cs, &os, cur, sym);
120         if (*k >= 0)
121             break;
122
123         char buf[80];
124         sprintf(buf, _("職業を選んで下さい (%c-%c) ('='初期オプション設定, 灰色:勝利済): ", "Choose a class (%c-%c) ('=' for options, Gray is winner): "),
125             sym[0], sym[MAX_CLASS - 1]);
126
127         put_str(buf, 10, 6);
128         char c = inkey();
129         if (c == 'Q')
130             birth_quit();
131
132         if (c == 'S')
133             return false;
134
135         if (c == ' ' || c == '\r' || c == '\n') {
136             if (cs == MAX_CLASS) {
137                 *k = randint0(MAX_CLASS);
138                 cs = *k;
139                 continue;
140             } else {
141                 *k = cs;
142                 break;
143             }
144         }
145
146         interpret_class_select_key_move(c, &cs);
147         if (c == '*') {
148             *k = randint0(MAX_CLASS);
149             cs = *k;
150             continue;
151         }
152
153         *k = (islower(c) ? A2I(c) : -1);
154         if ((*k >= 0) && (*k < MAX_CLASS)) {
155             cs = *k;
156             continue;
157         }
158
159         *k = (isupper(c) ? (26 + c - 'A') : -1);
160         if ((*k >= 26) && (*k < MAX_CLASS)) {
161             cs = *k;
162             continue;
163         } else
164             *k = -1;
165
166         birth_help_option(creature_ptr, c, BK_CLASS);
167     }
168
169     return true;
170 }
171
172 /*!
173  * @brief プレイヤーの職業選択を行う / Player class
174  */
175 bool get_player_class(player_type *creature_ptr)
176 {
177     clear_from(10);
178     put_str(
179         _("注意:《職業》によってキャラクターの先天的な能力やボーナスが変化します。", "Note: Your 'class' determines various intrinsic abilities and bonuses."),
180         23, 5);
181     put_str(_("()で囲まれた選択肢はこの種族には似合わない職業です。", "Any entries in parentheses should only be used by advanced players."), 11, 5);
182     put_str("                                   ", 6, 40);
183
184     char sym[MAX_CLASS];
185     enumerate_class_list(sym);
186
187     char cur[80];
188     sprintf(cur, "%c%c%s", '*', p2, _("ランダム", "Random"));
189     int k = -1;
190     if (!select_class(creature_ptr, cur, sym, &k))
191         return false;
192
193     creature_ptr->pclass = static_cast<player_class_type>(k);
194     cp_ptr = &class_info[creature_ptr->pclass];
195     mp_ptr = &m_info[creature_ptr->pclass];
196     c_put_str(TERM_L_BLUE, cp_ptr->title, 5, 15);
197     return true;
198 }