OSDN Git Service

[Refactor] struct player_type を class PlayerType に置換。
[hengbandforosx/hengbandosx.git] / src / player / player-status-resist.cpp
1 #include "player/player-status-resist.h"
2 #include "artifact/fixed-art-types.h"
3 #include "grid/grid.h"
4 #include "inventory/inventory-slot-types.h"
5 #include "monster-race/monster-race.h"
6 #include "monster-race/race-flags2.h"
7 #include "monster-race/race-flags7.h"
8 #include "mutation/mutation-flag-types.h"
9 #include "object-enchant/object-ego.h"
10 #include "object-enchant/tr-types.h"
11 #include "object-enchant/trc-types.h"
12 #include "object-hook/hook-weapon.h"
13 #include "object/object-flags.h"
14 #include "player-base/player-race.h"
15 #include "player-info/class-info.h"
16 #include "player-info/race-info.h"
17 #include "player/player-skill.h"
18 #include "player/player-status-flags.h"
19 #include "player/player-status.h"
20 #include "player/special-defense-types.h"
21 #include "realm/realm-hex-numbers.h"
22 #include "realm/realm-song-numbers.h"
23 #include "realm/realm-types.h"
24 #include "spell-realm/spells-hex.h"
25 #include "status/element-resistance.h"
26 #include "sv-definition/sv-weapon-types.h"
27 #include "system/floor-type-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"
32 #include "util/quarks.h"
33 #include "util/string-processor.h"
34
35 /*!
36  * @brief 耐性倍率計算の用途に応じた分岐処理
37  */
38 PERCENTAGE randrate(int dice, int fix, rate_calc_type_mode mode)
39 {
40     switch (mode) {
41     case CALC_RAND:
42         return randint1(dice) * 100 + fix * 100;
43         break;
44     case CALC_AVERAGE:
45         return (dice + 1) * 50 + fix * 100;
46         break;
47     case CALC_MIN:
48         return (fix + 1) * 100;
49         break;
50     case CALC_MAX:
51         return (dice + fix) * 100;
52         break;
53     default:
54         return (fix + 1) * 100;
55         break;
56     }
57 }
58
59 /*!
60  * @brief 酸属性攻撃に対するダメージ倍率計算
61  */
62 PERCENTAGE calc_acid_damage_rate(PlayerType *player_ptr)
63 {
64     PERCENTAGE per = 100;
65
66     if (has_immune_acid(player_ptr)) {
67         return 0;
68     }
69
70     BIT_FLAGS flgs = has_vuln_acid(player_ptr);
71
72     for (BIT_FLAGS check_flag = 0x01U; check_flag < FLAG_CAUSE_MAX; check_flag <<= 1) {
73         if (any_bits(flgs, check_flag)) {
74             if (check_flag == FLAG_CAUSE_MUTATION) {
75                 per *= 2;
76             } else {
77                 per += per / 3;
78             }
79         }
80     }
81
82     if (has_resist_acid(player_ptr))
83         per = (per + 2) / 3;
84     if (is_oppose_acid(player_ptr))
85         per = (per + 2) / 3;
86
87     return per;
88 }
89
90 /*!
91  * @brief 電撃属性攻撃に対するダメージ倍率計算
92  */
93 PERCENTAGE calc_elec_damage_rate(PlayerType *player_ptr)
94 {
95     PERCENTAGE per = 100;
96
97     if (has_immune_elec(player_ptr)) {
98         return 0;
99     }
100
101     BIT_FLAGS flgs = has_vuln_elec(player_ptr);
102     for (BIT_FLAGS check_flag = 0x01U; check_flag < FLAG_CAUSE_MAX; check_flag <<= 1) {
103         if (any_bits(flgs, check_flag)) {
104             if (check_flag == FLAG_CAUSE_MUTATION) {
105                 per *= 2;
106             } else {
107                 per += per / 3;
108             }
109         }
110     }
111
112     if (has_resist_elec(player_ptr))
113         per = (per + 2) / 3;
114     if (is_oppose_elec(player_ptr))
115         per = (per + 2) / 3;
116
117     return per;
118 }
119
120 /*!
121  * @brief 火炎属性攻撃に対するダメージ倍率計算
122  */
123 PERCENTAGE calc_fire_damage_rate(PlayerType *player_ptr)
124 {
125     PERCENTAGE per = 100;
126     BIT_FLAGS flgs = has_vuln_fire(player_ptr);
127     for (BIT_FLAGS check_flag = 0x01U; check_flag < FLAG_CAUSE_MAX; check_flag <<= 1) {
128         if (any_bits(flgs, check_flag)) {
129             if (check_flag == FLAG_CAUSE_MUTATION) {
130                 per *= 2;
131             } else {
132                 per += per / 3;
133             }
134         }
135     }
136
137     /* Resist the damage */
138     if (has_resist_fire(player_ptr))
139         per = (per + 2) / 3;
140     if (is_oppose_fire(player_ptr))
141         per = (per + 2) / 3;
142
143     return per;
144 }
145
146 /*!
147  * @brief 冷気属性攻撃に対するダメージ倍率計算
148  */
149 PERCENTAGE calc_cold_damage_rate(PlayerType *player_ptr)
150 {
151     PERCENTAGE per = 100;
152     BIT_FLAGS flgs = has_vuln_cold(player_ptr);
153     for (BIT_FLAGS check_flag = 0x01U; check_flag < FLAG_CAUSE_MAX; check_flag <<= 1) {
154         if (any_bits(flgs, check_flag)) {
155             if (check_flag == FLAG_CAUSE_MUTATION) {
156                 per *= 2;
157             } else {
158                 per += per / 3;
159             }
160         }
161     }
162
163     if (has_resist_cold(player_ptr))
164         per = (per + 2) / 3;
165     if (is_oppose_cold(player_ptr))
166         per = (per + 2) / 3;
167
168     return per;
169 }
170
171 /*!
172  * @brief 毒属性攻撃に対するダメージ倍率計算
173  */
174 PERCENTAGE calc_pois_damage_rate(PlayerType *player_ptr)
175 {
176     PERCENTAGE per = 100;
177     if (has_resist_pois(player_ptr))
178         per = (per + 2) / 3;
179     if (is_oppose_pois(player_ptr))
180         per = (per + 2) / 3;
181
182     return per;
183 }
184
185 /*!
186  * @brief 放射性廃棄物攻撃に対するダメージ倍率計算
187  */
188 PERCENTAGE calc_nuke_damage_rate(PlayerType *player_ptr)
189 {
190
191     PERCENTAGE per = 100;
192     if (has_resist_pois(player_ptr))
193         per = (2 * per + 2) / 5;
194     if (is_oppose_pois(player_ptr))
195         per = (2 * per + 2) / 5;
196
197     return per;
198 }
199
200 /*!
201  * @brief 死の光線に対するダメージ倍率計算
202  */
203 PERCENTAGE calc_deathray_damage_rate(PlayerType *player_ptr, rate_calc_type_mode mode)
204 {
205     (void)mode; // unused
206     if (player_ptr->mimic_form) {
207         if (PlayerRace(player_ptr).is_mimic_nonliving()) {
208             return 0;
209         }
210     }
211
212     switch (player_ptr->prace) {
213     case PlayerRaceType::GOLEM:
214     case PlayerRaceType::SKELETON:
215     case PlayerRaceType::ZOMBIE:
216     case PlayerRaceType::VAMPIRE:
217     case PlayerRaceType::BALROG:
218     case PlayerRaceType::SPECTRE:
219         return 0;
220         break;
221
222     default:
223         break;
224     }
225
226     return 100;
227 }
228
229 /*!
230  * @brief 閃光属性攻撃に対するダメージ倍率計算
231  */
232 PERCENTAGE calc_lite_damage_rate(PlayerType *player_ptr, rate_calc_type_mode mode)
233 {
234     PERCENTAGE per = 100;
235
236     PlayerRace race(player_ptr);
237
238     if (race.tr_flags().has(TR_VUL_LITE)) {
239         switch (race.life()) {
240         case PlayerRaceLifeType::UNDEAD:
241             per *= 2;
242             break;
243         default:
244             per = per * 4 / 3;
245             break;
246         }
247     }
248
249     if (has_resist_lite(player_ptr)) {
250         per *= 400;
251         per /= randrate(4, 7, mode);
252     }
253
254     if (player_ptr->wraith_form)
255         per *= 2;
256
257     return per;
258 }
259
260 /*!
261  * @brief 暗黒属性攻撃に対するダメージ倍率計算
262  */
263 PERCENTAGE calc_dark_damage_rate(PlayerType *player_ptr, rate_calc_type_mode mode)
264 {
265     PERCENTAGE per = 100;
266
267     if (has_immune_dark(player_ptr))
268         return 0;
269
270     if (has_resist_dark(player_ptr)) {
271         per *= 400;
272         per /= randrate(4, 7, mode);
273     }
274
275     return per;
276 }
277
278 /*!
279  * @brief 破片属性攻撃に対するダメージ倍率計算
280  */
281 PERCENTAGE calc_shards_damage_rate(PlayerType *player_ptr, rate_calc_type_mode mode)
282 {
283     PERCENTAGE per = 100;
284
285     if (has_resist_shard(player_ptr)) {
286         per *= 600;
287         per /= randrate(4, 7, mode);
288     }
289
290     return per;
291 }
292
293 /*!
294  * @brief 轟音属性攻撃に対するダメージ倍率計算
295  */
296 PERCENTAGE calc_sound_damage_rate(PlayerType *player_ptr, rate_calc_type_mode mode)
297 {
298     PERCENTAGE per = 100;
299
300     if (has_resist_sound(player_ptr)) {
301         per *= 500;
302         per /= randrate(4, 7, mode);
303     }
304
305     return per;
306 }
307
308 /*!
309  * @brief 混乱属性攻撃に対するダメージ倍率計算
310  */
311 PERCENTAGE calc_conf_damage_rate(PlayerType *player_ptr, rate_calc_type_mode mode)
312 {
313     PERCENTAGE per = 100;
314
315     if (has_resist_conf(player_ptr)) {
316         per *= 500;
317         per /= randrate(4, 7, mode);
318     }
319
320     return per;
321 }
322
323 /*!
324  * @brief 混沌属性攻撃に対するダメージ倍率計算
325  */
326 PERCENTAGE calc_chaos_damage_rate(PlayerType *player_ptr, rate_calc_type_mode mode)
327 {
328     PERCENTAGE per = 100;
329
330     if (has_resist_chaos(player_ptr)) {
331         per *= 600;
332         per /= randrate(4, 7, mode);
333     }
334
335     return per;
336 }
337
338 /*!
339  * @brief 劣化属性攻撃に対するダメージ倍率計算
340  */
341 PERCENTAGE calc_disenchant_damage_rate(PlayerType *player_ptr, rate_calc_type_mode mode)
342 {
343     PERCENTAGE per = 100;
344
345     if (has_resist_disen(player_ptr)) {
346         per *= 600;
347         per /= randrate(4, 7, mode);
348     }
349
350     return per;
351 }
352
353 /*!
354  * @brief 因果混乱属性攻撃に対するダメージ倍率計算
355  */
356 PERCENTAGE calc_nexus_damage_rate(PlayerType *player_ptr, rate_calc_type_mode mode)
357 {
358     PERCENTAGE per = 100;
359
360     if (has_resist_disen(player_ptr)) {
361         per *= 600;
362         per /= randrate(4, 7, mode);
363     }
364
365     return per;
366 }
367
368 /*!
369  * @brief ロケット属性攻撃に対するダメージ倍率計算
370  */
371 PERCENTAGE calc_rocket_damage_rate(PlayerType *player_ptr, rate_calc_type_mode mode)
372 {
373     (void)mode; // unused
374     PERCENTAGE per = 100;
375
376     if (has_resist_shard(player_ptr)) {
377         per /= 2;
378     }
379
380     return per;
381 }
382
383 /*!
384  * @brief 地獄属性攻撃に対するダメージ倍率計算
385  */
386 PERCENTAGE calc_nether_damage_rate(PlayerType *player_ptr, rate_calc_type_mode mode)
387 {
388     PERCENTAGE per = 100;
389
390     if (has_resist_neth(player_ptr)) {
391         if (!PlayerRace(player_ptr).equals(PlayerRaceType::SPECTRE))
392             per *= 6;
393         per *= 100;
394         per /= randrate(4, 7, mode);
395     }
396
397     return per;
398 }
399
400 /*!
401  * @brief 時間逆転攻撃に対するダメージ倍率計算
402  */
403 PERCENTAGE calc_time_damage_rate(PlayerType *player_ptr, rate_calc_type_mode mode)
404 {
405     (void)mode; // unused
406     PERCENTAGE per = 100;
407
408     if (has_resist_time(player_ptr)) {
409         per *= 400;
410         per /= randrate(4, 7, mode);
411     }
412
413     return per;
414 }
415
416 /*!
417  * @brief 水流攻撃に対するダメージ倍率計算
418  */
419 PERCENTAGE calc_water_damage_rate(PlayerType *player_ptr, rate_calc_type_mode mode)
420 {
421     (void)mode; // unused
422     PERCENTAGE per = 100;
423
424     if (has_resist_water(player_ptr)) {
425         per *= 400;
426         per /= randrate(4, 7, mode);
427     }
428
429     return per;
430 }
431
432 /*!
433  * @brief 聖なる火炎攻撃に対するダメージ倍率計算
434  */
435 PERCENTAGE calc_holy_fire_damage_rate(PlayerType *player_ptr, rate_calc_type_mode mode)
436 {
437     (void)mode; // unused
438     PERCENTAGE per = 100;
439     if (player_ptr->alignment > 10)
440         per /= 2;
441     else if (player_ptr->alignment < -10)
442         per *= 2;
443     return per;
444 }
445
446 /*!
447  * @brief 地獄の火炎攻撃に対するダメージ倍率計算
448  */
449 PERCENTAGE calc_hell_fire_damage_rate(PlayerType *player_ptr, rate_calc_type_mode mode)
450 {
451     (void)mode; // unused
452     PERCENTAGE per = 100;
453     if (player_ptr->alignment > 10)
454         per *= 2;
455     return per;
456 }
457
458 /*!
459  * @brief 重力攻撃に対するダメージ倍率計算
460  */
461 PERCENTAGE calc_gravity_damage_rate(PlayerType *player_ptr, rate_calc_type_mode mode)
462 {
463     (void)mode; // unused
464     PERCENTAGE per = 100;
465     if (player_ptr->levitation) {
466         per = (per * 2) / 3;
467     }
468     return per;
469 }
470
471 /*!
472  * @brief 虚無攻撃に対するダメージ倍率計算
473  */
474 PERCENTAGE calc_void_damage_rate(PlayerType *player_ptr, rate_calc_type_mode mode)
475 {
476     (void)mode; // unused
477     PERCENTAGE per = 100;
478     if (player_ptr->tim_pass_wall) {
479         per = per * 3 / 2;
480     } else if (player_ptr->anti_tele) {
481         per *= 400;
482         per /= randrate(4, 7, mode);
483     } else if (player_ptr->levitation) {
484         per = (per * 2) / 3;
485     }
486     return per;
487 }
488
489 /*!
490  * @brief 深淵攻撃に対するダメージ倍率計算
491  */
492 PERCENTAGE calc_abyss_damage_rate(PlayerType *player_ptr, rate_calc_type_mode mode)
493 {
494     (void)mode; // unused
495     PERCENTAGE per = 100;
496
497     if (has_resist_dark(player_ptr)) {
498         per *= 400;
499         per /= randrate(4, 7, mode);
500     } else if (!player_ptr->levitation && player_ptr->anti_tele) {
501         per = (per * 5) / 4;
502     }
503     return per;
504 }