OSDN Git Service

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