OSDN Git Service

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