1 #include "player-status/player-speed.h"
2 #include "artifact/fixed-art-types.h"
3 #include "grid/feature-flag-types.h"
4 #include "grid/feature.h"
5 #include "inventory/inventory-slot-types.h"
6 #include "monster-race/monster-race.h"
7 #include "monster/monster-status.h"
8 #include "mutation/mutation-flag-types.h"
9 #include "object-enchant/tr-types.h"
10 #include "object/object-flags.h"
11 #include "player-info/equipment-info.h"
12 #include "player/attack-defense-types.h"
13 #include "player/digestion-processor.h"
14 #include "player/player-race.h"
15 #include "player/player-skill.h"
16 #include "player/player-status-flags.h"
17 #include "player/player-status.h"
18 #include "player/special-defense-types.h"
19 #include "realm/realm-hex-numbers.h"
20 #include "realm/realm-types.h"
21 #include "spell-realm/spells-hex.h"
22 #include "system/floor-type-definition.h"
23 #include "system/grid-type-definition.h"
24 #include "system/monster-race-definition.h"
25 #include "system/monster-type-definition.h"
26 #include "system/object-type-definition.h"
27 #include "system/player-type-definition.h"
28 #include "util/bit-flags-calculator.h"
31 * @brief 速度 - 初期値、下限、上限
37 void PlayerSpeed::set_locals()
39 this->default_value = 110;
41 this->max_value = 209;
42 this->tr_flag = TR_SPEED;
43 this->tr_bad_flag = TR_SPEED;
50 * ** クラッコンと妖精に加算(+レベル/10)
51 * ** 悪魔変化/吸血鬼変化で加算(+3)
53 * ** マーフォークがFF_WATER地形にいれば加算(+2+レベル/10)
54 * ** そうでなく浮遊を持っていないなら減算(-2)
56 int16_t PlayerSpeed::race_value()
60 if (is_specific_player_race(this->owner_ptr, player_race_type::KLACKON) || is_specific_player_race(this->owner_ptr, player_race_type::SPRITE))
61 result += (this->owner_ptr->lev) / 10;
63 if (is_specific_player_race(this->owner_ptr, player_race_type::MERFOLK)) {
64 floor_type *floor_ptr = this->owner_ptr->current_floor_ptr;
65 feature_type *f_ptr = &f_info[floor_ptr->grid_array[this->owner_ptr->y][this->owner_ptr->x].feat];
66 if (f_ptr->flags.has(FF::WATER)) {
67 result += (2 + this->owner_ptr->lev / 10);
68 } else if (!this->owner_ptr->levitation) {
73 if (this->owner_ptr->mimic_form) {
74 switch (this->owner_ptr->mimic_form) {
78 case MIMIC_DEMON_LORD:
93 * ** 忍者の装備が重ければ減算(-レベル/10)
94 * ** 忍者の装備が適正ならば加算(+3)さらにクラッコン、妖精、いかさま以外なら加算(+レベル/10)
95 * ** 錬気術師で装備が重くなくクラッコン、妖精、いかさま以外なら加算(+レベル/10)
96 * ** 狂戦士なら加算(+3),レベル20/30/40/50ごとに+1
98 int16_t PlayerSpeed::class_value()
102 if (this->owner_ptr->pclass == CLASS_NINJA) {
103 if (heavy_armor(this->owner_ptr)) {
104 result -= (this->owner_ptr->lev) / 10;
105 } else if ((!this->owner_ptr->inventory_list[INVEN_MAIN_HAND].k_idx || can_attack_with_main_hand(this->owner_ptr))
106 && (!this->owner_ptr->inventory_list[INVEN_SUB_HAND].k_idx || can_attack_with_sub_hand(this->owner_ptr))) {
108 if (!(is_specific_player_race(this->owner_ptr, player_race_type::KLACKON) || is_specific_player_race(this->owner_ptr, player_race_type::SPRITE)
109 || (this->owner_ptr->pseikaku == PERSONALITY_MUNCHKIN)))
110 result += (this->owner_ptr->lev) / 10;
114 if ((this->owner_ptr->pclass == CLASS_MONK || this->owner_ptr->pclass == CLASS_FORCETRAINER) && !(heavy_armor(this->owner_ptr))) {
115 if (!(is_specific_player_race(this->owner_ptr, player_race_type::KLACKON) || is_specific_player_race(this->owner_ptr, player_race_type::SPRITE)
116 || (this->owner_ptr->pseikaku == PERSONALITY_MUNCHKIN)))
117 result += (this->owner_ptr->lev) / 10;
120 if (this->owner_ptr->pclass == CLASS_BERSERKER) {
122 if (this->owner_ptr->lev > 29)
124 if (this->owner_ptr->lev > 39)
126 if (this->owner_ptr->lev > 44)
128 if (this->owner_ptr->lev > 49)
138 * ** いかさまでクラッコン/妖精以外なら加算(+5+レベル/10)
140 int16_t PlayerSpeed::personality_value()
143 if (this->owner_ptr->pseikaku == PERSONALITY_MUNCHKIN && this->owner_ptr->prace != player_race_type::KLACKON && this->owner_ptr->prace != player_race_type::SPRITE) {
144 result += (this->owner_ptr->lev) / 10 + 5;
150 * @brief 速度計算 - 装備品特殊セット
153 * ** 棘セット装備中ならば加算(+7)
154 * ** アイシングデス-トゥインクル装備中ならば加算(+7)
156 int16_t PlayerSpeed::special_weapon_set_value()
159 if (has_melee_weapon(this->owner_ptr, INVEN_MAIN_HAND) && has_melee_weapon(this->owner_ptr, INVEN_SUB_HAND)) {
160 if ((this->owner_ptr->inventory_list[INVEN_MAIN_HAND].name1 == ART_QUICKTHORN)
161 && (this->owner_ptr->inventory_list[INVEN_SUB_HAND].name1 == ART_TINYTHORN)) {
165 if ((this->owner_ptr->inventory_list[INVEN_MAIN_HAND].name1 == ART_ICINGDEATH)
166 && (this->owner_ptr->inventory_list[INVEN_SUB_HAND].name1 == ART_TWINKLE)) {
177 * ** 装備品にTR_SPEEDがあれば加算(+pval+1
178 * ** セットで加速増減があるものを計算
180 int16_t PlayerSpeed::equipments_value()
182 int16_t result = PlayerStatusBase::equipments_value();
183 result += this->special_weapon_set_value();
189 * @brief 速度計算 - 一時的効果
194 * ** 呪術「衝撃のクローク」で加算(+3)
196 * ** 光速移動中は+999(最終的に+99になる)
198 int16_t PlayerSpeed::time_effect_value()
202 if (is_fast(this->owner_ptr)) {
206 if (this->owner_ptr->slow) {
210 if (this->owner_ptr->realm1 == REALM_HEX) {
211 if (hex_spelling(this->owner_ptr, HEX_SHOCK_CLOAK)) {
216 if (this->owner_ptr->food >= PY_FOOD_MAX)
219 /* Temporary lightspeed forces to be maximum speed */
220 if (this->owner_ptr->lightspeed)
232 int16_t PlayerSpeed::battleform_value()
235 if (any_bits(this->owner_ptr->special_defense, KAMAE_SUZAKU))
244 * ** 変異MUT3_XTRA_FATなら減算(-2)
245 * ** 変異MUT3_XTRA_LEGなら加算(+3)
246 * ** 変異MUT3_SHORT_LEGなら減算(-3)
248 int16_t PlayerSpeed::mutation_value()
252 const auto &muta = this->owner_ptr->muta;
253 if (muta.has(MUTA::XTRA_FAT)) {
257 if (muta.has(MUTA::XTRA_LEGS)) {
261 if (muta.has(MUTA::SHORT_LEG)) {
272 * * 騎乗中ならばモンスターの加速に準拠、ただし騎乗技能値とモンスターレベルによるキャップ処理あり
274 int16_t PlayerSpeed::riding_value()
276 monster_type *riding_m_ptr = &(this->owner_ptr)->current_floor_ptr->m_list[this->owner_ptr->riding];
277 SPEED speed = riding_m_ptr->mspeed;
280 if (!this->owner_ptr->riding) {
284 if (riding_m_ptr->mspeed > 110) {
285 result = (int16_t)((speed - 110) * (this->owner_ptr->skill_exp[SKILL_RIDING] * 3 + this->owner_ptr->lev * 160L - 10000L) / (22000L));
289 result = speed - 110;
292 result += (this->owner_ptr->skill_exp[SKILL_RIDING] + this->owner_ptr->lev * 160L) / 3200;
294 if (monster_fast_remaining(riding_m_ptr))
296 if (monster_slow_remaining(riding_m_ptr))
306 * * 所持品の重量による減速処理。乗馬時は別計算。
308 int16_t PlayerSpeed::inventory_weight_value()
312 int weight = calc_inventory_weight(this->owner_ptr);
315 if (this->owner_ptr->riding) {
316 monster_type *riding_m_ptr = &(this->owner_ptr)->current_floor_ptr->m_list[this->owner_ptr->riding];
317 monster_race *riding_r_ptr = &r_info[riding_m_ptr->r_idx];
318 count = 1500 + riding_r_ptr->level * 25;
320 if (this->owner_ptr->skill_exp[SKILL_RIDING] < RIDING_EXP_SKILLED) {
321 weight += (this->owner_ptr->wt * 3 * (RIDING_EXP_SKILLED - this->owner_ptr->skill_exp[SKILL_RIDING])) / RIDING_EXP_SKILLED;
324 if (weight > count) {
325 result -= ((weight - count) / (count / 5));
328 count = (int)calc_weight_limit(this->owner_ptr);
329 if (weight > count) {
330 result -= ((weight - count) / (count / 5));
337 * @brief 速度計算 - ACTION
342 int16_t PlayerSpeed::action_value()
345 if (this->owner_ptr->action == ACTION_SEARCH)
352 * @return 加速修正が0でない装備に対応したBIT_FLAG
354 * * セット二刀流は両手のフラグをONにする
356 BIT_FLAGS PlayerSpeed::equipments_flags(tr_type check_flag)
358 BIT_FLAGS result = PlayerStatusBase::equipments_flags(check_flag);
360 if (this->special_weapon_set_value() != 0)
361 set_bits(result, FLAG_CAUSE_INVEN_MAIN_HAND | FLAG_CAUSE_INVEN_SUB_HAND);
367 * @brief 速度計算 - 乗馬時の例外処理
370 * * 非乗馬時 - ここまでの修正値合算をそのまま使用
371 * * 乗馬時 - 乗馬の速度と重量減衰のみを計算
373 int16_t PlayerSpeed::set_exception_value(int16_t value)
375 if (this->owner_ptr->riding) {
376 value = this->default_value;
377 value += this->riding_value();
378 value += this->inventory_weight_value();
379 value += this->action_value();