OSDN Git Service

9a1c06870d4165910122309db89dc44cf430b3f3
[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-checker.h"
13 #include "object-hook/hook-weapon.h"
14 #include "object/object-flags.h"
15 #include "player/mimic-info-table.h"
16 #include "player/player-class.h"
17 #include "player/player-race-types.h"
18 #include "player/player-race.h"
19 #include "player/player-skill.h"
20 #include "player/player-status-flags.h"
21 #include "player/player-status.h"
22 #include "player/special-defense-types.h"
23 #include "realm/realm-hex-numbers.h"
24 #include "realm/realm-song-numbers.h"
25 #include "realm/realm-types.h"
26 #include "spell-realm/spells-hex.h"
27 #include "status/element-resistance.h"
28 #include "sv-definition/sv-weapon-types.h"
29 #include "system/floor-type-definition.h"
30 #include "system/monster-type-definition.h"
31 #include "system/object-type-definition.h"
32 #include "system/player-type-definition.h"
33 #include "util/bit-flags-calculator.h"
34 #include "util/quarks.h"
35 #include "util/string-processor.h"
36
37 /*!
38  * @brief 耐性倍率計算の用途に応じた分岐処理
39  */
40 PERCENTAGE randrate(int dice, int fix, rate_calc_type_mode mode)
41 {
42     switch (mode) {
43     case CALC_RAND:
44         return randint1(dice) * 100 + fix * 100;
45         break;
46     case CALC_AVERAGE:
47         return (dice + 1) * 50 + fix * 100;
48         break;
49     case CALC_MIN:
50         return (fix + 1) * 100;
51         break;
52     case CALC_MAX:
53         return (dice + fix) * 100;
54         break;
55     default:
56         return (fix + 1) * 100;
57         break;
58     }
59 }
60
61 /*!
62  * @brief 酸属性攻撃に対するダメージ倍率計算
63  */
64 PERCENTAGE calc_acid_damage_rate(player_type *creature_ptr)
65 {
66     PERCENTAGE per = 100;
67
68     if (has_immune_acid(creature_ptr)) {
69         return 0;
70     }
71
72     BIT_FLAGS flgs = has_vuln_acid(creature_ptr);
73     
74     for (BIT_FLAGS check_flag = 0x01U; check_flag < FLAG_CAUSE_MAX; check_flag <<= 1) {
75         if (any_bits(flgs, check_flag)) {
76             if (check_flag == FLAG_CAUSE_MUTATION) {
77                 per *= 2;
78             } else {
79                 per += per / 3;
80             }
81         }
82     }
83
84     if (has_resist_acid(creature_ptr))
85         per = (per + 2) / 3;
86     if (is_oppose_acid(creature_ptr))
87         per = (per + 2) / 3;
88
89     return per;
90 }
91
92 /*!
93  * @brief 電撃属性攻撃に対するダメージ倍率計算
94  */
95 PERCENTAGE calc_elec_damage_rate(player_type *creature_ptr)
96 {
97     PERCENTAGE per = 100;
98
99     if (has_immune_elec(creature_ptr)) {
100         return 0;
101     }
102
103     BIT_FLAGS flgs = has_vuln_elec(creature_ptr);
104     for (BIT_FLAGS check_flag = 0x01U; check_flag < FLAG_CAUSE_MAX; check_flag <<= 1) {
105         if (any_bits(flgs, check_flag)) {
106             if (check_flag == FLAG_CAUSE_MUTATION) {
107                 per *= 2;
108             } else {
109                 per += per / 3;
110             }
111         }
112     }
113
114     if (has_resist_elec(creature_ptr))
115         per = (per + 2) / 3;
116     if (is_oppose_elec(creature_ptr))
117         per = (per + 2) / 3;
118
119     return per;
120 }
121
122 /*!
123  * @brief 火炎属性攻撃に対するダメージ倍率計算
124  */
125 PERCENTAGE calc_fire_damage_rate(player_type *creature_ptr)
126 {
127     PERCENTAGE per = 100;
128     BIT_FLAGS flgs = has_vuln_fire(creature_ptr);
129     for (BIT_FLAGS check_flag = 0x01U; check_flag < FLAG_CAUSE_MAX; check_flag <<= 1) {
130         if (any_bits(flgs, check_flag)) {
131             if (check_flag == FLAG_CAUSE_MUTATION) {
132                 per *= 2;
133             } else {
134                 per += per / 3;
135             }
136         }
137     }
138
139     /* Resist the damage */
140     if (has_resist_fire(creature_ptr))
141         per = (per + 2) / 3;
142     if (is_oppose_fire(creature_ptr))
143         per = (per + 2) / 3;
144
145     return per;
146 }
147
148 /*!
149  * @brief 冷気属性攻撃に対するダメージ倍率計算
150  */
151 PERCENTAGE calc_cold_damage_rate(player_type *creature_ptr)
152 {
153     PERCENTAGE per = 100;
154     BIT_FLAGS flgs = has_vuln_cold(creature_ptr);
155     for (BIT_FLAGS check_flag = 0x01U; check_flag < FLAG_CAUSE_MAX; check_flag <<= 1) {
156         if (any_bits(flgs, check_flag)) {
157             if (check_flag == FLAG_CAUSE_MUTATION) {
158                 per *= 2;
159             } else {
160                 per += per / 3;
161             }
162         }
163     }
164
165     if (has_resist_cold(creature_ptr))
166         per = (per + 2) / 3;
167     if (is_oppose_cold(creature_ptr))
168         per = (per + 2) / 3;
169
170     return per;
171 }
172
173 /*!
174  * @brief 毒属性攻撃に対するダメージ倍率計算
175  */
176 PERCENTAGE calc_pois_damage_rate(player_type *creature_ptr)
177 {
178     PERCENTAGE per = 100;
179     if (has_resist_pois(creature_ptr))
180         per = (per + 2) / 3;
181     if (is_oppose_pois(creature_ptr))
182         per = (per + 2) / 3;
183
184     return per;
185 }
186
187 /*!
188  * @brief 放射性廃棄物攻撃に対するダメージ倍率計算
189  */
190 PERCENTAGE calc_nuke_damage_rate(player_type *creature_ptr)
191 {
192
193     PERCENTAGE per = 100;
194     if (has_resist_pois(creature_ptr))
195         per = (2 * per + 2) / 5;
196     if (is_oppose_pois(creature_ptr))
197         per = (2 * per + 2) / 5;
198
199     return per;
200 }
201
202 /*!
203  * @brief 死の光線に対するダメージ倍率計算
204  */
205 PERCENTAGE calc_deathray_damage_rate(player_type *creature_ptr, rate_calc_type_mode mode)
206 {
207     (void)mode; // unused
208     if (creature_ptr->mimic_form) {
209         if (mimic_info[creature_ptr->mimic_form].MIMIC_FLAGS & MIMIC_IS_NONLIVING) {
210             return 0;
211         }
212     }
213
214     switch (creature_ptr->prace) {
215     case RACE_GOLEM:
216     case RACE_SKELETON:
217     case RACE_ZOMBIE:
218     case RACE_VAMPIRE:
219     case RACE_BALROG:
220     case RACE_SPECTRE:
221         return 0;
222         break;
223
224     default:
225         break;
226     }
227
228     return 100;
229 }
230
231 /*!
232  * @brief 閃光属性攻撃に対するダメージ倍率計算
233  */
234 PERCENTAGE calc_lite_damage_rate(player_type *creature_ptr, rate_calc_type_mode mode)
235 {
236     PERCENTAGE per = 100;
237
238     if (player_race_has_flag(creature_ptr, TR_VUL_LITE)) {
239         switch (player_race_life(creature_ptr)) {
240         case PlayerRaceLife::UNDEAD:
241             per *= 2;
242             break;
243         default:
244             per = per * 4 / 3;
245             break;
246         }
247     }
248
249     if (has_resist_lite(creature_ptr)) {
250         per *= 400;
251         per /= randrate(4, 7, mode);
252     }
253
254     if (creature_ptr->wraith_form)
255         per *= 2;
256
257     return per;
258 }
259
260 /*!
261  * @brief 暗黒属性攻撃に対するダメージ倍率計算
262  */
263 PERCENTAGE calc_dark_damage_rate(player_type *creature_ptr, rate_calc_type_mode mode)
264 {
265     PERCENTAGE per = 100;
266
267     if (has_immune_dark(creature_ptr))
268         return 0;
269
270     if (has_resist_dark(creature_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(player_type *creature_ptr, rate_calc_type_mode mode)
282 {
283     PERCENTAGE per = 100;
284
285     if (has_resist_shard(creature_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(player_type *creature_ptr, rate_calc_type_mode mode)
297 {
298     PERCENTAGE per = 100;
299
300     if (has_resist_sound(creature_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(player_type *creature_ptr, rate_calc_type_mode mode)
312 {
313     PERCENTAGE per = 100;
314
315     if (has_resist_conf(creature_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(player_type *creature_ptr, rate_calc_type_mode mode)
327 {
328     PERCENTAGE per = 100;
329
330     if (has_resist_chaos(creature_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(player_type *creature_ptr, rate_calc_type_mode mode)
342 {
343     PERCENTAGE per = 100;
344
345     if (has_resist_disen(creature_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(player_type *creature_ptr, rate_calc_type_mode mode)
357 {
358     PERCENTAGE per = 100;
359
360     if (has_resist_disen(creature_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(player_type *creature_ptr, rate_calc_type_mode mode)
372 {
373     (void)mode; // unused
374     PERCENTAGE per = 100;
375
376     if (has_resist_shard(creature_ptr)) {
377         per /= 2;
378     }
379
380     return per;
381 }
382
383 /*!
384  * @brief 地獄属性攻撃に対するダメージ倍率計算
385  */
386 PERCENTAGE calc_nether_damage_rate(player_type *creature_ptr, rate_calc_type_mode mode)
387 {
388     PERCENTAGE per = 100;
389
390     if (has_resist_neth(creature_ptr)) {
391         if (!is_specific_player_race(creature_ptr, RACE_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(player_type *creature_ptr, rate_calc_type_mode mode)
404 {
405     (void)mode; // unused
406     PERCENTAGE per = 100;
407
408     if (has_resist_time(creature_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(player_type *creature_ptr, rate_calc_type_mode mode)
420 {
421     (void)mode; // unused
422     PERCENTAGE per = 100;
423
424     if (has_resist_water(creature_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(player_type *creature_ptr, rate_calc_type_mode mode)
436 {
437     (void)mode; // unused
438     PERCENTAGE per = 100;
439     if (creature_ptr->align > 10)
440         per /= 2;
441     else if (creature_ptr->align < -10)
442         per *= 2;
443     return per;
444 }
445
446 /*!
447  * @brief 地獄の火炎攻撃に対するダメージ倍率計算
448  */
449 PERCENTAGE calc_hell_fire_damage_rate(player_type *creature_ptr, rate_calc_type_mode mode)
450 {
451     (void)mode; // unused
452     PERCENTAGE per = 100;
453     if (creature_ptr->align > 10)
454         per *= 2;
455     return per;
456 }
457
458 /*!
459  * @brief 重力攻撃に対するダメージ倍率計算
460  */
461 PERCENTAGE calc_gravity_damage_rate(player_type *creature_ptr, rate_calc_type_mode mode)
462 {
463     (void)mode; // unused
464     PERCENTAGE per = 100;
465     if (creature_ptr->levitation) {
466         per = (per * 2) / 3;
467     }
468     return per;
469 }
470
471 /*!
472  * @brief 虚無攻撃に対するダメージ倍率計算
473  */
474 PERCENTAGE calc_void_damage_rate(player_type *creature_ptr, rate_calc_type_mode mode)
475 {
476     (void)mode; // unused
477     PERCENTAGE per = 100;
478     if (creature_ptr->tim_pass_wall) {
479         per = per * 3 / 2;
480     } else if (creature_ptr->anti_tele) {
481         per *= 400;
482         per /= randrate(4, 7, mode);
483     } else if (creature_ptr->levitation) {
484         per = (per * 2) / 3;
485     }
486     return per;
487 }
488
489 /*!
490  * @brief 深淵攻撃に対するダメージ倍率計算
491  */
492 PERCENTAGE calc_abyss_damage_rate(player_type *creature_ptr, rate_calc_type_mode mode)
493 {
494     (void)mode; // unused
495     PERCENTAGE per = 100;
496
497     if (has_resist_dark(creature_ptr)) {
498         per *= 400;
499         per /= randrate(4, 7, mode);
500     } else if (!creature_ptr->levitation && creature_ptr->anti_tele) {
501         per = (per * 5) / 4;
502     }
503     return per;
504 }