OSDN Git Service

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