OSDN Git Service

[Fix] fresh-afterコマンドの修正
[hengbandforosx/hengbandosx.git] / src / effect / effect-monster-oldies.c
1 #include "effect/effect-monster-oldies.h"
2 #include "core/player-redraw-types.h"
3 #include "effect/effect-monster-util.h"
4 #include "monster-race/monster-race.h"
5 #include "monster-race/race-flags1.h"
6 #include "monster-race/race-flags3.h"
7 #include "monster-race/race-flags7.h"
8 #include "monster-race/race-indice-types.h"
9 #include "monster/monster-status-setter.h"
10 #include "monster/monster-status.h"
11 #include "monster-floor/monster-generator.h"
12 #include "monster/monster-info.h"
13 #include "player-info/avatar.h"
14 #include "system/floor-type-definition.h"
15 #include "view/display-messages.h"
16
17 // Powerful monsters can resist.
18 process_result effect_monster_old_poly(effect_monster_type *em_ptr)
19 {
20         if (em_ptr->seen) em_ptr->obvious = TRUE;
21         em_ptr->do_polymorph = TRUE;
22
23         if ((em_ptr->r_ptr->flags1 & RF1_UNIQUE) ||
24                 (em_ptr->r_ptr->flags1 & RF1_QUESTOR) ||
25                 (em_ptr->r_ptr->level > randint1((em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10)) + 10))
26         {
27                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
28                 em_ptr->do_polymorph = FALSE;
29                 em_ptr->obvious = FALSE;
30         }
31
32         em_ptr->dam = 0;
33         return PROCESS_CONTINUE;
34 }
35
36
37 process_result effect_monster_old_clone(player_type *caster_ptr, effect_monster_type *em_ptr)
38 {
39         if (em_ptr->seen) em_ptr->obvious = TRUE;
40
41         if ((caster_ptr->current_floor_ptr->inside_arena) ||
42                 is_pet(em_ptr->m_ptr) ||
43                 (em_ptr->r_ptr->flags1 & (RF1_UNIQUE | RF1_QUESTOR)) ||
44                 (em_ptr->r_ptr->flags7 & (RF7_NAZGUL | RF7_UNIQUE2)))
45         {
46                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
47                 em_ptr->dam = 0;
48                 return PROCESS_CONTINUE;
49         }
50
51         em_ptr->m_ptr->hp = em_ptr->m_ptr->maxhp;
52         if (multiply_monster(caster_ptr, em_ptr->g_ptr->m_idx, TRUE, 0L))
53                 em_ptr->note = _("が分裂した!", " spawns!");
54
55         em_ptr->dam = 0;
56         return PROCESS_CONTINUE;
57 }
58
59
60 process_result effect_monster_star_heal(player_type *caster_ptr, effect_monster_type *em_ptr)
61 {
62         if (em_ptr->seen) em_ptr->obvious = TRUE;
63
64         (void)set_monster_csleep(caster_ptr, em_ptr->g_ptr->m_idx, 0);
65
66         if (em_ptr->m_ptr->maxhp < em_ptr->m_ptr->max_maxhp)
67         {
68                 if (em_ptr->seen_msg)
69                         msg_format(_("%^sの強さが戻った。", "%^s recovers %s vitality."), em_ptr->m_name, em_ptr->m_poss);
70                 em_ptr->m_ptr->maxhp = em_ptr->m_ptr->max_maxhp;
71         }
72
73         if (!em_ptr->dam)
74         {
75                 if (caster_ptr->health_who == em_ptr->g_ptr->m_idx)
76                         caster_ptr->redraw |= (PR_HEALTH);
77                 if (caster_ptr->riding == em_ptr->g_ptr->m_idx)
78                         caster_ptr->redraw |= (PR_UHEALTH);
79
80                 return PROCESS_FALSE;
81         }
82
83         return PROCESS_TRUE;
84 }
85
86
87 // who == 0ならばプレーヤーなので、それの判定.
88 static void effect_monster_old_heal_check_player(player_type *caster_ptr, effect_monster_type *em_ptr)
89 {
90         if (em_ptr->who != 0) return;
91
92         chg_virtue(caster_ptr, V_VITALITY, 1);
93         if (em_ptr->r_ptr->flags1 & RF1_UNIQUE)
94                 chg_virtue(caster_ptr, V_INDIVIDUALISM, 1);
95
96         if (is_friendly(em_ptr->m_ptr))
97                 chg_virtue(caster_ptr, V_HONOUR, 1);
98         else if (!(em_ptr->r_ptr->flags3 & RF3_EVIL))
99         {
100                 if (em_ptr->r_ptr->flags3 & RF3_GOOD)
101                         chg_virtue(caster_ptr, V_COMPASSION, 2);
102                 else
103                         chg_virtue(caster_ptr, V_COMPASSION, 1);
104         }
105
106         if (em_ptr->r_ptr->flags3 & RF3_ANIMAL)
107                 chg_virtue(caster_ptr, V_NATURE, 1);
108 }
109
110
111 static void effect_monster_old_heal_recovery(player_type *caster_ptr, effect_monster_type *em_ptr)
112 {
113         if (monster_stunned_remaining(em_ptr->m_ptr))
114         {
115                 if (em_ptr->seen_msg)
116                         msg_format(_("%^sは朦朧状態から立ち直った。", "%^s is no longer stunned."), em_ptr->m_name);
117
118                 (void)set_monster_stunned(caster_ptr, em_ptr->g_ptr->m_idx, 0);
119         }
120
121         if (monster_confused_remaining(em_ptr->m_ptr))
122         {
123                 if (em_ptr->seen_msg)
124                         msg_format(_("%^sは混乱から立ち直った。", "%^s is no longer confused."), em_ptr->m_name);
125
126                 (void)set_monster_confused(caster_ptr, em_ptr->g_ptr->m_idx, 0);
127         }
128
129         if (monster_fear_remaining(em_ptr->m_ptr))
130         {
131                 if (em_ptr->seen_msg)
132                         msg_format(_("%^sは勇気を取り戻した。", "%^s recovers %s courage."), em_ptr->m_name, em_ptr->m_poss);
133
134                 (void)set_monster_monfear(caster_ptr, em_ptr->g_ptr->m_idx, 0);
135         }
136 }
137
138
139 // todo サーペントのHPがマジックナンバー扱いになっている
140 process_result effect_monster_old_heal(player_type *caster_ptr, effect_monster_type *em_ptr)
141 {
142         if (em_ptr->seen) em_ptr->obvious = TRUE;
143
144         /* Wake up */
145         (void)set_monster_csleep(caster_ptr, em_ptr->g_ptr->m_idx, 0);
146         effect_monster_old_heal_recovery(caster_ptr, em_ptr);
147         if (em_ptr->m_ptr->hp < 30000) em_ptr->m_ptr->hp += em_ptr->dam;
148         if (em_ptr->m_ptr->hp > em_ptr->m_ptr->maxhp) em_ptr->m_ptr->hp = em_ptr->m_ptr->maxhp;
149
150         effect_monster_old_heal_check_player(caster_ptr, em_ptr);
151         if (em_ptr->m_ptr->r_idx == MON_LEPER)
152         {
153                 em_ptr->heal_leper = TRUE;
154                 if (!em_ptr->who) chg_virtue(caster_ptr, V_COMPASSION, 5);
155         }
156
157         if (caster_ptr->health_who == em_ptr->g_ptr->m_idx) caster_ptr->redraw |= (PR_HEALTH);
158         if (caster_ptr->riding == em_ptr->g_ptr->m_idx) caster_ptr->redraw |= (PR_UHEALTH);
159
160         em_ptr->note = _("は体力を回復したようだ。", " looks healthier.");
161         em_ptr->dam = 0;
162         return PROCESS_CONTINUE;
163 }
164
165
166 process_result effect_monster_old_speed(player_type *caster_ptr, effect_monster_type *em_ptr)
167 {
168         if (em_ptr->seen) em_ptr->obvious = TRUE;
169
170         if (set_monster_fast(caster_ptr, em_ptr->g_ptr->m_idx, monster_fast_remaining(em_ptr->m_ptr) + 100))
171         {
172                 em_ptr->note = _("の動きが速くなった。", " starts moving faster.");
173         }
174
175         if (!em_ptr->who)
176         {
177                 if (em_ptr->r_ptr->flags1 & RF1_UNIQUE)
178                         chg_virtue(caster_ptr, V_INDIVIDUALISM, 1);
179                 if (is_friendly(em_ptr->m_ptr))
180                         chg_virtue(caster_ptr, V_HONOUR, 1);
181         }
182
183         em_ptr->dam = 0;
184         return PROCESS_CONTINUE;
185 }
186
187
188 process_result effect_monster_old_slow(player_type *caster_ptr, effect_monster_type *em_ptr)
189 {
190         if (em_ptr->seen) em_ptr->obvious = TRUE;
191
192         /* Powerful monsters can resist */
193         if ((em_ptr->r_ptr->flags1 & RF1_UNIQUE) ||
194                 (em_ptr->r_ptr->level > randint1((em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10)) + 10))
195         {
196                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
197                 em_ptr->obvious = FALSE;
198                 em_ptr->dam = 0;
199                 return PROCESS_CONTINUE;
200         }
201
202         if (set_monster_slow(caster_ptr, em_ptr->g_ptr->m_idx, monster_slow_remaining(em_ptr->m_ptr) + 50))
203                 em_ptr->note = _("の動きが遅くなった。", " starts moving slower.");
204
205         em_ptr->dam = 0;
206         return PROCESS_CONTINUE;
207 }
208
209
210 /*!
211  * todo 「ユニークは (魔法では)常に眠らない」はr_infoの趣旨に反すると思われる
212  * 眠る確率を半分にするとかしておいた方が良さそう
213  */
214 process_result effect_monster_old_sleep(player_type *caster_ptr, effect_monster_type *em_ptr)
215 {
216         if (em_ptr->seen) em_ptr->obvious = TRUE;
217
218         if ((em_ptr->r_ptr->flags1 & RF1_UNIQUE) ||
219                 (em_ptr->r_ptr->flags3 & RF3_NO_SLEEP) ||
220                 (em_ptr->r_ptr->level > randint1((em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10)) + 10))
221         {
222                 if (em_ptr->r_ptr->flags3 & RF3_NO_SLEEP)
223                 {
224                         if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags3 |= (RF3_NO_SLEEP);
225                 }
226
227                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
228                 em_ptr->obvious = FALSE;
229         }
230         else
231         {
232                 em_ptr->note = _("は眠り込んでしまった!", " falls asleep!");
233                 em_ptr->do_sleep = 500;
234         }
235
236         em_ptr->dam = 0;
237         return PROCESS_CONTINUE;
238 }
239
240
241 /*!
242  * todo 「ユニークは (魔法では)常に混乱しない」はr_infoの趣旨に反すると思われる
243  * 眠る確率を半分にするとかしておいた方が良さそう
244  */
245 process_result effect_monster_old_conf(player_type *caster_ptr, effect_monster_type *em_ptr)
246 {
247         if (em_ptr->seen) em_ptr->obvious = TRUE;
248
249         em_ptr->do_conf = damroll(3, (em_ptr->dam / 2)) + 1;
250         if ((em_ptr->r_ptr->flags1 & (RF1_UNIQUE)) ||
251                 (em_ptr->r_ptr->flags3 & (RF3_NO_CONF)) ||
252                 (em_ptr->r_ptr->level > randint1((em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10)) + 10))
253         {
254                 if (em_ptr->r_ptr->flags3 & (RF3_NO_CONF))
255                 {
256                         if (is_original_ap_and_seen(caster_ptr, em_ptr->m_ptr)) em_ptr->r_ptr->r_flags3 |= (RF3_NO_CONF);
257                 }
258
259                 em_ptr->do_conf = 0;
260                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
261                 em_ptr->obvious = FALSE;
262         }
263
264         em_ptr->dam = 0;
265         return PROCESS_CONTINUE;
266 }
267
268
269 process_result effect_monster_stasis(effect_monster_type *em_ptr, bool to_evil)
270 {
271         if (em_ptr->seen) em_ptr->obvious = TRUE;
272
273         int stasis_damage = (em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10);
274         bool has_resistance = (em_ptr->r_ptr->flags1 & RF1_UNIQUE) != 0;
275         has_resistance |= em_ptr->r_ptr->level > randint1(stasis_damage) + 10;
276         if (to_evil) has_resistance |= (em_ptr->r_ptr->flags3 & RF3_EVIL) == 0;
277
278         if (has_resistance)
279         {
280                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
281                 em_ptr->obvious = FALSE;
282         }
283         else
284         {
285                 em_ptr->note = _("は動けなくなった!", " is suspended!");
286                 em_ptr->do_sleep = 500;
287         }
288
289         em_ptr->dam = 0;
290         return PROCESS_CONTINUE;
291 }
292
293
294 process_result effect_monster_stun(effect_monster_type *em_ptr)
295 {
296         if (em_ptr->seen) em_ptr->obvious = TRUE;
297
298         em_ptr->do_stun = damroll((em_ptr->caster_lev / 20) + 3, (em_ptr->dam)) + 1;
299         if ((em_ptr->r_ptr->flags1 & (RF1_UNIQUE)) ||
300                 (em_ptr->r_ptr->level > randint1((em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10)) + 10))
301         {
302                 em_ptr->do_stun = 0;
303                 em_ptr->note = _("には効果がなかった。", " is unaffected.");
304                 em_ptr->obvious = FALSE;
305         }
306
307         em_ptr->dam = 0;
308         return PROCESS_CONTINUE;
309 }