OSDN Git Service

Merge pull request #1192 from hengband/feature/3.0.0Alpha26
[hengbandforosx/hengbandosx.git] / src / player / permanent-resistances.cpp
1 #include "permanent-resistances.h"
2 #include "inventory/inventory-slot-types.h"
3 #include "mind/mind-elementalist.h"
4 #include "mutation/mutation-flag-types.h"
5 #include "object-enchant/tr-types.h"
6 #include "player-info/equipment-info.h"
7 #include "player/player-personality-types.h"
8 #include "player/player-race-types.h"
9 #include "player/player-race.h"
10 #include "player/player-status-flags.h"
11 #include "player/special-defense-types.h"
12 #include "system/object-type-definition.h"
13 #include "system/player-type-definition.h"
14 #include "util/bit-flags-calculator.h"
15
16 /*!
17  * @brief プレーヤーの職業による耐性フラグを返す
18  * @param creature_ptr プレーヤーへの参照ポインタ
19  * @param flags 耐性フラグの配列
20  * @todo 最終的にplayer-status系列と統合する
21  */
22 static void add_class_flags(player_type *creature_ptr, BIT_FLAGS *flags)
23 {
24     switch (creature_ptr->pclass) {
25     case CLASS_WARRIOR: {
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         if (creature_ptr->lev > 29)
35             add_flag(flags, TR_RES_FEAR);
36
37         break;
38     }
39     case CLASS_PALADIN: {
40         if (creature_ptr->lev > 39)
41             add_flag(flags, TR_RES_FEAR);
42
43         break;
44     }
45     case CLASS_CHAOS_WARRIOR: {
46         if (creature_ptr->lev > 29)
47             add_flag(flags, TR_RES_CHAOS);
48         if (creature_ptr->lev > 39)
49             add_flag(flags, TR_RES_FEAR);
50
51         break;
52     }
53     case CLASS_MONK:
54     case CLASS_FORCETRAINER: {
55         if ((creature_ptr->lev > 9) && !heavy_armor(creature_ptr))
56             add_flag(flags, TR_SPEED);
57         if ((creature_ptr->lev > 24) && !heavy_armor(creature_ptr))
58             add_flag(flags, TR_FREE_ACT);
59
60         break;
61     }
62     case CLASS_NINJA: {
63         if (heavy_armor(creature_ptr)) {
64             add_flag(flags, TR_SPEED);
65         } else {
66             if ((!creature_ptr->inventory_list[INVEN_MAIN_HAND].k_idx || can_attack_with_main_hand(creature_ptr))
67                 && (!creature_ptr->inventory_list[INVEN_SUB_HAND].k_idx || can_attack_with_sub_hand(creature_ptr)))
68                 add_flag(flags, TR_SPEED);
69             if (creature_ptr->lev > 24 && !creature_ptr->icky_wield[0] && !creature_ptr->icky_wield[1])
70                 add_flag(flags, TR_FREE_ACT);
71         }
72
73         add_flag(flags, TR_SLOW_DIGEST);
74         add_flag(flags, TR_RES_FEAR);
75         if (creature_ptr->lev > 19)
76             add_flag(flags, TR_RES_POIS);
77         if (creature_ptr->lev > 24)
78             add_flag(flags, TR_SUST_DEX);
79         if (creature_ptr->lev > 29)
80             add_flag(flags, TR_SEE_INVIS);
81
82         break;
83     }
84     case CLASS_MINDCRAFTER: {
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         add_flag(flags, TR_RES_SOUND);
98         break;
99     }
100     case CLASS_BERSERKER: {
101         add_flag(flags, TR_SUST_STR);
102         add_flag(flags, TR_SUST_DEX);
103         add_flag(flags, TR_SUST_CON);
104         add_flag(flags, TR_REGEN);
105         add_flag(flags, TR_FREE_ACT);
106         add_flag(flags, TR_SPEED);
107         if (creature_ptr->lev > 39)
108             add_flag(flags, TR_REFLECT);
109
110         break;
111     }
112     case CLASS_MIRROR_MASTER: {
113         if (creature_ptr->lev > 39)
114             add_flag(flags, TR_REFLECT);
115
116         break;
117     }
118     case CLASS_ELEMENTALIST:
119         if (has_element_resist(creature_ptr, ElementRealm::FIRE, 1))
120             add_flag(flags, TR_RES_FIRE);
121         if (has_element_resist(creature_ptr, ElementRealm::ICE, 1))
122             add_flag(flags, TR_RES_COLD);
123         if (has_element_resist(creature_ptr, ElementRealm::SKY, 1))
124             add_flag(flags, TR_RES_ELEC);
125         if (has_element_resist(creature_ptr, ElementRealm::SEA, 1))
126             add_flag(flags, TR_RES_ACID);
127         if (has_element_resist(creature_ptr, ElementRealm::DARKNESS, 1))
128             add_flag(flags, TR_RES_DARK);
129         if (has_element_resist(creature_ptr, ElementRealm::DARKNESS, 30))
130             add_flag(flags, TR_RES_NETHER);
131         if (has_element_resist(creature_ptr, ElementRealm::CHAOS, 1))
132             add_flag(flags, TR_RES_CONF);
133         if (has_element_resist(creature_ptr, ElementRealm::CHAOS, 30))
134             add_flag(flags, TR_RES_CHAOS);
135         if (has_element_resist(creature_ptr, ElementRealm::EARTH, 1))
136             add_flag(flags, TR_RES_SHARDS);
137         if (has_element_resist(creature_ptr, ElementRealm::EARTH, 30))
138             add_flag(flags, TR_REFLECT);
139         if (has_element_resist(creature_ptr, ElementRealm::DEATH, 1))
140             add_flag(flags, TR_RES_POIS);
141         if (has_element_resist(creature_ptr, ElementRealm::DEATH, 30))
142             add_flag(flags, TR_RES_DISEN);
143         break;
144     default:
145         break;
146     }
147 }
148
149 /*!
150  * @brief 突然変異による耐性フラグを返す
151  * @param creature_ptr プレーヤーへの参照ポインタ
152  * @param flags 耐性フラグの配列
153  * @todo 最終的にplayer-status系列と統合する
154  */
155 static void add_mutation_flags(player_type *creature_ptr, BIT_FLAGS *flags)
156 {
157     if (creature_ptr->muta.none())
158         return;
159
160     if (creature_ptr->muta.has(MUTA::FLESH_ROT))
161         remove_flag(flags, TR_REGEN);
162     if (creature_ptr->muta.has_any_of({ MUTA::XTRA_FAT, MUTA::XTRA_LEGS, MUTA::SHORT_LEG }))
163         add_flag(flags, TR_SPEED);
164     if (creature_ptr->muta.has(MUTA::ELEC_TOUC))
165         add_flag(flags, TR_SH_ELEC);
166     if (creature_ptr->muta.has(MUTA::FIRE_BODY)) {
167         add_flag(flags, TR_SH_FIRE);
168         add_flag(flags, TR_LITE_1);
169     }
170
171     if (creature_ptr->muta.has(MUTA::WINGS))
172         add_flag(flags, TR_LEVITATION);
173     if (creature_ptr->muta.has(MUTA::FEARLESS))
174         add_flag(flags, TR_RES_FEAR);
175     if (creature_ptr->muta.has(MUTA::REGEN))
176         add_flag(flags, TR_REGEN);
177     if (creature_ptr->muta.has(MUTA::ESP))
178         add_flag(flags, TR_TELEPATHY);
179     if (creature_ptr->muta.has(MUTA::MOTION))
180         add_flag(flags, TR_FREE_ACT);
181 }
182
183 /*!
184  * @brief 性格による耐性フラグを返す
185  * @param creature_ptr プレーヤーへの参照ポインタ
186  * @param flags 耐性フラグの配列
187  * @todo 最終的にplayer-status系列と統合する
188  */
189 static void add_personality_flags(player_type *creature_ptr, BIT_FLAGS *flags)
190 {
191     if (creature_ptr->pseikaku == PERSONALITY_SEXY)
192         add_flag(flags, TR_AGGRAVATE);
193     if (creature_ptr->pseikaku == PERSONALITY_CHARGEMAN)
194         add_flag(flags, TR_RES_CONF);
195
196     if (creature_ptr->pseikaku != PERSONALITY_MUNCHKIN)
197         return;
198
199     add_flag(flags, TR_RES_BLIND);
200     add_flag(flags, TR_RES_CONF);
201     add_flag(flags, TR_HOLD_EXP);
202     if (creature_ptr->pclass != CLASS_NINJA)
203         add_flag(flags, TR_LITE_1);
204     if (creature_ptr->lev > 9)
205         add_flag(flags, TR_SPEED);
206 }
207
208 /*!
209  * @brief 剣術家の型による耐性フラグを返す
210  * @param creature_ptr プレーヤーへの参照ポインタ
211  * @param flags 耐性フラグの配列
212  * @todo 最終的にplayer-status系列と統合する
213  */
214 static void add_kata_flags(player_type *creature_ptr, BIT_FLAGS *flags)
215 {
216     if (creature_ptr->special_defense & KATA_FUUJIN)
217         add_flag(flags, TR_REFLECT);
218     if (creature_ptr->special_defense & KAMAE_GENBU)
219         add_flag(flags, TR_REFLECT);
220     if (creature_ptr->special_defense & KAMAE_SUZAKU)
221         add_flag(flags, TR_LEVITATION);
222     if (creature_ptr->special_defense & KAMAE_SEIRYU) {
223         add_flag(flags, TR_RES_FIRE);
224         add_flag(flags, TR_RES_COLD);
225         add_flag(flags, TR_RES_ACID);
226         add_flag(flags, TR_RES_ELEC);
227         add_flag(flags, TR_RES_POIS);
228         add_flag(flags, TR_LEVITATION);
229         add_flag(flags, TR_SH_FIRE);
230         add_flag(flags, TR_SH_ELEC);
231         add_flag(flags, TR_SH_COLD);
232     }
233
234     if ((creature_ptr->special_defense & KATA_MUSOU) == 0)
235         return;
236
237     add_flag(flags, TR_RES_FEAR);
238     add_flag(flags, TR_RES_LITE);
239     add_flag(flags, TR_RES_DARK);
240     add_flag(flags, TR_RES_BLIND);
241     add_flag(flags, TR_RES_CONF);
242     add_flag(flags, TR_RES_SOUND);
243     add_flag(flags, TR_RES_SHARDS);
244     add_flag(flags, TR_RES_NETHER);
245     add_flag(flags, TR_RES_NEXUS);
246     add_flag(flags, TR_RES_CHAOS);
247     add_flag(flags, TR_RES_DISEN);
248     add_flag(flags, TR_REFLECT);
249     add_flag(flags, TR_HOLD_EXP);
250     add_flag(flags, TR_FREE_ACT);
251     add_flag(flags, TR_SH_FIRE);
252     add_flag(flags, TR_SH_ELEC);
253     add_flag(flags, TR_SH_COLD);
254     add_flag(flags, TR_LEVITATION);
255     add_flag(flags, TR_LITE_1);
256     add_flag(flags, TR_SEE_INVIS);
257     add_flag(flags, TR_TELEPATHY);
258     add_flag(flags, TR_SLOW_DIGEST);
259     add_flag(flags, TR_REGEN);
260     add_flag(flags, TR_SUST_STR);
261     add_flag(flags, TR_SUST_INT);
262     add_flag(flags, TR_SUST_WIS);
263     add_flag(flags, TR_SUST_DEX);
264     add_flag(flags, TR_SUST_CON);
265     add_flag(flags, TR_SUST_CHR);
266 }
267
268 /*!
269  * @brief プレイヤーの職業、種族に応じた耐性フラグを返す
270  * Prints ratings on certain abilities
271  * @param creature_ptr 参照元クリーチャーポインタ
272  * @param flags フラグを保管する配列
273  * @details
274  * Obtain the "flags" for the player as if he was an item
275  * @todo 最終的にplayer-status系列と統合する
276  */
277 void player_flags(player_type *creature_ptr, BIT_FLAGS *flags)
278 {
279     for (int i = 0; i < TR_FLAG_SIZE; i++)
280         flags[i] = 0L;
281
282     add_class_flags(creature_ptr, flags);
283     add_player_race_flags(creature_ptr, flags);
284
285     add_mutation_flags(creature_ptr, flags);
286     add_personality_flags(creature_ptr, flags);
287     add_kata_flags(creature_ptr, flags);
288 }
289
290 void riding_flags(player_type *creature_ptr, BIT_FLAGS *flags, BIT_FLAGS *negative_flags)
291 {
292     for (int i = 0; i < TR_FLAG_SIZE; i++) {
293         flags[i] = 0L;
294         negative_flags[i] = 0L;
295     }
296
297     if (!creature_ptr->riding)
298         return;
299
300     if (any_bits(has_levitation(creature_ptr), FLAG_CAUSE_RIDING)) {
301         add_flag(flags, TR_LEVITATION);
302     } else {
303         add_flag(negative_flags, TR_LEVITATION);
304     }
305 }