OSDN Git Service

[Refactor] race-flags#.h のインクルードを削除
[hengbandforosx/hengbandosx.git] / src / effect / effect-monster-resist-hurt.cpp
1 #include "effect/effect-monster-resist-hurt.h"
2 #include "effect/effect-monster-util.h"
3 #include "monster-race/monster-race.h"
4 #include "monster-race/race-brightness-flags.h"
5 #include "monster-race/race-flags-resistance.h"
6 #include "monster-race/race-indice-types.h"
7 #include "monster/monster-info.h"
8 #include "monster/monster-status-setter.h"
9 #include "monster/monster-status.h"
10 #include "system/grid-type-definition.h"
11 #include "system/monster-entity.h"
12 #include "system/monster-race-info.h"
13 #include "system/player-type-definition.h"
14 #include "util/bit-flags-calculator.h"
15
16 /*!
17  * @brief モンスターの耐性がなく、効果もない場合の処理
18  * @param em_ptr 魔法効果情報への参照ポインタ
19  * @return 効果処理を続ける
20  */
21 ProcessResult effect_monster_nothing(EffectMonster *em_ptr)
22 {
23     if (em_ptr->seen) {
24         em_ptr->obvious = true;
25     }
26
27     return ProcessResult::PROCESS_CONTINUE;
28 }
29
30 ProcessResult effect_monster_acid(PlayerType *player_ptr, EffectMonster *em_ptr)
31 {
32     if (em_ptr->seen) {
33         em_ptr->obvious = true;
34     }
35
36     if (em_ptr->r_ptr->resistance_flags.has_not(MonsterResistanceType::IMMUNE_ACID)) {
37         return ProcessResult::PROCESS_CONTINUE;
38     }
39
40     em_ptr->note = _("にはかなり耐性がある!", " resists a lot.");
41     em_ptr->dam /= 9;
42     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
43         em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::IMMUNE_ACID);
44     }
45
46     return ProcessResult::PROCESS_CONTINUE;
47 }
48
49 ProcessResult effect_monster_elec(PlayerType *player_ptr, EffectMonster *em_ptr)
50 {
51     if (em_ptr->seen) {
52         em_ptr->obvious = true;
53     }
54
55     if (em_ptr->r_ptr->resistance_flags.has_not(MonsterResistanceType::IMMUNE_ELEC)) {
56         return ProcessResult::PROCESS_CONTINUE;
57     }
58
59     em_ptr->note = _("にはかなり耐性がある!", " resists a lot.");
60     em_ptr->dam /= 9;
61     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
62         em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::IMMUNE_ELEC);
63     }
64
65     return ProcessResult::PROCESS_CONTINUE;
66 }
67
68 ProcessResult effect_monster_fire(PlayerType *player_ptr, EffectMonster *em_ptr)
69 {
70     if (em_ptr->seen) {
71         em_ptr->obvious = true;
72     }
73
74     if (em_ptr->r_ptr->resistance_flags.has(MonsterResistanceType::IMMUNE_FIRE)) {
75         em_ptr->note = _("にはかなり耐性がある!", " resists a lot.");
76         em_ptr->dam /= 9;
77         if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
78             em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::IMMUNE_FIRE);
79         }
80
81         return ProcessResult::PROCESS_CONTINUE;
82     }
83
84     if (em_ptr->r_ptr->resistance_flags.has_not(MonsterResistanceType::HURT_FIRE)) {
85         return ProcessResult::PROCESS_CONTINUE;
86     }
87
88     em_ptr->note = _("はひどい痛手をうけた。", " is hit hard.");
89     em_ptr->dam *= 2;
90     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
91         em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::HURT_FIRE);
92     }
93
94     return ProcessResult::PROCESS_CONTINUE;
95 }
96
97 ProcessResult effect_monster_cold(PlayerType *player_ptr, EffectMonster *em_ptr)
98 {
99     if (em_ptr->seen) {
100         em_ptr->obvious = true;
101     }
102
103     if (em_ptr->r_ptr->resistance_flags.has(MonsterResistanceType::IMMUNE_COLD)) {
104         em_ptr->note = _("にはかなり耐性がある!", " resists a lot.");
105         em_ptr->dam /= 9;
106         if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
107             em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::IMMUNE_COLD);
108         }
109
110         return ProcessResult::PROCESS_CONTINUE;
111     }
112
113     if (em_ptr->r_ptr->resistance_flags.has_not(MonsterResistanceType::HURT_COLD)) {
114         return ProcessResult::PROCESS_CONTINUE;
115     }
116
117     em_ptr->note = _("はひどい痛手をうけた。", " is hit hard.");
118     em_ptr->dam *= 2;
119     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
120         em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::HURT_COLD);
121     }
122
123     return ProcessResult::PROCESS_CONTINUE;
124 }
125
126 ProcessResult effect_monster_pois(PlayerType *player_ptr, EffectMonster *em_ptr)
127 {
128     if (em_ptr->seen) {
129         em_ptr->obvious = true;
130     }
131
132     if (em_ptr->r_ptr->resistance_flags.has_not(MonsterResistanceType::IMMUNE_POISON)) {
133         return ProcessResult::PROCESS_CONTINUE;
134     }
135
136     em_ptr->note = _("にはかなり耐性がある!", " resists a lot.");
137     em_ptr->dam /= 9;
138     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
139         em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::IMMUNE_POISON);
140     }
141
142     return ProcessResult::PROCESS_CONTINUE;
143 }
144
145 ProcessResult effect_monster_nuke(PlayerType *player_ptr, EffectMonster *em_ptr)
146 {
147     if (em_ptr->seen) {
148         em_ptr->obvious = true;
149     }
150
151     if (em_ptr->r_ptr->resistance_flags.has(MonsterResistanceType::IMMUNE_POISON)) {
152         em_ptr->note = _("には耐性がある。", " resists.");
153         em_ptr->dam *= 3;
154         em_ptr->dam /= randint1(6) + 6;
155         if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
156             em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::IMMUNE_POISON);
157         }
158
159         return ProcessResult::PROCESS_CONTINUE;
160     }
161
162     if (one_in_(3)) {
163         em_ptr->do_polymorph = true;
164     }
165
166     return ProcessResult::PROCESS_CONTINUE;
167 }
168
169 ProcessResult effect_monster_hell_fire(PlayerType *player_ptr, EffectMonster *em_ptr)
170 {
171     if (em_ptr->seen) {
172         em_ptr->obvious = true;
173     }
174
175     if (em_ptr->r_ptr->kind_flags.has_not(MonsterKindType::GOOD)) {
176         return ProcessResult::PROCESS_CONTINUE;
177     }
178
179     em_ptr->note = _("はひどい痛手をうけた。", " is hit hard.");
180     em_ptr->dam *= 2;
181     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
182         em_ptr->r_ptr->r_kind_flags.set(MonsterKindType::GOOD);
183     }
184
185     return ProcessResult::PROCESS_CONTINUE;
186 }
187
188 ProcessResult effect_monster_holy_fire(PlayerType *player_ptr, EffectMonster *em_ptr)
189 {
190     if (em_ptr->seen) {
191         em_ptr->obvious = true;
192     }
193
194     if (em_ptr->r_ptr->kind_flags.has(MonsterKindType::GOOD)) {
195         em_ptr->note = _("には完全な耐性がある!", " is immune.");
196         em_ptr->dam = 0;
197         if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
198             em_ptr->r_ptr->r_kind_flags.set(MonsterKindType::GOOD);
199         }
200         return ProcessResult::PROCESS_CONTINUE;
201     }
202
203     if (em_ptr->r_ptr->kind_flags.has(MonsterKindType::EVIL)) {
204         em_ptr->dam *= 2;
205         em_ptr->note = _("はひどい痛手をうけた。", " is hit hard.");
206         if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
207             em_ptr->r_ptr->r_kind_flags.set(MonsterKindType::EVIL);
208         }
209         return ProcessResult::PROCESS_CONTINUE;
210     }
211
212     em_ptr->note = _("には耐性がある。", " resists.");
213     em_ptr->dam *= 3;
214     em_ptr->dam /= randint1(6) + 6;
215
216     return ProcessResult::PROCESS_CONTINUE;
217 }
218
219 ProcessResult effect_monster_plasma(PlayerType *player_ptr, EffectMonster *em_ptr)
220 {
221     if (em_ptr->seen) {
222         em_ptr->obvious = true;
223     }
224
225     if (em_ptr->r_ptr->resistance_flags.has_not(MonsterResistanceType::RESIST_PLASMA)) {
226         return ProcessResult::PROCESS_CONTINUE;
227     }
228
229     em_ptr->note = _("には耐性がある。", " resists.");
230     em_ptr->dam *= 3;
231     em_ptr->dam /= randint1(6) + 6;
232     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
233         em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_PLASMA);
234     }
235
236     return ProcessResult::PROCESS_CONTINUE;
237 }
238
239 static bool effect_monster_nether_resist(PlayerType *player_ptr, EffectMonster *em_ptr)
240 {
241     if (em_ptr->r_ptr->resistance_flags.has_not(MonsterResistanceType::RESIST_NETHER)) {
242         return false;
243     }
244
245     if (em_ptr->r_ptr->kind_flags.has(MonsterKindType::UNDEAD)) {
246         em_ptr->note = _("には完全な耐性がある!", " is immune.");
247         em_ptr->dam = 0;
248         if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
249             em_ptr->r_ptr->r_kind_flags.set(MonsterKindType::UNDEAD);
250         }
251     } else {
252         em_ptr->note = _("には耐性がある。", " resists.");
253         em_ptr->dam *= 3;
254         em_ptr->dam /= randint1(6) + 6;
255     }
256
257     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
258         em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_NETHER);
259     }
260
261     return true;
262 }
263
264 ProcessResult effect_monster_nether(PlayerType *player_ptr, EffectMonster *em_ptr)
265 {
266     if (em_ptr->seen) {
267         em_ptr->obvious = true;
268     }
269
270     if (effect_monster_nether_resist(player_ptr, em_ptr) || (em_ptr->r_ptr->kind_flags.has_not(MonsterKindType::EVIL))) {
271         return ProcessResult::PROCESS_CONTINUE;
272     }
273
274     em_ptr->note = _("はいくらか耐性を示した。", " resists somewhat.");
275     em_ptr->dam /= 2;
276     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
277         em_ptr->r_ptr->r_kind_flags.set(MonsterKindType::EVIL);
278     }
279
280     return ProcessResult::PROCESS_CONTINUE;
281 }
282
283 ProcessResult effect_monster_water(PlayerType *player_ptr, EffectMonster *em_ptr)
284 {
285     if (em_ptr->seen) {
286         em_ptr->obvious = true;
287     }
288
289     if (em_ptr->r_ptr->resistance_flags.has_not(MonsterResistanceType::RESIST_WATER)) {
290         return ProcessResult::PROCESS_CONTINUE;
291     }
292
293     if ((em_ptr->m_ptr->r_idx == MonsterRaceId::WATER_ELEM) || (em_ptr->m_ptr->r_idx == MonsterRaceId::UNMAKER)) {
294         em_ptr->note = _("には完全な耐性がある!", " is immune.");
295         em_ptr->dam = 0;
296     } else {
297         em_ptr->note = _("には耐性がある。", " resists.");
298         em_ptr->dam *= 3;
299         em_ptr->dam /= randint1(6) + 6;
300     }
301
302     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
303         em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_WATER);
304     }
305
306     return ProcessResult::PROCESS_CONTINUE;
307 }
308
309 ProcessResult effect_monster_chaos(PlayerType *player_ptr, EffectMonster *em_ptr)
310 {
311     if (em_ptr->seen) {
312         em_ptr->obvious = true;
313     }
314
315     if (em_ptr->r_ptr->resistance_flags.has(MonsterResistanceType::RESIST_CHAOS)) {
316         em_ptr->note = _("には耐性がある。", " resists.");
317         em_ptr->dam *= 3;
318         em_ptr->dam /= randint1(6) + 6;
319         if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
320             em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_CHAOS);
321         }
322     } else if (em_ptr->r_ptr->kind_flags.has(MonsterKindType::DEMON) && one_in_(3)) {
323         em_ptr->note = _("はいくらか耐性を示した。", " resists somewhat.");
324         em_ptr->dam *= 3;
325         em_ptr->dam /= randint1(6) + 6;
326         if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
327             em_ptr->r_ptr->r_kind_flags.set(MonsterKindType::DEMON);
328         }
329     } else {
330         em_ptr->do_polymorph = true;
331         em_ptr->do_conf = (5 + randint1(11) + em_ptr->r) / (em_ptr->r + 1);
332     }
333
334     return ProcessResult::PROCESS_CONTINUE;
335 }
336
337 ProcessResult effect_monster_shards(PlayerType *player_ptr, EffectMonster *em_ptr)
338 {
339     if (em_ptr->seen) {
340         em_ptr->obvious = true;
341     }
342
343     if (em_ptr->r_ptr->resistance_flags.has_not(MonsterResistanceType::RESIST_SHARDS)) {
344         return ProcessResult::PROCESS_CONTINUE;
345     }
346
347     em_ptr->note = _("には耐性がある。", " resists.");
348     em_ptr->dam *= 3;
349     em_ptr->dam /= randint1(6) + 6;
350     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
351         em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_SHARDS);
352     }
353
354     return ProcessResult::PROCESS_CONTINUE;
355 }
356
357 ProcessResult effect_monster_rocket(PlayerType *player_ptr, EffectMonster *em_ptr)
358 {
359     if (em_ptr->seen) {
360         em_ptr->obvious = true;
361     }
362
363     if (em_ptr->r_ptr->resistance_flags.has_not(MonsterResistanceType::RESIST_SHARDS)) {
364         return ProcessResult::PROCESS_CONTINUE;
365     }
366
367     em_ptr->note = _("はいくらか耐性を示した。", " resists somewhat.");
368     em_ptr->dam /= 2;
369     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
370         em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_SHARDS);
371     }
372
373     return ProcessResult::PROCESS_CONTINUE;
374 }
375
376 ProcessResult effect_monster_sound(PlayerType *player_ptr, EffectMonster *em_ptr)
377 {
378     if (em_ptr->seen) {
379         em_ptr->obvious = true;
380     }
381
382     if (em_ptr->r_ptr->resistance_flags.has_not(MonsterResistanceType::RESIST_SOUND)) {
383         em_ptr->do_stun = (10 + randint1(15) + em_ptr->r) / (em_ptr->r + 1);
384         return ProcessResult::PROCESS_CONTINUE;
385     }
386
387     em_ptr->note = _("には耐性がある。", " resists.");
388     em_ptr->dam *= 2;
389     em_ptr->dam /= randint1(6) + 6;
390     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
391         em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_SOUND);
392     }
393
394     return ProcessResult::PROCESS_CONTINUE;
395 }
396
397 ProcessResult effect_monster_confusion(PlayerType *player_ptr, EffectMonster *em_ptr)
398 {
399     if (em_ptr->seen) {
400         em_ptr->obvious = true;
401     }
402
403     if (em_ptr->r_ptr->resistance_flags.has_not(MonsterResistanceType::NO_CONF)) {
404         em_ptr->do_conf = (10 + randint1(15) + em_ptr->r) / (em_ptr->r + 1);
405         return ProcessResult::PROCESS_CONTINUE;
406     }
407
408     em_ptr->note = _("には耐性がある。", " resists.");
409     em_ptr->dam *= 3;
410     em_ptr->dam /= randint1(6) + 6;
411     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
412         em_ptr->r_ptr->resistance_flags.set(MonsterResistanceType::NO_CONF);
413     }
414
415     return ProcessResult::PROCESS_CONTINUE;
416 }
417
418 ProcessResult effect_monster_disenchant(PlayerType *player_ptr, EffectMonster *em_ptr)
419 {
420     if (em_ptr->seen) {
421         em_ptr->obvious = true;
422     }
423
424     if (em_ptr->r_ptr->resistance_flags.has_not(MonsterResistanceType::RESIST_DISENCHANT)) {
425         return ProcessResult::PROCESS_CONTINUE;
426     }
427
428     em_ptr->note = _("には耐性がある。", " resists.");
429     em_ptr->dam *= 3;
430     em_ptr->dam /= randint1(6) + 6;
431     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
432         em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_DISENCHANT);
433     }
434
435     return ProcessResult::PROCESS_CONTINUE;
436 }
437
438 ProcessResult effect_monster_nexus(PlayerType *player_ptr, EffectMonster *em_ptr)
439 {
440     if (em_ptr->seen) {
441         em_ptr->obvious = true;
442     }
443
444     if (em_ptr->r_ptr->resistance_flags.has_not(MonsterResistanceType::RESIST_NEXUS)) {
445         return ProcessResult::PROCESS_CONTINUE;
446     }
447
448     em_ptr->note = _("には耐性がある。", " resists.");
449     em_ptr->dam *= 3;
450     em_ptr->dam /= randint1(6) + 6;
451     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
452         em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_NEXUS);
453     }
454
455     return ProcessResult::PROCESS_CONTINUE;
456 }
457
458 ProcessResult effect_monster_force(PlayerType *player_ptr, EffectMonster *em_ptr)
459 {
460     if (em_ptr->seen) {
461         em_ptr->obvious = true;
462     }
463
464     if (em_ptr->r_ptr->resistance_flags.has_not(MonsterResistanceType::RESIST_FORCE)) {
465         em_ptr->do_stun = (randint1(15) + em_ptr->r) / (em_ptr->r + 1);
466         return ProcessResult::PROCESS_CONTINUE;
467     }
468
469     em_ptr->note = _("には耐性がある。", " resists.");
470     em_ptr->dam *= 3;
471     em_ptr->dam /= randint1(6) + 6;
472     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
473         em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_FORCE);
474     }
475
476     return ProcessResult::PROCESS_CONTINUE;
477 }
478
479 // Powerful monsters can resists and normal monsters slow down.
480 ProcessResult effect_monster_inertial(PlayerType *player_ptr, EffectMonster *em_ptr)
481 {
482     if (em_ptr->seen) {
483         em_ptr->obvious = true;
484     }
485
486     if (em_ptr->r_ptr->resistance_flags.has(MonsterResistanceType::RESIST_INERTIA)) {
487         em_ptr->note = _("には耐性がある。", " resists.");
488         em_ptr->dam *= 3;
489         em_ptr->dam /= randint1(6) + 6;
490         if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
491             em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_INERTIA);
492         }
493
494         return ProcessResult::PROCESS_CONTINUE;
495     }
496
497     bool cancel_effect = em_ptr->r_ptr->kind_flags.has(MonsterKindType::UNIQUE);
498     cancel_effect |= (em_ptr->r_ptr->level > randint1(std::max(1, em_ptr->dam - 10)) + 10);
499     if (cancel_effect) {
500         em_ptr->obvious = false;
501         return ProcessResult::PROCESS_CONTINUE;
502     }
503
504     if (set_monster_slow(player_ptr, em_ptr->g_ptr->m_idx, em_ptr->m_ptr->get_remaining_deceleration() + 50)) {
505         em_ptr->note = _("の動きが遅くなった。", " starts moving slower.");
506     }
507
508     return ProcessResult::PROCESS_CONTINUE;
509 }
510
511 ProcessResult effect_monster_time(PlayerType *player_ptr, EffectMonster *em_ptr)
512 {
513     if (em_ptr->seen) {
514         em_ptr->obvious = true;
515     }
516
517     if (em_ptr->r_ptr->resistance_flags.has_not(MonsterResistanceType::RESIST_TIME)) {
518         em_ptr->do_time = (em_ptr->dam + 1) / 2;
519         return ProcessResult::PROCESS_CONTINUE;
520     }
521
522     em_ptr->note = _("には耐性がある。", " resists.");
523     em_ptr->dam *= 3;
524     em_ptr->dam /= randint1(6) + 6;
525     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
526         em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_TIME);
527     }
528
529     return ProcessResult::PROCESS_CONTINUE;
530 }
531
532 static bool effect_monster_gravity_resist_teleport(PlayerType *player_ptr, EffectMonster *em_ptr)
533 {
534     if (em_ptr->r_ptr->resistance_flags.has_not(MonsterResistanceType::RESIST_TELEPORT)) {
535         em_ptr->obvious = true;
536         return false;
537     }
538
539     if (em_ptr->r_ptr->kind_flags.has(MonsterKindType::UNIQUE)) {
540         if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
541             em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_TELEPORT);
542         }
543
544         em_ptr->note = _("には効果がなかった。", " is unaffected!");
545         return true;
546     }
547
548     if (em_ptr->r_ptr->level <= randint1(100)) {
549         em_ptr->obvious = true;
550         return false;
551     }
552
553     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
554         em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_TELEPORT);
555     }
556
557     em_ptr->note = _("には耐性がある!", " resists!");
558     return true;
559 }
560
561 static void effect_monster_gravity_slow(PlayerType *player_ptr, EffectMonster *em_ptr)
562 {
563     bool cancel_effect = em_ptr->r_ptr->kind_flags.has(MonsterKindType::UNIQUE);
564     cancel_effect |= (em_ptr->r_ptr->level > randint1(std::max(1, em_ptr->dam - 10)) + 10);
565     if (cancel_effect) {
566         em_ptr->obvious = false;
567         return;
568     }
569
570     if (set_monster_slow(player_ptr, em_ptr->g_ptr->m_idx, em_ptr->m_ptr->get_remaining_deceleration() + 50)) {
571         em_ptr->note = _("の動きが遅くなった。", " starts moving slower.");
572     }
573     em_ptr->obvious = true;
574 }
575
576 static void effect_monster_gravity_stun(EffectMonster *em_ptr)
577 {
578     em_ptr->do_stun = damroll((em_ptr->caster_lev / 20) + 3, (em_ptr->dam)) + 1;
579     bool has_resistance = em_ptr->r_ptr->kind_flags.has(MonsterKindType::UNIQUE);
580     has_resistance |= (em_ptr->r_ptr->level > randint1(std::max(1, em_ptr->dam - 10)) + 10);
581     if (has_resistance) {
582         em_ptr->do_stun = 0;
583         return;
584     }
585     em_ptr->obvious = true;
586 }
587
588 /*
589  * Powerful monsters can resist and normal monsters slow down
590  * Furthermore, this magic can make non-unique monsters slow/stun.
591  */
592 ProcessResult effect_monster_gravity(PlayerType *player_ptr, EffectMonster *em_ptr)
593 {
594     em_ptr->do_dist = effect_monster_gravity_resist_teleport(player_ptr, em_ptr) ? 0 : 10;
595     if (player_ptr->riding && (em_ptr->g_ptr->m_idx == player_ptr->riding)) {
596         em_ptr->do_dist = 0;
597     }
598
599     if (em_ptr->r_ptr->resistance_flags.has(MonsterResistanceType::RESIST_GRAVITY)) {
600         em_ptr->note = _("には耐性がある!", " resists!");
601         em_ptr->dam *= 3;
602         em_ptr->dam /= randint1(6) + 6;
603         em_ptr->do_dist = 0;
604         if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
605             em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_GRAVITY);
606         }
607         return ProcessResult::PROCESS_CONTINUE;
608     }
609
610     em_ptr->note = _("には効果がなかった。", " is unaffected!");
611
612     effect_monster_gravity_slow(player_ptr, em_ptr);
613     effect_monster_gravity_stun(em_ptr);
614     return ProcessResult::PROCESS_CONTINUE;
615 }
616
617 ProcessResult effect_monster_disintegration(PlayerType *player_ptr, EffectMonster *em_ptr)
618 {
619     if (em_ptr->seen) {
620         em_ptr->obvious = true;
621     }
622
623     if (em_ptr->r_ptr->resistance_flags.has_not(MonsterResistanceType::HURT_ROCK)) {
624         return ProcessResult::PROCESS_CONTINUE;
625     }
626
627     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
628         em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::HURT_ROCK);
629     }
630
631     em_ptr->note = _("の皮膚がただれた!", " loses some skin!");
632     em_ptr->note_dies = _("は蒸発した!", " evaporates!");
633     em_ptr->dam *= 2;
634     return ProcessResult::PROCESS_CONTINUE;
635 }
636
637 ProcessResult effect_monster_icee_bolt(PlayerType *player_ptr, EffectMonster *em_ptr)
638 {
639     if (em_ptr->seen) {
640         em_ptr->obvious = true;
641     }
642
643     em_ptr->do_stun = (randint1(15) + 1) / (em_ptr->r + 1);
644     if (em_ptr->r_ptr->resistance_flags.has(MonsterResistanceType::IMMUNE_COLD)) {
645         em_ptr->note = _("にはかなり耐性がある!", " resists a lot.");
646         em_ptr->dam /= 9;
647         if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
648             em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::IMMUNE_COLD);
649         }
650     } else if (em_ptr->r_ptr->resistance_flags.has(MonsterResistanceType::HURT_COLD)) {
651         em_ptr->note = _("はひどい痛手をうけた。", " is hit hard.");
652         em_ptr->dam *= 2;
653         if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
654             em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::HURT_COLD);
655         }
656     }
657
658     return ProcessResult::PROCESS_CONTINUE;
659 }
660
661 /*!
662  * @brief 虚無属性の耐性と効果の発動
663  * @param player_ptr プレイヤー情報への参照ポインタ
664  * @em_ptr 魔法効果情報への参照ポインタ
665  * @return 効果処理を続けるかどうか
666  * @details
667  * 量子生物に倍打、壁抜けに1.5倍打、テレポート耐性が耐性
668  */
669 ProcessResult effect_monster_void(PlayerType *player_ptr, EffectMonster *em_ptr)
670 {
671     if (em_ptr->seen) {
672         em_ptr->obvious = true;
673     }
674
675     if (em_ptr->r_ptr->kind_flags.has(MonsterKindType::QUANTUM)) {
676         em_ptr->note = _("の存在確率が減少した。", "'s wave function is reduced.");
677         em_ptr->note_dies = _("は観測されなくなった。", "'s wave function collapses.");
678         em_ptr->dam *= 2;
679         if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
680             em_ptr->r_ptr->r_kind_flags.set(MonsterKindType::QUANTUM);
681         }
682     } else if (em_ptr->r_ptr->feature_flags.has(MonsterFeatureType::PASS_WALL)) {
683         em_ptr->note = _("の存在が薄れていく。", "is fading out.");
684         em_ptr->note_dies = _("は消えてしまった。", "has disappeared.");
685         em_ptr->dam *= 3;
686         em_ptr->dam /= 2;
687         if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
688             em_ptr->r_ptr->r_feature_flags.set(MonsterFeatureType::PASS_WALL);
689         }
690     } else if (em_ptr->r_ptr->resistance_flags.has_any_of({ MonsterResistanceType::RESIST_TELEPORT, MonsterResistanceType::RESIST_FORCE, MonsterResistanceType::RESIST_GRAVITY })) {
691         em_ptr->note = _("には耐性がある!", " resists!");
692         em_ptr->dam *= 3;
693         em_ptr->dam /= randint1(6) + 6;
694         if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
695             if (em_ptr->r_ptr->resistance_flags.has(MonsterResistanceType::RESIST_TELEPORT)) {
696                 em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_TELEPORT);
697             }
698             if (em_ptr->r_ptr->resistance_flags.has(MonsterResistanceType::RESIST_FORCE)) {
699                 em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_FORCE);
700             }
701             if (em_ptr->r_ptr->resistance_flags.has(MonsterResistanceType::RESIST_GRAVITY)) {
702                 em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_GRAVITY);
703             }
704         }
705     } else {
706         em_ptr->note_dies = _("は消滅してしまった。", "has vanished.");
707     }
708
709     return ProcessResult::PROCESS_CONTINUE;
710 }
711
712 /*!
713  * @brief 深淵属性の耐性と効果の発動
714  * @param player_ptr プレイヤー情報への参照ポインタ
715  * @em_ptr 魔法効果情報への参照ポインタ
716  * @return 効果処理を続けるかどうか
717  * @details
718  * 飛ばないテレポート耐性に1.25倍打、暗黒耐性が耐性
719  * 1/3で追加に混乱か恐怖
720  */
721 ProcessResult effect_monster_abyss(PlayerType *player_ptr, EffectMonster *em_ptr)
722 {
723     if (em_ptr->seen) {
724         em_ptr->obvious = true;
725     }
726
727     auto dark = { MonsterBrightnessType::SELF_DARK_1, MonsterBrightnessType::SELF_DARK_2, MonsterBrightnessType::HAS_DARK_1, MonsterBrightnessType::HAS_DARK_2 };
728
729     if (em_ptr->r_ptr->brightness_flags.has_any_of(dark)) {
730         em_ptr->note = _("には耐性がある!", " resists!");
731         em_ptr->dam *= 3;
732         em_ptr->dam /= (randint1(6) + 6);
733     } else if (em_ptr->r_ptr->resistance_flags.has(MonsterResistanceType::RESIST_DARK)) {
734         em_ptr->note = _("には耐性がある!", " resists!");
735         em_ptr->dam *= 3;
736         em_ptr->dam /= (randint1(4) + 5);
737         if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
738             em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_DARK);
739         }
740     } else if (em_ptr->r_ptr->feature_flags.has_not(MonsterFeatureType::CAN_FLY)) {
741         if (em_ptr->r_ptr->resistance_flags.has(MonsterResistanceType::RESIST_TELEPORT)) {
742             em_ptr->dam *= 5;
743             em_ptr->dam /= 4;
744             if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
745                 em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_TELEPORT);
746             }
747         }
748
749         em_ptr->note = _("は深淵に囚われていく。", " is trapped in the abyss.");
750         em_ptr->note_dies = _("は深淵に堕ちてしまった。", " has fallen into the abyss.");
751
752         if (one_in_(3) && set_monster_slow(player_ptr, em_ptr->g_ptr->m_idx, em_ptr->m_ptr->get_remaining_deceleration() + 50)) {
753             em_ptr->note = _("の動きが遅くなった。", " starts moving slower.");
754         }
755     }
756
757     if (em_ptr->r_ptr->misc_flags.has(MonsterMiscType::ELDRITCH_HORROR) || em_ptr->r_ptr->misc_flags.has(MonsterMiscType::EMPTY_MIND)) {
758         return ProcessResult::PROCESS_CONTINUE;
759     }
760
761     if (one_in_(3)) {
762         if (one_in_(2)) {
763             em_ptr->do_conf = (10 + randint1(15) + em_ptr->r) / (em_ptr->r + 1);
764         } else {
765             em_ptr->do_fear = (10 + randint1(15) + em_ptr->r) / (em_ptr->r + 1);
766         }
767     }
768
769     return ProcessResult::PROCESS_CONTINUE;
770 }
771
772 ProcessResult effect_monster_meteor(PlayerType *player_ptr, EffectMonster *em_ptr)
773 {
774     if (em_ptr->seen) {
775         em_ptr->obvious = true;
776     }
777
778     if (em_ptr->r_ptr->resistance_flags.has_not(MonsterResistanceType::RESIST_METEOR)) {
779         return ProcessResult::PROCESS_CONTINUE;
780     }
781
782     em_ptr->note = _("には耐性がある!", " resists!");
783     em_ptr->dam *= 3;
784     em_ptr->dam /= randint1(6) + 6;
785     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
786         em_ptr->r_ptr->r_resistance_flags.set(MonsterResistanceType::RESIST_METEOR);
787     }
788
789     return ProcessResult::PROCESS_CONTINUE;
790 }