OSDN Git Service

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