OSDN Git Service

[Refactor] #40457 Moved sv-* from object/ to sv-definition/
[hengbandforosx/hengbandosx.git] / src / birth / birth-stat.c
1 #include "system/angband.h"
2 #include "birth/birth-stat.h"
3 #include "sv-definition/sv-weapon-types.h"
4 #include "player/player-personality.h"
5 #include "player/player-personalities-table.h"
6 #include "player/player-skill.h"
7 #include "spell/spells-status.h"
8 #include "player/player-races-table.h"
9
10 /*!
11  * @brief プレイヤーの能力値表現に基づいて加減算を行う。
12  * @param value 現在の能力値
13  * @param amount 加減算する値
14  * @return 加減算の結果
15  */
16 int adjust_stat(int value, int amount)
17 {
18     if (amount < 0) {
19         for (int i = 0; i < (0 - amount); i++) {
20             if (value >= 18 + 10) {
21                 value -= 10;
22             } else if (value > 18) {
23                 value = 18;
24             } else if (value > 3) {
25                 value--;
26             }
27         }
28     } else if (amount > 0) {
29         for (int i = 0; i < amount; i++) {
30             if (value < 18) {
31                 value++;
32             } else {
33                 value += 10;
34             }
35         }
36     }
37
38     return value;
39 }
40
41 /*!
42  * @brief プレイヤーの能力値を一通りロールする。 / Roll for a characters stats
43  * @param creature_ptr プレーヤーへの参照ポインタ
44  * @return なし
45  * @details
46  * calc_bonuses()による、独立ステータスからの副次ステータス算出も行っている。
47  * For efficiency, we include a chunk of "calc_bonuses()".\n
48  */
49 void get_stats(player_type* creature_ptr)
50 {
51     while (TRUE) {
52         int sum = 0;
53         for (int i = 0; i < 2; i++) {
54             s32b tmp = randint0(60 * 60 * 60);
55             BASE_STATUS val;
56
57             /* Extract 5 + 1d3 + 1d4 + 1d5 */
58             val = 5 + 3;
59             val += tmp % 3;
60             tmp /= 3;
61             val += tmp % 4;
62             tmp /= 4;
63             val += tmp % 5;
64             tmp /= 5;
65
66             sum += val;
67             creature_ptr->stat_cur[3 * i] = creature_ptr->stat_max[3 * i] = val;
68
69             /* Extract 5 + 1d3 + 1d4 + 1d5 */
70             val = 5 + 3;
71             val += tmp % 3;
72             tmp /= 3;
73             val += tmp % 4;
74             tmp /= 4;
75             val += tmp % 5;
76             tmp /= 5;
77
78             sum += val;
79             creature_ptr->stat_cur[3 * i + 1] = creature_ptr->stat_max[3 * i + 1] = val;
80
81             val = 5 + 3;
82             val += tmp % 3;
83             tmp /= 3;
84             val += tmp % 4;
85             tmp /= 4;
86             val += (BASE_STATUS)tmp;
87
88             sum += val;
89             creature_ptr->stat_cur[3 * i + 2] = creature_ptr->stat_max[3 * i + 2] = val;
90         }
91
92         if ((sum > 42 + 5 * 6) && (sum < 57 + 5 * 6))
93             break;
94     }
95 }
96
97 /*!
98  * @brief その他「オートローラ中は算出の対象にしない」副次ステータスを処理する / Roll for some info that the auto-roller ignores
99  * @return なし
100  */
101 void get_extra(player_type* creature_ptr, bool roll_hitdie)
102 {
103     if (creature_ptr->prace == RACE_ANDROID)
104         creature_ptr->expfact = rp_ptr->r_exp;
105     else
106         creature_ptr->expfact = rp_ptr->r_exp + cp_ptr->c_exp;
107
108     if (((creature_ptr->pclass == CLASS_MONK) || (creature_ptr->pclass == CLASS_FORCETRAINER) || (creature_ptr->pclass == CLASS_NINJA)) && ((creature_ptr->prace == RACE_KLACKON) || (creature_ptr->prace == RACE_SPRITE)))
109         creature_ptr->expfact -= 15;
110
111     /* Reset record of race/realm changes */
112     creature_ptr->start_race = creature_ptr->prace;
113     creature_ptr->old_race1 = 0L;
114     creature_ptr->old_race2 = 0L;
115     creature_ptr->old_realm = 0;
116
117     for (int i = 0; i < 64; i++) {
118         if (creature_ptr->pclass == CLASS_SORCERER)
119             creature_ptr->spell_exp[i] = SPELL_EXP_MASTER;
120         else if (creature_ptr->pclass == CLASS_RED_MAGE)
121             creature_ptr->spell_exp[i] = SPELL_EXP_SKILLED;
122         else
123             creature_ptr->spell_exp[i] = SPELL_EXP_UNSKILLED;
124     }
125
126     for (int i = 0; i < 5; i++)
127         for (int j = 0; j < 64; j++)
128             creature_ptr->weapon_exp[i][j] = s_info[creature_ptr->pclass].w_start[i][j];
129
130     if ((creature_ptr->pseikaku == PERSONALITY_SEXY) && (creature_ptr->weapon_exp[TV_HAFTED - TV_WEAPON_BEGIN][SV_WHIP] < WEAPON_EXP_BEGINNER)) {
131         creature_ptr->weapon_exp[TV_HAFTED - TV_WEAPON_BEGIN][SV_WHIP] = WEAPON_EXP_BEGINNER;
132     }
133
134     for (int i = 0; i < GINOU_MAX; i++)
135         creature_ptr->skill_exp[i] = s_info[creature_ptr->pclass].s_start[i];
136
137     if (creature_ptr->pclass == CLASS_SORCERER)
138         creature_ptr->hitdie = rp_ptr->r_mhp / 2 + cp_ptr->c_mhp + ap_ptr->a_mhp;
139     else
140         creature_ptr->hitdie = rp_ptr->r_mhp + cp_ptr->c_mhp + ap_ptr->a_mhp;
141
142     if (roll_hitdie)
143         roll_hitdice(creature_ptr, SPOP_NO_UPDATE);
144
145     creature_ptr->mhp = creature_ptr->player_hp[0];
146 }
147
148 /*!
149  * @brief プレイヤーの限界ステータスを決める。
150  * @param creature_ptr プレーヤーへの参照ポインタ
151  * @return なし
152  * @details 新生の薬やステータスシャッフルでもこの関数が呼ばれる
153  */
154 void get_max_stats(player_type* creature_ptr)
155 {
156     int dice[6];
157     while (TRUE) {
158         int j = 0;
159         for (int i = 0; i < A_MAX; i++) {
160             dice[i] = randint1(7);
161             j += dice[i];
162         }
163
164         if (j == 24)
165             break;
166     }
167
168     for (int i = 0; i < A_MAX; i++) {
169         BASE_STATUS max_max = 18 + 60 + dice[i] * 10;
170         creature_ptr->stat_max_max[i] = max_max;
171         if (creature_ptr->stat_max[i] > max_max)
172             creature_ptr->stat_max[i] = max_max;
173         if (creature_ptr->stat_cur[i] > max_max)
174             creature_ptr->stat_cur[i] = max_max;
175     }
176
177     creature_ptr->knowledge &= ~(KNOW_STAT);
178     creature_ptr->redraw |= (PR_STATS);
179 }