OSDN Git Service

9c95155dad4128cc11e54541ae9460bc9a86d809
[hengbandforosx/hengbandosx.git] / src / status / element-resistance.cpp
1 #include "status/element-resistance.h"
2 #include "core/disturbance.h"
3 #include "core/player-redraw-types.h"
4 #include "core/stuff-handler.h"
5 #include "game-option/disturbance-options.h"
6 #include "player-base/player-class.h"
7 #include "player-base/player-race.h"
8 #include "player-info/race-info.h"
9 #include "player-info/samurai-data-type.h"
10 #include "player/special-defense-types.h"
11 #include "realm/realm-song-numbers.h"
12 #include "spell-realm/spells-song.h"
13 #include "system/player-type-definition.h"
14 #include "system/redrawing-flags-updater.h"
15 #include "view/display-messages.h"
16
17 /*!
18  * @brief 一時的酸耐性の継続時間をセットする / Set "oppose_acid", notice observable changes
19  * @param v 継続時間
20  * @param do_dec 現在の継続時間より長い値のみ上書きする
21  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
22  */
23 bool set_oppose_acid(PlayerType *player_ptr, TIME_EFFECT v, bool do_dec)
24 {
25     bool notice = false;
26     v = (v > 10000) ? 10000 : (v < 0) ? 0
27                                       : v;
28     if (player_ptr->is_dead) {
29         return false;
30     }
31
32     if (v) {
33         if (player_ptr->oppose_acid && !do_dec) {
34             if (player_ptr->oppose_acid > v) {
35                 return false;
36             }
37         } else if (!is_oppose_acid(player_ptr)) {
38             msg_print(_("酸への耐性がついた気がする!", "You feel resistant to acid!"));
39             notice = true;
40         }
41     } else {
42         if (player_ptr->oppose_acid && !music_singing(player_ptr, MUSIC_RESIST) &&
43             !PlayerClass(player_ptr).samurai_stance_is(SamuraiStanceType::MUSOU)) {
44             msg_print(_("酸への耐性が薄れた気がする。", "You feel less resistant to acid."));
45             notice = true;
46         }
47     }
48
49     player_ptr->oppose_acid = v;
50     if (!notice) {
51         return false;
52     }
53
54     RedrawingFlagsUpdater::get_instance().set_flag(MainWindowRedrawingFlag::TIMED_EFFECT);
55     if (disturb_state) {
56         disturb(player_ptr, false, false);
57     }
58
59     handle_stuff(player_ptr);
60     return true;
61 }
62
63 /*!
64  * @brief 一時的電撃耐性の継続時間をセットする / Set "oppose_elec", notice observable changes
65  * @param v 継続時間
66  * @param do_dec 現在の継続時間より長い値のみ上書きする
67  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
68  */
69 bool set_oppose_elec(PlayerType *player_ptr, TIME_EFFECT v, bool do_dec)
70 {
71     bool notice = false;
72     v = (v > 10000) ? 10000 : (v < 0) ? 0
73                                       : v;
74
75     if (player_ptr->is_dead) {
76         return false;
77     }
78
79     if (v) {
80         if (player_ptr->oppose_elec && !do_dec) {
81             if (player_ptr->oppose_elec > v) {
82                 return false;
83             }
84         } else if (!is_oppose_elec(player_ptr)) {
85             msg_print(_("電撃への耐性がついた気がする!", "You feel resistant to electricity!"));
86             notice = true;
87         }
88     } else {
89         if (player_ptr->oppose_elec && !music_singing(player_ptr, MUSIC_RESIST) &&
90             !PlayerClass(player_ptr).samurai_stance_is(SamuraiStanceType::MUSOU)) {
91             msg_print(_("電撃への耐性が薄れた気がする。", "You feel less resistant to electricity."));
92             notice = true;
93         }
94     }
95
96     player_ptr->oppose_elec = v;
97     if (!notice) {
98         return false;
99     }
100
101     RedrawingFlagsUpdater::get_instance().set_flag(MainWindowRedrawingFlag::TIMED_EFFECT);
102     if (disturb_state) {
103         disturb(player_ptr, false, false);
104     }
105
106     handle_stuff(player_ptr);
107     return true;
108 }
109
110 /*!
111  * @brief 一時的火炎耐性の継続時間をセットする / Set "oppose_fire", notice observable changes
112  * @param v 継続時間
113  * @param do_dec 現在の継続時間より長い値のみ上書きする
114  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
115  */
116 bool set_oppose_fire(PlayerType *player_ptr, TIME_EFFECT v, bool do_dec)
117 {
118     bool notice = false;
119     v = (v > 10000) ? 10000 : (v < 0) ? 0
120                                       : v;
121     if (player_ptr->is_dead) {
122         return false;
123     }
124
125     if ((PlayerRace(player_ptr).equals(PlayerRaceType::BALROG) && (player_ptr->lev > 44)) || (player_ptr->mimic_form == MimicKindType::DEMON)) {
126         v = 1;
127     }
128     if (v) {
129         if (player_ptr->oppose_fire && !do_dec) {
130             if (player_ptr->oppose_fire > v) {
131                 return false;
132             }
133         } else if (!is_oppose_fire(player_ptr)) {
134             msg_print(_("火への耐性がついた気がする!", "You feel resistant to fire!"));
135             notice = true;
136         }
137     } else {
138         if (player_ptr->oppose_fire && !music_singing(player_ptr, MUSIC_RESIST) &&
139             !PlayerClass(player_ptr).samurai_stance_is(SamuraiStanceType::MUSOU)) {
140             msg_print(_("火への耐性が薄れた気がする。", "You feel less resistant to fire."));
141             notice = true;
142         }
143     }
144
145     player_ptr->oppose_fire = v;
146     if (!notice) {
147         return false;
148     }
149
150     RedrawingFlagsUpdater::get_instance().set_flag(MainWindowRedrawingFlag::TIMED_EFFECT);
151     if (disturb_state) {
152         disturb(player_ptr, false, false);
153     }
154
155     handle_stuff(player_ptr);
156     return true;
157 }
158
159 /*!
160  * @brief 一時的冷気耐性の継続時間をセットする / Set "oppose_cold", notice observable changes
161  * @param v 継続時間
162  * @param do_dec 現在の継続時間より長い値のみ上書きする
163  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
164  */
165 bool set_oppose_cold(PlayerType *player_ptr, TIME_EFFECT v, bool do_dec)
166 {
167     bool notice = false;
168     v = (v > 10000) ? 10000 : (v < 0) ? 0
169                                       : v;
170     if (player_ptr->is_dead) {
171         return false;
172     }
173
174     if (v) {
175         if (player_ptr->oppose_cold && !do_dec) {
176             if (player_ptr->oppose_cold > v) {
177                 return false;
178             }
179         } else if (!is_oppose_cold(player_ptr)) {
180             msg_print(_("冷気への耐性がついた気がする!", "You feel resistant to cold!"));
181             notice = true;
182         }
183     } else {
184         if (player_ptr->oppose_cold && !music_singing(player_ptr, MUSIC_RESIST) &&
185             !PlayerClass(player_ptr).samurai_stance_is(SamuraiStanceType::MUSOU)) {
186             msg_print(_("冷気への耐性が薄れた気がする。", "You feel less resistant to cold."));
187             notice = true;
188         }
189     }
190
191     player_ptr->oppose_cold = v;
192     if (!notice) {
193         return false;
194     }
195
196     RedrawingFlagsUpdater::get_instance().set_flag(MainWindowRedrawingFlag::TIMED_EFFECT);
197     if (disturb_state) {
198         disturb(player_ptr, false, false);
199     }
200
201     handle_stuff(player_ptr);
202     return true;
203 }
204
205 /*!
206  * @brief 一時的毒耐性の継続時間をセットする / Set "oppose_pois", notice observable changes
207  * @param v 継続時間
208  * @param do_dec 現在の継続時間より長い値のみ上書きする
209  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
210  */
211 bool set_oppose_pois(PlayerType *player_ptr, TIME_EFFECT v, bool do_dec)
212 {
213     bool notice = false;
214     v = (v > 10000) ? 10000 : (v < 0) ? 0
215                                       : v;
216     PlayerClass pc(player_ptr);
217     if (pc.has_poison_resistance()) {
218         v = 1;
219     }
220     if (player_ptr->is_dead) {
221         return false;
222     }
223
224     if (v) {
225         if (player_ptr->oppose_pois && !do_dec) {
226             if (player_ptr->oppose_pois > v) {
227                 return false;
228             }
229         } else if (!is_oppose_pois(player_ptr)) {
230             msg_print(_("毒への耐性がついた気がする!", "You feel resistant to poison!"));
231             notice = true;
232         }
233     } else {
234         if (player_ptr->oppose_pois && !music_singing(player_ptr, MUSIC_RESIST) &&
235             !pc.samurai_stance_is(SamuraiStanceType::MUSOU)) {
236             msg_print(_("毒への耐性が薄れた気がする。", "You feel less resistant to poison."));
237             notice = true;
238         }
239     }
240
241     player_ptr->oppose_pois = v;
242     if (!notice) {
243         return false;
244     }
245
246     RedrawingFlagsUpdater::get_instance().set_flag(MainWindowRedrawingFlag::TIMED_EFFECT);
247     if (disturb_state) {
248         disturb(player_ptr, false, false);
249     }
250
251     handle_stuff(player_ptr);
252     return true;
253 }
254
255 bool is_oppose_acid(PlayerType *player_ptr)
256 {
257     auto can_oppose_acid = player_ptr->oppose_acid != 0;
258     can_oppose_acid |= music_singing(player_ptr, MUSIC_RESIST);
259     can_oppose_acid |= PlayerClass(player_ptr).samurai_stance_is(SamuraiStanceType::MUSOU);
260     return can_oppose_acid;
261 }
262
263 bool is_oppose_elec(PlayerType *player_ptr)
264 {
265     auto can_oppose_elec = player_ptr->oppose_elec != 0;
266     can_oppose_elec |= music_singing(player_ptr, MUSIC_RESIST);
267     can_oppose_elec |= PlayerClass(player_ptr).samurai_stance_is(SamuraiStanceType::MUSOU);
268     return can_oppose_elec;
269 }
270
271 bool is_oppose_fire(PlayerType *player_ptr)
272 {
273     auto can_oppose_fire = player_ptr->oppose_fire != 0;
274     can_oppose_fire |= music_singing(player_ptr, MUSIC_RESIST);
275     can_oppose_fire |= PlayerClass(player_ptr).samurai_stance_is(SamuraiStanceType::MUSOU);
276     can_oppose_fire |= player_ptr->mimic_form == MimicKindType::DEMON;
277     can_oppose_fire |= (PlayerRace(player_ptr).equals(PlayerRaceType::BALROG) && player_ptr->lev > 44);
278     return can_oppose_fire;
279 }
280
281 bool is_oppose_cold(PlayerType *player_ptr)
282 {
283     auto can_oppose_cold = player_ptr->oppose_cold != 0;
284     can_oppose_cold |= music_singing(player_ptr, MUSIC_RESIST);
285     can_oppose_cold |= PlayerClass(player_ptr).samurai_stance_is(SamuraiStanceType::MUSOU);
286     return can_oppose_cold;
287 }
288
289 bool is_oppose_pois(PlayerType *player_ptr)
290 {
291     PlayerClass pc(player_ptr);
292     auto can_oppose_pois = player_ptr->oppose_pois != 0;
293     can_oppose_pois |= music_singing(player_ptr, MUSIC_RESIST);
294     can_oppose_pois |= pc.samurai_stance_is(SamuraiStanceType::MUSOU);
295     can_oppose_pois |= pc.has_poison_resistance();
296     return can_oppose_pois;
297 }