OSDN Git Service

d6f4e3253b7b383b2ead6179e64407011f18f6ab
[hengbandforosx/hengbandosx.git] / src / player-status / player-speed.cpp
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 "grid/grid.h"
6 #include "inventory/inventory-slot-types.h"
7 #include "monster-race/monster-race.h"
8 #include "monster/monster-status.h"
9 #include "mutation/mutation-flag-types.h"
10 #include "object-enchant/tr-types.h"
11 #include "object/object-flags.h"
12 #include "player-info/equipment-info.h"
13 #include "player/attack-defense-types.h"
14 #include "player/digestion-processor.h"
15 #include "player/player-race.h"
16 #include "player/player-skill.h"
17 #include "player/player-status-flags.h"
18 #include "player/player-status.h"
19 #include "player/special-defense-types.h"
20 #include "realm/realm-hex-numbers.h"
21 #include "realm/realm-types.h"
22 #include "spell-realm/spells-hex.h"
23 #include "system/floor-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"
29
30 /*
31  * @brief 速度 - 初期値、下限、上限
32  * @details
33  * * 初期値110 - 加速+0に相当
34  * * 上限209 - 加速+99相当
35  * * 下限11 - 加速-99相当
36  */
37 void PlayerSpeed::set_locals()
38 {
39     this->default_value = 110;
40     this->min_value = 11;
41     this->max_value = 209;
42     this->tr_flag = TR_SPEED;
43     this->tr_bad_flag = TR_SPEED;
44 }
45
46 /*
47  * @brief 速度計算 - 種族
48  * @return 速度値の増減分
49  * @details
50  * ** クラッコンと妖精に加算(+レベル/10)
51  * ** 悪魔変化/吸血鬼変化で加算(+3)
52  * ** 魔王変化で加算(+5)
53  * ** マーフォークがFF_WATER地形にいれば加算(+2+レベル/10)
54  * ** そうでなく浮遊を持っていないなら減算(-2)
55  */
56 s16b PlayerSpeed::race_value()
57 {
58     s16b result = 0;
59
60     if (is_specific_player_race(this->owner_ptr, RACE_KLACKON) || is_specific_player_race(this->owner_ptr, RACE_SPRITE))
61         result += (this->owner_ptr->lev) / 10;
62
63     if (is_specific_player_race(this->owner_ptr, RACE_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 (has_flag(f_ptr->flags, FF_WATER)) {
67             result += (2 + this->owner_ptr->lev / 10);
68         } else if (!this->owner_ptr->levitation) {
69             result -= 2;
70         }
71     }
72
73     if (this->owner_ptr->mimic_form) {
74         switch (this->owner_ptr->mimic_form) {
75         case MIMIC_DEMON:
76             result += 3;
77             break;
78         case MIMIC_DEMON_LORD:
79             result += 5;
80             break;
81         case MIMIC_VAMPIRE:
82             result += 3;
83             break;
84         }
85     }
86     return result;
87 }
88
89 /*
90  * @brief 速度計算 - 職業
91  * @return 速度値の増減分
92  * @details
93  * ** 忍者の装備が重ければ減算(-レベル/10)
94  * ** 忍者の装備が適正ならば加算(+3)さらにクラッコン、妖精、いかさま以外なら加算(+レベル/10)
95  * ** 錬気術師で装備が重くなくクラッコン、妖精、いかさま以外なら加算(+レベル/10)
96  * ** 狂戦士なら加算(+3),レベル20/30/40/50ごとに+1
97  */
98 s16b PlayerSpeed::class_value()
99 {
100     SPEED result = 0;
101
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))) {
107             result += 3;
108             if (!(is_specific_player_race(this->owner_ptr, RACE_KLACKON) || is_specific_player_race(this->owner_ptr, RACE_SPRITE)
109                     || (this->owner_ptr->pseikaku == PERSONALITY_MUNCHKIN)))
110                 result += (this->owner_ptr->lev) / 10;
111         }
112     }
113
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, RACE_KLACKON) || is_specific_player_race(this->owner_ptr, RACE_SPRITE)
116                 || (this->owner_ptr->pseikaku == PERSONALITY_MUNCHKIN)))
117             result += (this->owner_ptr->lev) / 10;
118     }
119
120     if (this->owner_ptr->pclass == CLASS_BERSERKER) {
121         result += 2;
122         if (this->owner_ptr->lev > 29)
123             result++;
124         if (this->owner_ptr->lev > 39)
125             result++;
126         if (this->owner_ptr->lev > 44)
127             result++;
128         if (this->owner_ptr->lev > 49)
129             result++;
130     }
131     return result;
132 }
133
134 /*
135  * @brief 速度計算 - 性格
136  * @return 速度値の増減分
137  * @details
138  * ** いかさまでクラッコン/妖精以外なら加算(+5+レベル/10)
139  */
140 s16b PlayerSpeed::personality_value()
141 {
142     s16b result = 0;
143     if (this->owner_ptr->pseikaku == PERSONALITY_MUNCHKIN && this->owner_ptr->prace != RACE_KLACKON && this->owner_ptr->prace != RACE_SPRITE) {
144         result += (this->owner_ptr->lev) / 10 + 5;
145     }
146     return result;
147 }
148
149 /*
150  * @brief 速度計算 - 装備品特殊セット
151  * @return 速度値の増減分
152  * @details
153  * ** 棘セット装備中ならば加算(+7)
154  * ** アイシングデス-トゥインクル装備中ならば加算(+7)
155  */
156 s16b PlayerSpeed::special_weapon_set_value()
157 {
158     s16b result = 0;
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)) {
162             result += 7;
163         }
164
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)) {
167             result += 5;
168         }
169     }
170     return result;
171 }
172
173 /*
174  * @brief 速度計算 - 装備品
175  * @return 速度値の増減分
176  * @details
177  * ** 装備品にTR_SPEEDがあれば加算(+pval+1
178  * ** セットで加速増減があるものを計算
179  */
180 s16b PlayerSpeed::equipments_value()
181 {
182     s16b result = PlayerStatusBase::equipments_value();
183     result += this->special_weapon_set_value();
184
185     return result;
186 }
187
188 /*
189  * @brief 速度計算 - 一時的効果
190  * @return 速度値の増減分
191  * @details
192  * ** 加速状態中なら加算(+10)
193  * ** 減速状態中なら減算(-10)
194  * ** 呪術「衝撃のクローク」で加算(+3)
195  * ** 食い過ぎなら減算(-10)
196  * ** 光速移動中は+999(最終的に+99になる)
197  */
198 s16b PlayerSpeed::time_effect_value()
199 {
200     s16b result = 0;
201
202     if (is_fast(this->owner_ptr)) {
203         result += 10;
204     }
205
206     if (this->owner_ptr->slow) {
207         result -= 10;
208     }
209
210     if (this->owner_ptr->realm1 == REALM_HEX) {
211         if (hex_spelling(this->owner_ptr, HEX_SHOCK_CLOAK)) {
212             result += 3;
213         }
214     }
215
216     if (this->owner_ptr->food >= PY_FOOD_MAX)
217         result -= 10;
218
219     /* Temporary lightspeed forces to be maximum speed */
220     if (this->owner_ptr->lightspeed)
221         result += 999;
222
223     return result;
224 }
225
226 /*
227  * @brief 速度計算 - 型
228  * @return 速度値の増減分
229  * @details
230  * ** 朱雀の構えなら加算(+10)
231  */
232 s16b PlayerSpeed::battleform_value()
233 {
234     s16b result = 0;
235     if (any_bits(this->owner_ptr->special_defense, KAMAE_SUZAKU))
236         result += 10;
237     return result;
238 }
239
240 /*
241  * @brief 速度計算 - 変異
242  * @return 速度値の増減分
243  * @details
244  * ** 変異MUT3_XTRA_FATなら減算(-2)
245  * ** 変異MUT3_XTRA_LEGなら加算(+3)
246  * ** 変異MUT3_SHORT_LEGなら減算(-3)
247  */
248 s16b PlayerSpeed::mutation_value()
249 {
250     SPEED result = 0;
251
252     const auto &muta = this->owner_ptr->muta;
253     if (muta.has(MUTA::XTRA_FAT)) {
254         result -= 2;
255     }
256
257     if (muta.has(MUTA::XTRA_LEGS)) {
258         result += 3;
259     }
260
261     if (muta.has(MUTA::SHORT_LEG)) {
262         result -= 3;
263     }
264
265     return result;
266 }
267
268 /*
269  * @brief 速度計算 - 乗馬
270  * @return 速度値の増減分
271  * @details
272  * * 騎乗中ならばモンスターの加速に準拠、ただし騎乗技能値とモンスターレベルによるキャップ処理あり
273  */
274 s16b PlayerSpeed::riding_value()
275 {
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;
278     SPEED result = 0;
279
280     if (!this->owner_ptr->riding) {
281         return 0;
282     }
283
284     if (riding_m_ptr->mspeed > 110) {
285         result = (s16b)((speed - 110) * (this->owner_ptr->skill_exp[SKILL_RIDING] * 3 + this->owner_ptr->lev * 160L - 10000L) / (22000L));
286         if (result < 0)
287             result = 0;
288     } else {
289         result = speed - 110;
290     }
291
292     result += (this->owner_ptr->skill_exp[SKILL_RIDING] + this->owner_ptr->lev * 160L) / 3200;
293
294     if (monster_fast_remaining(riding_m_ptr))
295         result += 10;
296     if (monster_slow_remaining(riding_m_ptr))
297         result -= 10;
298
299     return result;
300 }
301
302 /*
303  * @brief 速度計算 - 重量
304  * @return 速度値の増減分
305  * @details
306  * * 所持品の重量による減速処理。乗馬時は別計算。
307  */
308 s16b PlayerSpeed::inventory_weight_value()
309 {
310     SPEED result = 0;
311
312     int weight = calc_inventory_weight(this->owner_ptr);
313     int count;
314
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;
319
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;
322         }
323
324         if (weight > count) {
325             result -= ((weight - count) / (count / 5));
326         }
327     } else {
328         count = (int)calc_weight_limit(this->owner_ptr);
329         if (weight > count) {
330             result -= ((weight - count) / (count / 5));
331         }
332     }
333     return result;
334 }
335
336 /*
337  * @brief 速度計算 - ACTION
338  * @return 速度値の増減分
339  * @details
340  * * 探索中なら減算(-10)
341  */
342 s16b PlayerSpeed::action_value()
343 {
344     SPEED result = 0;
345     if (this->owner_ptr->action == ACTION_SEARCH)
346         result -= 10;
347     return result;
348 }
349
350 /*
351  * @brief 速度フラグ - 装備
352  * @return 加速修正が0でない装備に対応したBIT_FLAG
353  * @details
354  * * セット二刀流は両手のフラグをONにする
355  */
356 BIT_FLAGS PlayerSpeed::equipments_flags(tr_type check_flag)
357 {
358     BIT_FLAGS result = PlayerStatusBase::equipments_flags(check_flag);
359
360     if (this->special_weapon_set_value() != 0)
361         set_bits(result, FLAG_CAUSE_INVEN_MAIN_HAND | FLAG_CAUSE_INVEN_SUB_HAND);
362
363     return result;
364 }
365
366 /*
367  * @brief 速度計算 - 乗馬時の例外処理
368  * @return 計算済の速度値
369  * @details
370  * * 非乗馬時 - ここまでの修正値合算をそのまま使用
371  * * 乗馬時 - 乗馬の速度と重量減衰のみを計算
372  */
373 s16b PlayerSpeed::set_exception_value(s16b value)
374 {
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();
380     }
381     return value;
382 }