OSDN Git Service

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