OSDN Git Service

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