OSDN Git Service

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