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-base/player-class.h"
12 #include "player-base/player-race.h"
13 #include "player-info/equipment-info.h"
14 #include "player-info/monk-data-type.h"
15 #include "player-info/race-info.h"
16 #include "player/attack-defense-types.h"
17 #include "player/digestion-processor.h"
18 #include "player/player-skill.h"
19 #include "player/player-status-flags.h"
20 #include "player/player-status.h"
21 #include "player/special-defense-types.h"
22 #include "realm/realm-hex-numbers.h"
23 #include "realm/realm-types.h"
24 #include "spell-realm/spells-hex.h"
25 #include "system/floor-type-definition.h"
26 #include "system/grid-type-definition.h"
27 #include "system/monster-race-definition.h"
28 #include "system/monster-type-definition.h"
29 #include "system/object-type-definition.h"
30 #include "system/player-type-definition.h"
31 #include "util/bit-flags-calculator.h"
33 PlayerSpeed::PlayerSpeed(player_type *player_ptr)
34 : PlayerStatusBase(player_ptr)
39 * @brief 速度 - 初期値、下限、上限
45 void PlayerSpeed::set_locals()
47 this->default_value = 110;
49 this->max_value = 209;
50 this->tr_flag = TR_SPEED;
51 this->tr_bad_flag = TR_SPEED;
58 * ** クラッコンと妖精に加算(+レベル/10)
59 * ** 悪魔変化/吸血鬼変化で加算(+3)
61 * ** マーフォークがFF_WATER地形にいれば加算(+2+レベル/10)
62 * ** そうでなく浮遊を持っていないなら減算(-2)
64 int16_t PlayerSpeed::race_value()
68 if (PlayerRace(this->player_ptr).equals(PlayerRaceType::KLACKON) || PlayerRace(this->player_ptr).equals(PlayerRaceType::SPRITE))
69 result += (this->player_ptr->lev) / 10;
71 if (PlayerRace(this->player_ptr).equals(PlayerRaceType::MERFOLK)) {
72 floor_type *floor_ptr = this->player_ptr->current_floor_ptr;
73 feature_type *f_ptr = &f_info[floor_ptr->grid_array[this->player_ptr->y][this->player_ptr->x].feat];
74 if (f_ptr->flags.has(FF::WATER)) {
75 result += (2 + this->player_ptr->lev / 10);
76 } else if (!this->player_ptr->levitation) {
81 if (this->player_ptr->mimic_form) {
82 switch (this->player_ptr->mimic_form) {
86 case MIMIC_DEMON_LORD:
101 * ** 忍者の装備が重ければ減算(-レベル/10)
102 * ** 忍者の装備が適正ならば加算(+3)さらにクラッコン、妖精、いかさま以外なら加算(+レベル/10)
103 * ** 錬気術師で装備が重くなくクラッコン、妖精、いかさま以外なら加算(+レベル/10)
104 * ** 狂戦士なら加算(+3),レベル20/30/40/50ごとに+1
106 int16_t PlayerSpeed::class_value()
110 if (this->player_ptr->pclass == PlayerClassType::NINJA) {
111 if (heavy_armor(this->player_ptr)) {
112 result -= (this->player_ptr->lev) / 10;
113 } else if ((!this->player_ptr->inventory_list[INVEN_MAIN_HAND].k_idx || can_attack_with_main_hand(this->player_ptr)) && (!this->player_ptr->inventory_list[INVEN_SUB_HAND].k_idx || can_attack_with_sub_hand(this->player_ptr))) {
115 if (!(PlayerRace(this->player_ptr).equals(PlayerRaceType::KLACKON) || PlayerRace(this->player_ptr).equals(PlayerRaceType::SPRITE) || (this->player_ptr->ppersonality == PERSONALITY_MUNCHKIN)))
116 result += (this->player_ptr->lev) / 10;
120 if ((this->player_ptr->pclass == PlayerClassType::MONK || this->player_ptr->pclass == PlayerClassType::FORCETRAINER) && !(heavy_armor(this->player_ptr))) {
121 if (!(PlayerRace(this->player_ptr).equals(PlayerRaceType::KLACKON) || PlayerRace(this->player_ptr).equals(PlayerRaceType::SPRITE) || (this->player_ptr->ppersonality == PERSONALITY_MUNCHKIN)))
122 result += (this->player_ptr->lev) / 10;
125 if (this->player_ptr->pclass == PlayerClassType::BERSERKER) {
127 if (this->player_ptr->lev > 29)
129 if (this->player_ptr->lev > 39)
131 if (this->player_ptr->lev > 44)
133 if (this->player_ptr->lev > 49)
143 * ** いかさまでクラッコン/妖精以外なら加算(+5+レベル/10)
145 int16_t PlayerSpeed::personality_value()
148 if (this->player_ptr->ppersonality == PERSONALITY_MUNCHKIN && this->player_ptr->prace != PlayerRaceType::KLACKON && this->player_ptr->prace != PlayerRaceType::SPRITE) {
149 result += (this->player_ptr->lev) / 10 + 5;
155 * @brief 速度計算 - 装備品特殊セット
158 * ** 棘セット装備中ならば加算(+7)
159 * ** アイシングデス-トゥインクル装備中ならば加算(+7)
161 int16_t PlayerSpeed::special_weapon_set_value()
164 if (has_melee_weapon(this->player_ptr, INVEN_MAIN_HAND) && has_melee_weapon(this->player_ptr, INVEN_SUB_HAND)) {
165 if ((this->player_ptr->inventory_list[INVEN_MAIN_HAND].name1 == ART_QUICKTHORN) && (this->player_ptr->inventory_list[INVEN_SUB_HAND].name1 == ART_TINYTHORN)) {
169 if ((this->player_ptr->inventory_list[INVEN_MAIN_HAND].name1 == ART_ICINGDEATH) && (this->player_ptr->inventory_list[INVEN_SUB_HAND].name1 == ART_TWINKLE)) {
180 * ** 装備品にTR_SPEEDがあれば加算(+pval+1
181 * ** セットで加速増減があるものを計算
183 int16_t PlayerSpeed::equipments_value()
185 int16_t result = PlayerStatusBase::equipments_value();
186 result += this->special_weapon_set_value();
192 * @brief 速度計算 - 一時的効果
197 * ** 呪術「衝撃のクローク」で加算(+3)
199 * ** 光速移動中は+999(最終的に+99になる)
201 int16_t PlayerSpeed::time_effect_value()
205 if (is_fast(this->player_ptr)) {
209 if (this->player_ptr->slow) {
213 if (this->player_ptr->realm1 == REALM_HEX) {
214 if (SpellHex(this->player_ptr).is_spelling_specific(HEX_SHOCK_CLOAK)) {
219 if (this->player_ptr->food >= PY_FOOD_MAX)
222 /* Temporary lightspeed forces to be maximum speed */
223 if (this->player_ptr->lightspeed)
235 int16_t PlayerSpeed::battleform_value()
238 if (PlayerClass(player_ptr).monk_stance_is(MonkStance::SUZAKU))
247 * ** 変異MUT3_XTRA_FATなら減算(-2)
248 * ** 変異MUT3_XTRA_LEGなら加算(+3)
249 * ** 変異MUT3_SHORT_LEGなら減算(-3)
251 int16_t PlayerSpeed::mutation_value()
255 const auto &muta = this->player_ptr->muta;
256 if (muta.has(MUTA::XTRA_FAT)) {
260 if (muta.has(MUTA::XTRA_LEGS)) {
264 if (muta.has(MUTA::SHORT_LEG)) {
275 * * 騎乗中ならばモンスターの加速に準拠、ただし騎乗技能値とモンスターレベルによるキャップ処理あり
277 int16_t PlayerSpeed::riding_value()
279 monster_type *riding_m_ptr = &(this->player_ptr)->current_floor_ptr->m_list[this->player_ptr->riding];
280 SPEED speed = riding_m_ptr->mspeed;
283 if (!this->player_ptr->riding) {
287 if (riding_m_ptr->mspeed > 110) {
288 result = (int16_t)((speed - 110) * (this->player_ptr->skill_exp[SKILL_RIDING] * 3 + this->player_ptr->lev * 160L - 10000L) / (22000L));
292 result = speed - 110;
295 result += (this->player_ptr->skill_exp[SKILL_RIDING] + this->player_ptr->lev * 160L) / 3200;
297 if (monster_fast_remaining(riding_m_ptr))
299 if (monster_slow_remaining(riding_m_ptr))
309 * * 所持品の重量による減速処理。乗馬時は別計算。
311 int16_t PlayerSpeed::inventory_weight_value()
314 auto weight = calc_inventory_weight(this->player_ptr);
315 if (this->player_ptr->riding) {
316 auto *riding_m_ptr = &(this->player_ptr)->current_floor_ptr->m_list[this->player_ptr->riding];
317 auto *riding_r_ptr = &r_info[riding_m_ptr->r_idx];
318 auto count = 1500 + riding_r_ptr->level * 25;
319 if (weight > count) {
320 result -= ((weight - count) / (count / 5));
323 auto count = calc_weight_limit(this->player_ptr);
324 if (weight > count) {
325 result -= ((weight - count) / (count / 5));
333 * @brief 速度計算 - ACTION
338 int16_t PlayerSpeed::action_value()
341 if (this->player_ptr->action == ACTION_SEARCH)
348 * @return 加速修正が0でない装備に対応したBIT_FLAG
350 * * セット二刀流は両手のフラグをONにする
352 BIT_FLAGS PlayerSpeed::equipments_flags(tr_type check_flag)
354 BIT_FLAGS result = PlayerStatusBase::equipments_flags(check_flag);
356 if (this->special_weapon_set_value() != 0)
357 set_bits(result, FLAG_CAUSE_INVEN_MAIN_HAND | FLAG_CAUSE_INVEN_SUB_HAND);
363 * @brief 速度計算 - 乗馬時の例外処理
366 * * 非乗馬時 - ここまでの修正値合算をそのまま使用
367 * * 乗馬時 - 乗馬の速度と重量減衰のみを計算
369 int16_t PlayerSpeed::set_exception_value(int16_t value)
371 if (this->player_ptr->riding) {
372 value = this->default_value;
373 value += this->riding_value();
374 value += this->inventory_weight_value();
375 value += this->action_value();