OSDN Git Service

[Refactor] #40477 Separated game-option-types.h from cmd-gameoption.h
[hengband/hengband.git] / src / birth / auto-roller.c
1 #include "birth/auto-roller.h"
2 #include "birth/birth-stat.h"
3 #include "birth/birth-util.h"
4 #include "player/player-personality.h"
5 #include "system/game-option-types.h"
6 #include "term/term-color-types.h"
7
8 /*!
9  * ランダムクエストのモンスターを確定するために試行する回数 / Maximum number of tries for selection of a proper quest monster
10  */
11 #define MAX_TRIES 100
12
13 /*! オートローラの能力値的要求水準 / Autoroll limit */
14 s16b stat_limit[6];
15
16 /*! オートローラ中、各能力値が水準を超えた回数 / Autoroll matches */
17 s32b stat_match[6];
18
19 /*! オートローラの試行回数 / Autoroll round */
20 s32b auto_round;
21
22 /*!
23  * @brief オートローラで得たい能力値の基準を決める。
24  * @param creature_ptr プレーヤーへの参照ポインタ
25  * @return なし
26  */
27 bool get_stat_limits(player_type *creature_ptr)
28 {
29     clear_from(10);
30     put_str(_("最低限得たい能力値を設定して下さい。", "Set minimum stats."), 10, 10);
31     put_str(_("2/8で項目選択、4/6で値の増減、Enterで次へ", "2/8 for Select, 4/6 for Change value, Enter for Goto next"), 11, 10);
32     put_str(_("         基本値  種族 職業 性格     合計値  最大値", "           Base   Rac  Cla  Per      Total  Maximum"), 13, 10);
33
34     int cval[6];
35     char buf[80];
36     char cur[80];
37     char inp[80];
38     for (int i = 0; i < A_MAX; i++) {
39         stat_match[i] = 0;
40         cval[i] = 3;
41         int j = rp_ptr->r_adj[i] + cp_ptr->c_adj[i] + ap_ptr->a_adj[i];
42         int m = adjust_stat(17, j);
43         if (m > 18)
44             sprintf(cur, "18/%02d", (m - 18));
45         else
46             sprintf(cur, "%2d", m);
47
48         m = adjust_stat(cval[i], j);
49         if (m > 18)
50             sprintf(inp, "18/%02d", (m - 18));
51         else
52             sprintf(inp, "%2d", m);
53
54         sprintf(buf, "%6s       %2d   %+3d  %+3d  %+3d  =  %6s  %6s", stat_names[i], cval[i], rp_ptr->r_adj[i], cp_ptr->c_adj[i], ap_ptr->a_adj[i], inp, cur);
55         put_str(buf, 14 + i, 10);
56     }
57
58     int cs = 0;
59     int os = 6;
60     while (TRUE) {
61         if (cs != os) {
62             if (os == 6) {
63                 c_put_str(TERM_WHITE, _("決定する", "Accept"), 21, 35);
64             } else if (os < A_MAX) {
65                 c_put_str(TERM_WHITE, cur, 14 + os, 10);
66             }
67             if (cs == 6) {
68                 c_put_str(TERM_YELLOW, _("決定する", "Accept"), 21, 35);
69             } else {
70                 int j = rp_ptr->r_adj[cs] + cp_ptr->c_adj[cs] + ap_ptr->a_adj[cs];
71                 int m = adjust_stat(cval[cs], j);
72                 if (m > 18)
73                     sprintf(inp, "18/%02d", (m - 18));
74                 else
75                     sprintf(inp, "%2d", m);
76
77                 sprintf(
78                     cur, "%6s       %2d   %+3d  %+3d  %+3d  =  %6s", stat_names[cs], cval[cs], rp_ptr->r_adj[cs], cp_ptr->c_adj[cs], ap_ptr->a_adj[cs], inp);
79                 c_put_str(TERM_YELLOW, cur, 14 + cs, 10);
80             }
81
82             os = cs;
83         }
84
85         char c = inkey();
86         switch (c) {
87         case 'Q':
88             birth_quit();
89             break;
90         case 'S':
91             return FALSE;
92         case ESCAPE:
93             break;
94         case ' ':
95         case '\r':
96         case '\n':
97             if (cs == 6)
98                 break;
99             cs++;
100             c = '2';
101             break;
102         case '8':
103         case 'k':
104             if (cs > 0)
105                 cs--;
106             break;
107         case '2':
108         case 'j':
109             if (cs < A_MAX)
110                 cs++;
111             break;
112         case '4':
113         case 'h':
114             if (cs != 6) {
115                 if (cval[cs] == 3) {
116                     cval[cs] = 17;
117                     os = 7;
118                 } else if (cval[cs] > 3) {
119                     cval[cs]--;
120                     os = 7;
121                 } else
122                     return FALSE;
123             }
124
125             break;
126         case '6':
127         case 'l':
128             if (cs != 6) {
129                 if (cval[cs] == 17) {
130                     cval[cs] = 3;
131                     os = 7;
132                 } else if (cval[cs] < 17) {
133                     cval[cs]++;
134                     os = 7;
135                 } else
136                     return FALSE;
137             }
138
139             break;
140         case 'm':
141             if (cs != 6) {
142                 cval[cs] = 17;
143                 os = 7;
144             }
145
146             break;
147         case 'n':
148             if (cs != 6) {
149                 cval[cs] = 3;
150                 os = 7;
151             }
152
153             break;
154         case '?':
155 #ifdef JP
156             show_help(creature_ptr, "jbirth.txt#AutoRoller");
157 #else
158             show_help(creature_ptr, "birth.txt#AutoRoller");
159 #endif
160             break;
161         case '=':
162             screen_save();
163 #ifdef JP
164             do_cmd_options_aux(OPT_PAGE_BIRTH, "初期オプション((*)はスコアに影響)");
165 #else
166             do_cmd_options_aux(OPT_PAGE_BIRTH, "Birth Option((*)s effect score)");
167 #endif
168
169             screen_load();
170             break;
171         default:
172             bell();
173             break;
174         }
175
176         if (c == ESCAPE || ((c == ' ' || c == '\r' || c == '\n') && cs == 6))
177             break;
178     }
179
180     for (int i = 0; i < A_MAX; i++)
181         stat_limit[i] = (s16b)cval[i];
182
183     return TRUE;
184 }
185
186 void initialize_chara_limit(chara_limit_type *chara_limit_ptr)
187 {
188     chara_limit_ptr->agemin = 0;
189     chara_limit_ptr->agemax = 0;
190     chara_limit_ptr->htmin = 0;
191     chara_limit_ptr->htmax = 0;
192     chara_limit_ptr->wtmin = 0;
193     chara_limit_ptr->wtmax = 0;
194     chara_limit_ptr->scmin = 0;
195     chara_limit_ptr->scmax = 0;
196 }
197
198 /*!
199  * @brief オートローラで得たい年齢、身長、体重、社会的地位の基準を決める。
200  * @return なし
201  */
202 bool get_chara_limits(player_type *creature_ptr, chara_limit_type *chara_limit_ptr)
203 {
204 #define MAXITEMS 8
205
206     char buf[80], cur[80];
207     concptr itemname[] = { _("年齢", "age"), _("身長(インチ)", "height"), _("体重(ポンド)", "weight"), _("社会的地位", "social class") };
208
209     clear_from(10);
210     put_str(_("2/4/6/8で項目選択、+/-で値の増減、Enterで次へ", "2/4/6/8 for Select, +/- for Change value, Enter for Goto next"), 11, 10);
211     put_str(
212         _("注意:身長と体重の最大値/最小値ぎりぎりの値は非常に出現確率が低くなります。", "Caution: Values near minimum or maximum are extremely rare."), 23, 2);
213
214     int max_percent, min_percent;
215     if (creature_ptr->psex == SEX_MALE) {
216         max_percent = (int)(rp_ptr->m_b_ht + rp_ptr->m_m_ht * 4 - 1) * 100 / (int)(rp_ptr->m_b_ht);
217         min_percent = (int)(rp_ptr->m_b_ht - rp_ptr->m_m_ht * 4 + 1) * 100 / (int)(rp_ptr->m_b_ht);
218     } else {
219         max_percent = (int)(rp_ptr->f_b_ht + rp_ptr->f_m_ht * 4 - 1) * 100 / (int)(rp_ptr->f_b_ht);
220         min_percent = (int)(rp_ptr->f_b_ht - rp_ptr->f_m_ht * 4 + 1) * 100 / (int)(rp_ptr->f_b_ht);
221     }
222
223     put_str(_("体格/地位の最小値/最大値を設定して下さい。", "Set minimum/maximum attribute."), 10, 10);
224     put_str(_("  項    目                 最小値  最大値", " Parameter                    Min     Max"), 13, 20);
225     int mval[MAXITEMS];
226     int cval[MAXITEMS];
227     for (int i = 0; i < MAXITEMS; i++) {
228         int m;
229         switch (i) {
230         case 0: /* Minimum age */
231             m = rp_ptr->b_age + 1;
232             break;
233         case 1: /* Maximum age */
234             m = rp_ptr->b_age + rp_ptr->m_age;
235             break;
236
237         case 2: /* Minimum height */
238             if (creature_ptr->psex == SEX_MALE)
239                 m = rp_ptr->m_b_ht - rp_ptr->m_m_ht * 4 + 1;
240             else
241                 m = rp_ptr->f_b_ht - rp_ptr->f_m_ht * 4 + 1;
242             break;
243         case 3: /* Maximum height */
244             if (creature_ptr->psex == SEX_MALE)
245                 m = rp_ptr->m_b_ht + rp_ptr->m_m_ht * 4 - 1;
246             else
247                 m = rp_ptr->f_b_ht + rp_ptr->f_m_ht * 4 - 1;
248             break;
249         case 4: /* Minimum weight */
250             if (creature_ptr->psex == SEX_MALE)
251                 m = (rp_ptr->m_b_wt * min_percent / 100) - (rp_ptr->m_m_wt * min_percent / 75) + 1;
252             else
253                 m = (rp_ptr->f_b_wt * min_percent / 100) - (rp_ptr->f_m_wt * min_percent / 75) + 1;
254             break;
255         case 5: /* Maximum weight */
256             if (creature_ptr->psex == SEX_MALE)
257                 m = (rp_ptr->m_b_wt * max_percent / 100) + (rp_ptr->m_m_wt * max_percent / 75) - 1;
258             else
259                 m = (rp_ptr->f_b_wt * max_percent / 100) + (rp_ptr->f_m_wt * max_percent / 75) - 1;
260             break;
261         case 6: /* Minimum social class */
262             m = 1;
263             break;
264         case 7: /* Maximum social class */
265             m = 100;
266             break;
267         default:
268             m = 1;
269             break;
270         }
271
272         mval[i] = m;
273         cval[i] = m;
274     }
275
276     for (int i = 0; i < 4; i++) {
277         sprintf(buf, "%-12s (%3d - %3d)", itemname[i], mval[i * 2], mval[i * 2 + 1]);
278         put_str(buf, 14 + i, 20);
279         for (int j = 0; j < 2; j++) {
280             sprintf(buf, "     %3d", cval[i * 2 + j]);
281             put_str(buf, 14 + i, 45 + 8 * j);
282         }
283     }
284
285     int cs = 0;
286     int os = MAXITEMS;
287     while (TRUE) {
288         if (cs != os) {
289             const char accept[] = _("決定する", "Accept");
290             if (os == MAXITEMS)
291                 c_put_str(TERM_WHITE, accept, 19, 35);
292             else
293                 c_put_str(TERM_WHITE, cur, 14 + os / 2, 45 + 8 * (os % 2));
294
295             if (cs == MAXITEMS) {
296                 c_put_str(TERM_YELLOW, accept, 19, 35);
297             } else {
298                 sprintf(cur, "     %3d", cval[cs]);
299                 c_put_str(TERM_YELLOW, cur, 14 + cs / 2, 45 + 8 * (cs % 2));
300             }
301
302             os = cs;
303         }
304
305         char c = inkey();
306         switch (c) {
307         case 'Q':
308             birth_quit();
309             break;
310         case 'S':
311             return FALSE;
312         case ESCAPE:
313             break; /*後でもう一回breakせんと*/
314         case ' ':
315         case '\r':
316         case '\n':
317             if (cs == MAXITEMS)
318                 break;
319             cs++;
320             c = '6';
321             break;
322         case '8':
323         case 'k':
324             if (cs - 2 >= 0)
325                 cs -= 2;
326             break;
327         case '2':
328         case 'j':
329             if (cs < MAXITEMS)
330                 cs += 2;
331             if (cs > MAXITEMS)
332                 cs = MAXITEMS;
333             break;
334         case '4':
335         case 'h':
336             if (cs > 0)
337                 cs--;
338             break;
339         case '6':
340         case 'l':
341             if (cs < MAXITEMS)
342                 cs++;
343             break;
344         case '-':
345         case '<':
346             if (cs != MAXITEMS) {
347                 if (cs % 2) {
348                     if (cval[cs] > cval[cs - 1]) {
349                         cval[cs]--;
350                         os = 127;
351                     }
352                 } else {
353                     if (cval[cs] > mval[cs]) {
354                         cval[cs]--;
355                         os = 127;
356                     }
357                 }
358             }
359
360             break;
361         case '+':
362         case '>':
363             if (cs != MAXITEMS) {
364                 if (cs % 2) {
365                     if (cval[cs] < mval[cs]) {
366                         cval[cs]++;
367                         os = 127;
368                     }
369                 } else {
370                     if (cval[cs] < cval[cs + 1]) {
371                         cval[cs]++;
372                         os = 127;
373                     }
374                 }
375             }
376
377             break;
378         case 'm':
379             if (cs != MAXITEMS) {
380                 if (cs % 2) {
381                     if (cval[cs] < mval[cs]) {
382                         cval[cs] = mval[cs];
383                         os = 127;
384                     }
385                 } else {
386                     if (cval[cs] < cval[cs + 1]) {
387                         cval[cs] = cval[cs + 1];
388                         os = 127;
389                     }
390                 }
391             }
392
393             break;
394         case 'n':
395             if (cs != MAXITEMS) {
396                 if (cs % 2) {
397                     if (cval[cs] > cval[cs - 1]) {
398                         cval[cs] = cval[cs - 1];
399                         os = 255;
400                     }
401                 } else {
402                     if (cval[cs] > mval[cs]) {
403                         cval[cs] = mval[cs];
404                         os = 255;
405                     }
406                 }
407             }
408
409             break;
410         case '?':
411 #ifdef JP
412             show_help(creature_ptr, "jbirth.txt#AutoRoller");
413 #else
414             show_help(creature_ptr, "birth.txt#AutoRoller");
415 #endif
416             break;
417         case '=':
418             screen_save();
419             do_cmd_options_aux(OPT_PAGE_BIRTH, _("初期オプション((*)はスコアに影響)", "Birth Option((*)s effect score)"));
420             screen_load();
421             break;
422         default:
423             bell();
424             break;
425         }
426
427         if (c == ESCAPE || ((c == ' ' || c == '\r' || c == '\n') && cs == MAXITEMS))
428             break;
429     }
430
431     chara_limit_ptr->agemin = (s16b)cval[0];
432     chara_limit_ptr->agemax = (s16b)cval[1];
433     chara_limit_ptr->htmin = (s16b)cval[2];
434     chara_limit_ptr->htmax = (s16b)cval[3];
435     chara_limit_ptr->wtmin = (s16b)cval[4];
436     chara_limit_ptr->wtmax = (s16b)cval[5];
437     chara_limit_ptr->scmin = (s16b)cval[6];
438     chara_limit_ptr->scmax = (s16b)cval[7];
439     return TRUE;
440 }