OSDN Git Service

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