OSDN Git Service

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