OSDN Git Service

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