OSDN Git Service

Merge remote-tracking branch 'remotes/origin/feature/Fix-Sanity-Blast-by-AutoSave...
[hengband/hengband.git] / src / player / permanent-resistances.c
1 #include "permanent-resistances.h"
2 #include "inventory/inventory-slot-types.h"
3 #include "mutation/mutation-flag-types.h"
4 #include "object-enchant/tr-types.h"
5 #include "player/player-personalities-types.h"
6 #include "player/player-race-types.h"
7 #include "player/player-race.h"
8 #include "player/player-status-flags.h"
9 #include "player/special-defense-types.h"
10 #include "system/object-type-definition.h"
11 #include "util/bit-flags-calculator.h"
12
13 /*!
14  * @brief プレーヤーの職業による耐性フラグを返す
15  * @param creature_ptr プレーヤーへの参照ポインタ
16  * @param flags 耐性フラグの配列
17  * @return なし
18  * @todo 最終的にplayer-status系列と統合する
19  */
20 static void add_class_flags(player_type *creature_ptr, BIT_FLAGS *flags)
21 {
22     switch (creature_ptr->pclass) {
23     case CLASS_WARRIOR: {
24         if (creature_ptr->lev > 29)
25             add_flag(flags, TR_RES_FEAR);
26         if (creature_ptr->lev > 44)
27             add_flag(flags, TR_REGEN);
28
29         break;
30     }
31     case CLASS_SAMURAI: {
32         if (creature_ptr->lev > 29)
33             add_flag(flags, TR_RES_FEAR);
34
35         break;
36     }
37     case CLASS_PALADIN: {
38         if (creature_ptr->lev > 39)
39             add_flag(flags, TR_RES_FEAR);
40
41         break;
42     }
43     case CLASS_CHAOS_WARRIOR: {
44         if (creature_ptr->lev > 29)
45             add_flag(flags, TR_RES_CHAOS);
46         if (creature_ptr->lev > 39)
47             add_flag(flags, TR_RES_FEAR);
48
49         break;
50     }
51     case CLASS_MONK:
52     case CLASS_FORCETRAINER: {
53         if ((creature_ptr->lev > 9) && !heavy_armor(creature_ptr))
54             add_flag(flags, TR_SPEED);
55         if ((creature_ptr->lev > 24) && !heavy_armor(creature_ptr))
56             add_flag(flags, TR_FREE_ACT);
57
58         break;
59     }
60     case CLASS_NINJA: {
61         if (heavy_armor(creature_ptr)) {
62             add_flag(flags, TR_SPEED);
63         } else {
64             if ((!creature_ptr->inventory_list[INVEN_MAIN_HAND].k_idx || can_attack_with_main_hand(creature_ptr))
65                 && (!creature_ptr->inventory_list[INVEN_SUB_HAND].k_idx || can_attack_with_sub_hand(creature_ptr)))
66                 add_flag(flags, TR_SPEED);
67             if (creature_ptr->lev > 24 && !creature_ptr->icky_wield[0] && !creature_ptr->icky_wield[1])
68                 add_flag(flags, TR_FREE_ACT);
69         }
70
71         add_flag(flags, TR_SLOW_DIGEST);
72         add_flag(flags, TR_RES_FEAR);
73         if (creature_ptr->lev > 19)
74             add_flag(flags, TR_RES_POIS);
75         if (creature_ptr->lev > 24)
76             add_flag(flags, TR_SUST_DEX);
77         if (creature_ptr->lev > 29)
78             add_flag(flags, TR_SEE_INVIS);
79
80         break;
81     }
82     case CLASS_MINDCRAFTER: {
83         if (creature_ptr->lev > 9)
84             add_flag(flags, TR_RES_FEAR);
85         if (creature_ptr->lev > 19)
86             add_flag(flags, TR_SUST_WIS);
87         if (creature_ptr->lev > 29)
88             add_flag(flags, TR_RES_CONF);
89         if (creature_ptr->lev > 39)
90             add_flag(flags, TR_TELEPATHY);
91
92         break;
93     }
94     case CLASS_BARD: {
95         add_flag(flags, TR_RES_SOUND);
96         break;
97     }
98     case CLASS_BERSERKER: {
99         add_flag(flags, TR_SUST_STR);
100         add_flag(flags, TR_SUST_DEX);
101         add_flag(flags, TR_SUST_CON);
102         add_flag(flags, TR_REGEN);
103         add_flag(flags, TR_FREE_ACT);
104         add_flag(flags, TR_SPEED);
105         if (creature_ptr->lev > 39)
106             add_flag(flags, TR_REFLECT);
107
108         break;
109     }
110     case CLASS_MIRROR_MASTER: {
111         if (creature_ptr->lev > 39)
112             add_flag(flags, TR_REFLECT);
113
114         break;
115     }
116     default:
117         break;
118     }
119 }
120
121 /*!
122  * @brief 特定の種族に擬態中の耐性フラグを返す
123  * @param creature_ptr プレーヤーへの参照ポインタ
124  * @param flags 耐性フラグの配列
125  * @return なし
126  * @todo 最終的にplayer-status系列と統合する
127  */
128 static void add_mimic_form_flags(player_type *creature_ptr, BIT_FLAGS *flags)
129 {
130     switch (creature_ptr->mimic_form) {
131     case MIMIC_DEMON:
132         add_flag(flags, TR_HOLD_EXP);
133         add_flag(flags, TR_RES_CHAOS);
134         add_flag(flags, TR_RES_NETHER);
135         add_flag(flags, TR_RES_FIRE);
136         add_flag(flags, TR_SEE_INVIS);
137         add_flag(flags, TR_SPEED);
138         break;
139     case MIMIC_DEMON_LORD:
140         add_flag(flags, TR_HOLD_EXP);
141         add_flag(flags, TR_RES_CHAOS);
142         add_flag(flags, TR_RES_NETHER);
143         add_flag(flags, TR_RES_FIRE);
144         add_flag(flags, TR_RES_COLD);
145         add_flag(flags, TR_RES_ELEC);
146         add_flag(flags, TR_RES_ACID);
147         add_flag(flags, TR_RES_POIS);
148         add_flag(flags, TR_RES_CONF);
149         add_flag(flags, TR_RES_DISEN);
150         add_flag(flags, TR_RES_NEXUS);
151         add_flag(flags, TR_RES_FEAR);
152         add_flag(flags, TR_IM_FIRE);
153         add_flag(flags, TR_SH_FIRE);
154         add_flag(flags, TR_SEE_INVIS);
155         add_flag(flags, TR_TELEPATHY);
156         add_flag(flags, TR_LEVITATION);
157         add_flag(flags, TR_SPEED);
158         break;
159     case MIMIC_VAMPIRE:
160         add_flag(flags, TR_HOLD_EXP);
161         add_flag(flags, TR_RES_DARK);
162         add_flag(flags, TR_RES_NETHER);
163         if (creature_ptr->pclass != CLASS_NINJA)
164             add_flag(flags, TR_LITE_1);
165         add_flag(flags, TR_RES_POIS);
166         add_flag(flags, TR_RES_COLD);
167         add_flag(flags, TR_SEE_INVIS);
168         add_flag(flags, TR_SPEED);
169         break;
170     }
171 }
172
173 /*!
174  * @brief 種族ベースの耐性フラグを返す
175  * @param creature_ptr プレーヤーへの参照ポインタ
176  * @param flags 耐性フラグの配列
177  * @return なし
178  * @todo 最終的にplayer-status系列と統合する
179  */
180 static void add_race_flags(player_type *creature_ptr, BIT_FLAGS *flags)
181 {
182     /* Common for all races */
183     if (rp_ptr->infra > 0)
184         add_flag(flags, TR_INFRA);
185
186     /* Unique for each race */
187     switch (creature_ptr->prace) {
188     case RACE_ELF: {
189         add_flag(flags, TR_RES_LITE);
190         break;
191     }
192     case RACE_HOBBIT: {
193         add_flag(flags, TR_HOLD_EXP);
194         break;
195     }
196     case RACE_GNOME: {
197         add_flag(flags, TR_FREE_ACT);
198         break;
199     }
200     case RACE_DWARF: {
201         add_flag(flags, TR_RES_BLIND);
202         break;
203     }
204     case RACE_HALF_ORC: {
205         add_flag(flags, TR_RES_DARK);
206         break;
207     }
208     case RACE_HALF_TROLL: {
209         add_flag(flags, TR_SUST_STR);
210         if (creature_ptr->lev <= 14)
211             break;
212
213         add_flag(flags, TR_REGEN);
214         if ((creature_ptr->pclass == CLASS_WARRIOR) || (creature_ptr->pclass == CLASS_BERSERKER))
215             add_flag(flags, TR_SLOW_DIGEST);
216
217         break;
218     }
219     case RACE_AMBERITE: {
220         add_flag(flags, TR_SUST_CON);
221         add_flag(flags, TR_REGEN);
222         break;
223     }
224     case RACE_HIGH_ELF: {
225         add_flag(flags, TR_RES_LITE);
226         add_flag(flags, TR_SEE_INVIS);
227         break;
228     }
229     case RACE_BARBARIAN: {
230         add_flag(flags, TR_RES_FEAR);
231         break;
232     }
233     case RACE_HALF_OGRE: {
234         add_flag(flags, TR_SUST_STR);
235         add_flag(flags, TR_RES_DARK);
236         break;
237     }
238     case RACE_HALF_GIANT: {
239         add_flag(flags, TR_RES_SHARDS);
240         add_flag(flags, TR_SUST_STR);
241         break;
242     }
243     case RACE_HALF_TITAN: {
244         add_flag(flags, TR_RES_CHAOS);
245         break;
246     }
247     case RACE_CYCLOPS: {
248         add_flag(flags, TR_RES_SOUND);
249         break;
250     }
251     case RACE_YEEK: {
252         add_flag(flags, TR_RES_ACID);
253         if (creature_ptr->lev > 19)
254             add_flag(flags, TR_IM_ACID);
255
256         break;
257     }
258     case RACE_KLACKON: {
259         add_flag(flags, TR_RES_CONF);
260         add_flag(flags, TR_RES_ACID);
261         if (creature_ptr->lev > 9)
262             add_flag(flags, TR_SPEED);
263
264         break;
265     }
266     case RACE_KOBOLD: {
267         add_flag(flags, TR_RES_POIS);
268         break;
269     }
270     case RACE_NIBELUNG: {
271         add_flag(flags, TR_RES_DISEN);
272         add_flag(flags, TR_RES_DARK);
273         break;
274     }
275     case RACE_DARK_ELF: {
276         add_flag(flags, TR_RES_DARK);
277         if (creature_ptr->lev > 19)
278             add_flag(flags, TR_SEE_INVIS);
279
280         break;
281     }
282     case RACE_DRACONIAN: {
283         add_flag(flags, TR_LEVITATION);
284         if (creature_ptr->lev > 4)
285             add_flag(flags, TR_RES_FIRE);
286         if (creature_ptr->lev > 9)
287             add_flag(flags, TR_RES_COLD);
288         if (creature_ptr->lev > 14)
289             add_flag(flags, TR_RES_ACID);
290         if (creature_ptr->lev > 19)
291             add_flag(flags, TR_RES_ELEC);
292         if (creature_ptr->lev > 34)
293             add_flag(flags, TR_RES_POIS);
294
295         break;
296     }
297     case RACE_MIND_FLAYER: {
298         add_flag(flags, TR_SUST_INT);
299         add_flag(flags, TR_SUST_WIS);
300         if (creature_ptr->lev > 14)
301             add_flag(flags, TR_SEE_INVIS);
302         if (creature_ptr->lev > 29)
303             add_flag(flags, TR_TELEPATHY);
304
305         break;
306     }
307     case RACE_IMP: {
308         add_flag(flags, TR_RES_FIRE);
309         if (creature_ptr->lev > 9)
310             add_flag(flags, TR_SEE_INVIS);
311         break;
312     }
313     case RACE_GOLEM: {
314         add_flag(flags, TR_SEE_INVIS);
315         add_flag(flags, TR_FREE_ACT);
316         add_flag(flags, TR_RES_POIS);
317         add_flag(flags, TR_SLOW_DIGEST);
318         if (creature_ptr->lev > 34)
319             add_flag(flags, TR_HOLD_EXP);
320
321         break;
322     }
323     case RACE_SKELETON: {
324         add_flag(flags, TR_SEE_INVIS);
325         add_flag(flags, TR_RES_SHARDS);
326         add_flag(flags, TR_HOLD_EXP);
327         add_flag(flags, TR_RES_POIS);
328         if (creature_ptr->lev > 9)
329             add_flag(flags, TR_RES_COLD);
330
331         break;
332     }
333     case RACE_ZOMBIE: {
334         add_flag(flags, TR_SEE_INVIS);
335         add_flag(flags, TR_HOLD_EXP);
336         add_flag(flags, TR_RES_NETHER);
337         add_flag(flags, TR_RES_POIS);
338         add_flag(flags, TR_SLOW_DIGEST);
339         if (creature_ptr->lev > 4)
340             add_flag(flags, TR_RES_COLD);
341
342         break;
343     }
344     case RACE_VAMPIRE: {
345         add_flag(flags, TR_HOLD_EXP);
346         add_flag(flags, TR_RES_DARK);
347         add_flag(flags, TR_RES_NETHER);
348         if (creature_ptr->pclass != CLASS_NINJA)
349             add_flag(flags, TR_LITE_1);
350
351         add_flag(flags, TR_RES_POIS);
352         add_flag(flags, TR_RES_COLD);
353         break;
354     }
355     case RACE_SPECTRE: {
356         add_flag(flags, TR_LEVITATION);
357         add_flag(flags, TR_FREE_ACT);
358         add_flag(flags, TR_RES_COLD);
359         add_flag(flags, TR_SEE_INVIS);
360         add_flag(flags, TR_HOLD_EXP);
361         add_flag(flags, TR_RES_NETHER);
362         add_flag(flags, TR_RES_POIS);
363         add_flag(flags, TR_SLOW_DIGEST);
364         if (creature_ptr->lev > 34)
365             add_flag(flags, TR_TELEPATHY);
366
367         break;
368     }
369     case RACE_SPRITE: {
370         add_flag(flags, TR_RES_LITE);
371         add_flag(flags, TR_LEVITATION);
372         if (creature_ptr->lev > 9)
373             add_flag(flags, TR_SPEED);
374
375         break;
376     }
377     case RACE_BEASTMAN: {
378         add_flag(flags, TR_RES_SOUND);
379         add_flag(flags, TR_RES_CONF);
380         break;
381     }
382     case RACE_ARCHON: {
383         add_flag(flags, TR_LEVITATION);
384         add_flag(flags, TR_SEE_INVIS);
385         break;
386     }
387     case RACE_BALROG: {
388         add_flag(flags, TR_RES_FIRE);
389         add_flag(flags, TR_RES_NETHER);
390         add_flag(flags, TR_HOLD_EXP);
391         if (creature_ptr->lev > 9)
392             add_flag(flags, TR_SEE_INVIS);
393
394         break;
395     }
396     case RACE_DUNADAN: {
397         add_flag(flags, TR_SUST_CON);
398         break;
399     }
400     case RACE_S_FAIRY: {
401         add_flag(flags, TR_LEVITATION);
402         break;
403     }
404     case RACE_KUTAR: {
405         add_flag(flags, TR_RES_CONF);
406         break;
407     }
408     case RACE_ANDROID: {
409         add_flag(flags, TR_FREE_ACT);
410         add_flag(flags, TR_RES_POIS);
411         add_flag(flags, TR_SLOW_DIGEST);
412         add_flag(flags, TR_HOLD_EXP);
413         break;
414     }
415     default:
416         break;
417     }
418 }
419
420 /*!
421  * @brief 突然変異による耐性フラグを返す
422  * @param creature_ptr プレーヤーへの参照ポインタ
423  * @param flags 耐性フラグの配列
424  * @return なし
425  * @todo 最終的にplayer-status系列と統合する
426  */
427 static void add_mutation_flags(player_type *creature_ptr, BIT_FLAGS *flags)
428 {
429     if (creature_ptr->muta3 == 0)
430         return;
431
432     if (creature_ptr->muta3 & MUT3_FLESH_ROT)
433         remove_flag(flags, TR_REGEN);
434     if ((creature_ptr->muta3 & MUT3_XTRA_FAT) || (creature_ptr->muta3 & MUT3_XTRA_LEGS) || (creature_ptr->muta3 & MUT3_SHORT_LEG))
435         add_flag(flags, TR_SPEED);
436     if (creature_ptr->muta3 & MUT3_ELEC_TOUC)
437         add_flag(flags, TR_SH_ELEC);
438     if (creature_ptr->muta3 & MUT3_FIRE_BODY) {
439         add_flag(flags, TR_SH_FIRE);
440         add_flag(flags, TR_LITE_1);
441     }
442
443     if (creature_ptr->muta3 & MUT3_WINGS)
444         add_flag(flags, TR_LEVITATION);
445     if (creature_ptr->muta3 & MUT3_FEARLESS)
446         add_flag(flags, TR_RES_FEAR);
447     if (creature_ptr->muta3 & MUT3_REGEN)
448         add_flag(flags, TR_REGEN);
449     if (creature_ptr->muta3 & MUT3_ESP)
450         add_flag(flags, TR_TELEPATHY);
451     if (creature_ptr->muta3 & MUT3_MOTION)
452         add_flag(flags, TR_FREE_ACT);
453 }
454
455 /*!
456  * @brief 性格による耐性フラグを返す
457  * @param creature_ptr プレーヤーへの参照ポインタ
458  * @param flags 耐性フラグの配列
459  * @return なし
460  * @todo 最終的にplayer-status系列と統合する
461  */
462 static void add_personality_flags(player_type *creature_ptr, BIT_FLAGS *flags)
463 {
464     if (creature_ptr->pseikaku == PERSONALITY_SEXY)
465         add_flag(flags, TR_AGGRAVATE);
466     if (creature_ptr->pseikaku == PERSONALITY_CHARGEMAN)
467         add_flag(flags, TR_RES_CONF);
468
469     if (creature_ptr->pseikaku != PERSONALITY_MUNCHKIN)
470         return;
471
472     add_flag(flags, TR_RES_BLIND);
473     add_flag(flags, TR_RES_CONF);
474     add_flag(flags, TR_HOLD_EXP);
475     if (creature_ptr->pclass != CLASS_NINJA)
476         add_flag(flags, TR_LITE_1);
477     if (creature_ptr->lev > 9)
478         add_flag(flags, TR_SPEED);
479 }
480
481 /*!
482  * @brief 剣術家の型による耐性フラグを返す
483  * @param creature_ptr プレーヤーへの参照ポインタ
484  * @param flags 耐性フラグの配列
485  * @todo 最終的にplayer-status系列と統合する
486  * @return なし
487  */
488 static void add_kata_flags(player_type *creature_ptr, BIT_FLAGS *flags)
489 {
490     if (creature_ptr->special_defense & KATA_FUUJIN)
491         add_flag(flags, TR_REFLECT);
492     if (creature_ptr->special_defense & KAMAE_GENBU)
493         add_flag(flags, TR_REFLECT);
494     if (creature_ptr->special_defense & KAMAE_SUZAKU)
495         add_flag(flags, TR_LEVITATION);
496     if (creature_ptr->special_defense & KAMAE_SEIRYU) {
497         add_flag(flags, TR_RES_FIRE);
498         add_flag(flags, TR_RES_COLD);
499         add_flag(flags, TR_RES_ACID);
500         add_flag(flags, TR_RES_ELEC);
501         add_flag(flags, TR_RES_POIS);
502         add_flag(flags, TR_LEVITATION);
503         add_flag(flags, TR_SH_FIRE);
504         add_flag(flags, TR_SH_ELEC);
505         add_flag(flags, TR_SH_COLD);
506     }
507
508     if ((creature_ptr->special_defense & KATA_MUSOU) == 0)
509         return;
510
511     add_flag(flags, TR_RES_FEAR);
512     add_flag(flags, TR_RES_LITE);
513     add_flag(flags, TR_RES_DARK);
514     add_flag(flags, TR_RES_BLIND);
515     add_flag(flags, TR_RES_CONF);
516     add_flag(flags, TR_RES_SOUND);
517     add_flag(flags, TR_RES_SHARDS);
518     add_flag(flags, TR_RES_NETHER);
519     add_flag(flags, TR_RES_NEXUS);
520     add_flag(flags, TR_RES_CHAOS);
521     add_flag(flags, TR_RES_DISEN);
522     add_flag(flags, TR_REFLECT);
523     add_flag(flags, TR_HOLD_EXP);
524     add_flag(flags, TR_FREE_ACT);
525     add_flag(flags, TR_SH_FIRE);
526     add_flag(flags, TR_SH_ELEC);
527     add_flag(flags, TR_SH_COLD);
528     add_flag(flags, TR_LEVITATION);
529     add_flag(flags, TR_LITE_1);
530     add_flag(flags, TR_SEE_INVIS);
531     add_flag(flags, TR_TELEPATHY);
532     add_flag(flags, TR_SLOW_DIGEST);
533     add_flag(flags, TR_REGEN);
534     add_flag(flags, TR_SUST_STR);
535     add_flag(flags, TR_SUST_INT);
536     add_flag(flags, TR_SUST_WIS);
537     add_flag(flags, TR_SUST_DEX);
538     add_flag(flags, TR_SUST_CON);
539     add_flag(flags, TR_SUST_CHR);
540 }
541
542 /*!
543  * @brief プレイヤーの職業、種族に応じた耐性フラグを返す
544  * Prints ratings on certain abilities
545  * @param creature_ptr 参照元クリーチャーポインタ
546  * @param flags フラグを保管する配列
547  * @return なし
548  * @details
549  * Obtain the "flags" for the player as if he was an item
550  * @todo 最終的にplayer-status系列と統合する
551  */
552 void player_flags(player_type *creature_ptr, BIT_FLAGS *flags)
553 {
554     for (int i = 0; i < TR_FLAG_SIZE; i++)
555         flags[i] = 0L;
556
557     add_class_flags(creature_ptr, flags);
558     void (*race_flags_func)(player_type *, BIT_FLAGS *) = creature_ptr->mimic_form ? add_mimic_form_flags : add_race_flags;
559     (*race_flags_func)(creature_ptr, flags);
560
561     add_mutation_flags(creature_ptr, flags);
562     add_personality_flags(creature_ptr, flags);
563     add_kata_flags(creature_ptr, flags);
564 }