1 #include "player/player-skill.h"
2 #include "core/player-update-types.h"
3 #include "monster-race/monster-race.h"
4 #include "system/floor-type-definition.h"
5 #include "system/monster-race-definition.h"
6 #include "system/monster-type-definition.h"
7 #include "system/object-type-definition.h"
8 #include "system/player-type-definition.h"
9 #include "util/bit-flags-calculator.h"
11 /* Proficiency of weapons and misc. skills (except riding) */
12 constexpr SUB_EXP WEAPON_EXP_UNSKILLED = 0;
13 constexpr SUB_EXP WEAPON_EXP_BEGINNER = 4000;
14 constexpr SUB_EXP WEAPON_EXP_SKILLED = 6000;
15 constexpr SUB_EXP WEAPON_EXP_EXPERT = 7000;
16 constexpr SUB_EXP WEAPON_EXP_MASTER = 8000;
18 /* Proficiency of riding */
19 constexpr SUB_EXP RIDING_EXP_UNSKILLED = 0;
20 constexpr SUB_EXP RIDING_EXP_BEGINNER = 500;
21 constexpr SUB_EXP RIDING_EXP_SKILLED = 2000;
22 constexpr SUB_EXP RIDING_EXP_EXPERT = 5000;
23 constexpr SUB_EXP RIDING_EXP_MASTER = 8000;
28 std::vector<skill_table> s_info;
33 const concptr exp_level_str[5] =
35 { "[初心者]", "[入門者]", "[熟練者]", "[エキスパート]", "[達人]" };
37 { "[Unskilled]", "[Beginner]", "[Skilled]", "[Expert]", "[Master]" };
40 PlayerSkill::PlayerSkill(player_type *player_ptr)
41 : player_ptr(player_ptr)
45 SUB_EXP PlayerSkill::weapon_exp_at(int level)
48 case EXP_LEVEL_UNSKILLED:
49 return WEAPON_EXP_UNSKILLED;
50 case EXP_LEVEL_BEGINNER:
51 return WEAPON_EXP_BEGINNER;
52 case EXP_LEVEL_SKILLED:
53 return WEAPON_EXP_SKILLED;
54 case EXP_LEVEL_EXPERT:
55 return WEAPON_EXP_EXPERT;
56 case EXP_LEVEL_MASTER:
57 return WEAPON_EXP_MASTER;
60 return WEAPON_EXP_UNSKILLED;
64 * @brief 武器や各種スキル(騎乗以外)の抽象的表現ランクを返す。 / Return proficiency level of weapons and misc. skills (except riding)
65 * @param weapon_exp 経験値
68 int PlayerSkill::weapon_exp_level(int weapon_exp)
70 if (weapon_exp < WEAPON_EXP_BEGINNER)
71 return EXP_LEVEL_UNSKILLED;
72 else if (weapon_exp < WEAPON_EXP_SKILLED)
73 return EXP_LEVEL_BEGINNER;
74 else if (weapon_exp < WEAPON_EXP_EXPERT)
75 return EXP_LEVEL_SKILLED;
76 else if (weapon_exp < WEAPON_EXP_MASTER)
77 return EXP_LEVEL_EXPERT;
79 return EXP_LEVEL_MASTER;
82 bool PlayerSkill::valid_weapon_exp(int weapon_exp)
84 return (WEAPON_EXP_UNSKILLED <= weapon_exp) && (weapon_exp <= WEAPON_EXP_MASTER);
88 * @brief 騎乗スキルの抽象的ランクを返す。 / Return proficiency level of riding
89 * @param riding_exp 経験値
92 int PlayerSkill::riding_exp_level(int riding_exp)
94 if (riding_exp < RIDING_EXP_BEGINNER)
95 return EXP_LEVEL_UNSKILLED;
96 else if (riding_exp < RIDING_EXP_SKILLED)
97 return EXP_LEVEL_BEGINNER;
98 else if (riding_exp < RIDING_EXP_EXPERT)
99 return EXP_LEVEL_SKILLED;
100 else if (riding_exp < RIDING_EXP_MASTER)
101 return EXP_LEVEL_EXPERT;
103 return EXP_LEVEL_MASTER;
106 void PlayerSkill::gain_melee_weapon_exp(const object_type *o_ptr)
108 auto now_exp = this->player_ptr->weapon_exp[o_ptr->tval][o_ptr->sval];
109 if (now_exp >= s_info[enum2i(this->player_ptr->pclass)].w_max[o_ptr->tval][o_ptr->sval])
113 if (now_exp < WEAPON_EXP_BEGINNER)
115 else if (now_exp < WEAPON_EXP_SKILLED)
117 else if ((now_exp < WEAPON_EXP_EXPERT) && (this->player_ptr->lev > 19))
119 else if ((player_ptr->lev > 34) && one_in_(2))
122 this->player_ptr->weapon_exp[o_ptr->tval][o_ptr->sval] += amount;
123 set_bits(this->player_ptr->update, PU_BONUS);
126 void PlayerSkill::gain_range_weapon_exp(const object_type *o_ptr)
128 auto now_exp = this->player_ptr->weapon_exp[o_ptr->tval][o_ptr->sval];
129 if (now_exp >= s_info[enum2i(this->player_ptr->pclass)].w_max[o_ptr->tval][o_ptr->sval])
133 if (now_exp < WEAPON_EXP_BEGINNER)
135 else if (now_exp < WEAPON_EXP_SKILLED)
137 else if ((now_exp < WEAPON_EXP_EXPERT) && (this->player_ptr->lev > 19))
139 else if (this->player_ptr->lev > 34)
142 this->player_ptr->weapon_exp[o_ptr->tval][o_ptr->sval] += amount;
143 set_bits(this->player_ptr->update, PU_BONUS);
146 void PlayerSkill::gain_martial_arts_skill_exp()
148 auto now_exp = this->player_ptr->skill_exp[SKILL_MARTIAL_ARTS];
149 if (now_exp >= s_info[enum2i(this->player_ptr->pclass)].s_max[SKILL_MARTIAL_ARTS])
153 if (now_exp < WEAPON_EXP_BEGINNER)
155 else if (now_exp < WEAPON_EXP_SKILLED)
157 else if ((now_exp < WEAPON_EXP_EXPERT) && (this->player_ptr->lev > 19))
159 else if ((this->player_ptr->lev > 34) && one_in_(3))
162 this->player_ptr->skill_exp[SKILL_MARTIAL_ARTS] += amount;
163 set_bits(this->player_ptr->update, PU_BONUS);
166 void PlayerSkill::gain_two_weapon_skill_exp()
168 auto now_exp = this->player_ptr->skill_exp[SKILL_TWO_WEAPON];
169 if (now_exp >= s_info[enum2i(this->player_ptr->pclass)].s_max[SKILL_TWO_WEAPON])
173 if (now_exp < WEAPON_EXP_BEGINNER)
175 else if (now_exp < WEAPON_EXP_SKILLED)
177 else if ((now_exp < WEAPON_EXP_EXPERT) && (this->player_ptr->lev > 19))
179 else if ((this->player_ptr->lev > 34) && one_in_(3))
182 this->player_ptr->skill_exp[SKILL_TWO_WEAPON] += amount;
183 set_bits(this->player_ptr->update, PU_BONUS);
186 void PlayerSkill::gain_riding_skill_exp_on_melee_attack(const monster_race *r_ptr)
188 auto now_exp = this->player_ptr->skill_exp[SKILL_RIDING];
189 auto max_exp = s_info[enum2i(this->player_ptr->pclass)].s_max[SKILL_RIDING];
190 if (now_exp >= max_exp)
193 auto riding_level = r_info[this->player_ptr->current_floor_ptr->m_list[this->player_ptr->riding].r_idx].level;
196 if ((now_exp / 200 - 5) < r_ptr->level)
199 if ((now_exp / 100) < riding_level) {
200 if ((now_exp / 100 + 15) < riding_level)
201 inc += 1 + (riding_level - (now_exp / 100 + 15));
206 this->player_ptr->skill_exp[SKILL_RIDING] = std::min<SUB_EXP>(max_exp, now_exp + inc);
207 set_bits(this->player_ptr->update, PU_BONUS);
210 void PlayerSkill::gain_riding_skill_exp_on_range_attack()
212 auto now_exp = this->player_ptr->skill_exp[SKILL_RIDING];
213 auto max_exp = s_info[enum2i(this->player_ptr->pclass)].s_max[SKILL_RIDING];
214 if (now_exp >= max_exp)
217 if (((this->player_ptr->skill_exp[SKILL_RIDING] - (RIDING_EXP_BEGINNER * 2)) / 200 < r_info[this->player_ptr->current_floor_ptr->m_list[this->player_ptr->riding].r_idx].level) && one_in_(2)) {
218 this->player_ptr->skill_exp[SKILL_RIDING] += 1;
219 set_bits(this->player_ptr->update, PU_BONUS);
223 void PlayerSkill::gain_riding_skill_exp_on_fall_off_check(HIT_POINT dam)
225 auto now_exp = this->player_ptr->skill_exp[SKILL_RIDING];
226 auto max_exp = s_info[enum2i(this->player_ptr->pclass)].s_max[SKILL_RIDING];
227 if (now_exp >= max_exp || max_exp <= 1000)
230 auto riding_level = r_info[this->player_ptr->current_floor_ptr->m_list[this->player_ptr->riding].r_idx].level;
232 if ((dam / 2 + riding_level) <= (now_exp / 30 + 10))
236 if ((now_exp / 100 + 15) < riding_level)
237 inc += 1 + (riding_level - (now_exp / 100 + 15));
241 player_ptr->skill_exp[SKILL_RIDING] = std::min<SUB_EXP>(max_exp, now_exp + inc);
242 set_bits(this->player_ptr->update, PU_BONUS);