OSDN Git Service

Merge pull request #1192 from hengband/feature/3.0.0Alpha26
[hengbandforosx/hengbandosx.git] / src / status / body-improvement.cpp
1 #include "status/body-improvement.h"
2 #include "core/disturbance.h"
3 #include "core/player-redraw-types.h"
4 #include "core/player-update-types.h"
5 #include "core/speed-table.h"
6 #include "core/stuff-handler.h"
7 #include "core/window-redrawer.h"
8 #include "game-option/disturbance-options.h"
9 #include "player-info/avatar.h"
10 #include "player/player-status.h"
11 #include "realm/realm-song-numbers.h"
12 #include "spell-realm/spells-song.h"
13 #include "system/player-type-definition.h"
14 #include "view/display-messages.h"
15
16 /*!
17  * @brief 対邪悪結界の継続時間をセットする / Set "protevil", notice observable changes
18  * @param v 継続時間
19  * @param do_dec 現在の継続時間より長い値のみ上書きする
20  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
21  */
22 bool set_protevil(player_type *creature_ptr, TIME_EFFECT v, bool do_dec)
23 {
24     bool notice = false;
25     v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
26
27     if (creature_ptr->is_dead)
28         return false;
29
30     if (v) {
31         if (creature_ptr->protevil && !do_dec) {
32             if (creature_ptr->protevil > v)
33                 return false;
34         } else if (!creature_ptr->protevil) {
35             msg_print(_("邪悪なる存在から守られているような感じがする!", "You feel safe from evil!"));
36             notice = true;
37         }
38     } else {
39         if (creature_ptr->protevil) {
40             msg_print(_("邪悪なる存在から守られている感じがなくなった。", "You no longer feel safe from evil."));
41             notice = true;
42         }
43     }
44
45     creature_ptr->protevil = v;
46     creature_ptr->redraw |= (PR_STATUS);
47
48     if (!notice)
49         return false;
50
51     if (disturb_state)
52         disturb(creature_ptr, false, false);
53
54     handle_stuff(creature_ptr);
55     return true;
56 }
57
58 /*!
59  * @brief 無傷球の継続時間をセットする / Set "invuln", notice observable changes
60  * @param v 継続時間
61  * @param do_dec 現在の継続時間より長い値のみ上書きする
62  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
63  */
64 bool set_invuln(player_type *creature_ptr, TIME_EFFECT v, bool do_dec)
65 {
66     bool notice = false;
67     v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
68
69     if (creature_ptr->is_dead)
70         return false;
71
72     if (v) {
73         if (creature_ptr->invuln && !do_dec) {
74             if (creature_ptr->invuln > v)
75                 return false;
76         } else if (!is_invuln(creature_ptr)) {
77             msg_print(_("無敵だ!", "Invulnerability!"));
78             notice = true;
79
80             chg_virtue(creature_ptr, V_UNLIFE, -2);
81             chg_virtue(creature_ptr, V_HONOUR, -2);
82             chg_virtue(creature_ptr, V_SACRIFICE, -3);
83             chg_virtue(creature_ptr, V_VALOUR, -5);
84
85             creature_ptr->redraw |= (PR_MAP);
86             creature_ptr->update |= (PU_MONSTERS);
87
88             creature_ptr->window_flags |= (PW_OVERHEAD | PW_DUNGEON);
89         }
90     } else {
91         if (creature_ptr->invuln && !music_singing(creature_ptr, MUSIC_INVULN)) {
92             msg_print(_("無敵ではなくなった。", "The invulnerability wears off."));
93             notice = true;
94
95             creature_ptr->redraw |= (PR_MAP);
96             creature_ptr->update |= (PU_MONSTERS);
97
98             creature_ptr->window_flags |= (PW_OVERHEAD | PW_DUNGEON);
99
100             creature_ptr->energy_need += ENERGY_NEED();
101         }
102     }
103
104     creature_ptr->invuln = v;
105     creature_ptr->redraw |= (PR_STATUS);
106
107     if (!notice)
108         return false;
109
110     if (disturb_state)
111         disturb(creature_ptr, false, false);
112
113     creature_ptr->update |= (PU_BONUS);
114     handle_stuff(creature_ptr);
115     return true;
116 }
117
118 /*!
119  * @brief 時限急回復の継続時間をセットする / Set "tim_regen", notice observable changes
120  * @param v 継続時間
121  * @param do_dec 現在の継続時間より長い値のみ上書きする
122  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
123  */
124 bool set_tim_regen(player_type *creature_ptr, TIME_EFFECT v, bool do_dec)
125 {
126     bool notice = false;
127     v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
128
129     if (creature_ptr->is_dead)
130         return false;
131
132     if (v) {
133         if (creature_ptr->tim_regen && !do_dec) {
134             if (creature_ptr->tim_regen > v)
135                 return false;
136         } else if (!creature_ptr->tim_regen) {
137             msg_print(_("回復力が上がった!", "You feel yourself regenerating quickly!"));
138             notice = true;
139         }
140     } else {
141         if (creature_ptr->tim_regen) {
142             msg_print(_("素早く回復する感じがなくなった。", "You feel you are no longer regenerating quickly."));
143             notice = true;
144         }
145     }
146
147     creature_ptr->tim_regen = v;
148     creature_ptr->redraw |= (PR_STATUS);
149
150     if (!notice)
151         return false;
152
153     if (disturb_state)
154         disturb(creature_ptr, false, false);
155
156     creature_ptr->update |= (PU_BONUS);
157     handle_stuff(creature_ptr);
158     return true;
159 }
160
161 /*!
162  * @brief 一時的反射の継続時間をセットする / Set "tim_reflect", notice observable changes
163  * @param v 継続時間
164  * @param do_dec 現在の継続時間より長い値のみ上書きする
165  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
166  */
167 bool set_tim_reflect(player_type *creature_ptr, TIME_EFFECT v, bool do_dec)
168 {
169     bool notice = false;
170     v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
171
172     if (creature_ptr->is_dead)
173         return false;
174
175     if (v) {
176         if (creature_ptr->tim_reflect && !do_dec) {
177             if (creature_ptr->tim_reflect > v)
178                 return false;
179         } else if (!creature_ptr->tim_reflect) {
180             msg_print(_("体の表面が滑かになった気がする。", "Your body becames smooth."));
181             notice = true;
182         }
183     } else {
184         if (creature_ptr->tim_reflect) {
185             msg_print(_("体の表面が滑かでなくなった。", "Your body is no longer smooth."));
186             notice = true;
187         }
188     }
189
190     creature_ptr->tim_reflect = v;
191     creature_ptr->redraw |= (PR_STATUS);
192
193     if (!notice)
194         return false;
195
196     if (disturb_state)
197         disturb(creature_ptr, false, false);
198
199     creature_ptr->update |= (PU_BONUS);
200     handle_stuff(creature_ptr);
201     return true;
202 }
203
204 /*!
205  * @brief 一時的壁抜けの継続時間をセットする / Set "tim_pass_wall", notice observable changes
206  * @param v 継続時間
207  * @param do_dec 現在の継続時間より長い値のみ上書きする
208  * @return ステータスに影響を及ぼす変化があった場合TRUEを返す。
209  */
210 bool set_pass_wall(player_type *creature_ptr, TIME_EFFECT v, bool do_dec)
211 {
212     bool notice = false;
213     v = (v > 10000) ? 10000 : (v < 0) ? 0 : v;
214
215     if (creature_ptr->is_dead)
216         return false;
217
218     if (v) {
219         if (creature_ptr->tim_pass_wall && !do_dec) {
220             if (creature_ptr->tim_pass_wall > v)
221                 return false;
222         } else if (!creature_ptr->tim_pass_wall) {
223             msg_print(_("体が半物質の状態になった。", "You became ethereal."));
224             notice = true;
225         }
226     } else {
227         if (creature_ptr->tim_pass_wall) {
228             msg_print(_("体が物質化した。", "You are no longer ethereal."));
229             notice = true;
230         }
231     }
232
233     creature_ptr->tim_pass_wall = v;
234     creature_ptr->redraw |= (PR_STATUS);
235
236     if (!notice)
237         return false;
238
239     if (disturb_state)
240         disturb(creature_ptr, false, false);
241
242     creature_ptr->update |= (PU_BONUS);
243     handle_stuff(creature_ptr);
244     return true;
245 }