OSDN Git Service

[Refactor] #2200 effect-processor::project() 以外の箇所からg_cap_mon_ptrの依存をなくした
[hengbandforosx/hengbandosx.git] / src / effect / effect-monster-switcher.cpp
1 /*!
2  * 本ファイル内の行数はまともなレベルに落ち着いているので、一旦ここに留め置くこととする
3  * @brief 魔法種別による各種処理切り替え
4  * @date 2020/04/29
5  * @author Hourier
6  * @todo どうしても「その他」に分類せざるを得ない魔法種別が残った
7  */
8
9 #include "effect/effect-monster-switcher.h"
10 #include "avatar/avatar.h"
11 #include "cmd-action/cmd-attack.h"
12 #include "effect/effect-monster-charm.h"
13 #include "effect/effect-monster-curse.h"
14 #include "effect/effect-monster-evil.h"
15 #include "effect/effect-monster-lite-dark.h"
16 #include "effect/effect-monster-oldies.h"
17 #include "effect/effect-monster-psi.h"
18 #include "effect/effect-monster-resist-hurt.h"
19 #include "effect/effect-monster-spirit.h"
20 #include "effect/effect-monster-util.h"
21 #include "mind/mind-elementalist.h"
22 #include "monster-floor/monster-death.h"
23 #include "monster-race/monster-race-hook.h"
24 #include "monster-race/monster-race.h"
25 #include "monster-race/race-flags1.h"
26 #include "monster-race/race-flags2.h"
27 #include "monster-race/race-flags3.h"
28 #include "monster/monster-info.h"
29 #include "monster/monster-status-setter.h"
30 #include "monster/monster-status.h"
31 #include "player/player-damage.h"
32 #include "spell-kind/spells-genocide.h"
33 #include "system/grid-type-definition.h"
34 #include "system/monster-race-definition.h"
35 #include "system/monster-type-definition.h"
36 #include "system/player-type-definition.h"
37 #include "util/bit-flags-calculator.h"
38 #include "view/display-messages.h"
39
40 process_result effect_monster_hypodynamia(PlayerType *player_ptr, effect_monster_type *em_ptr)
41 {
42     if (em_ptr->seen)
43         em_ptr->obvious = true;
44
45     if (monster_living(em_ptr->m_ptr->r_idx)) {
46         em_ptr->do_time = (em_ptr->dam + 7) / 8;
47         return PROCESS_CONTINUE;
48     }
49
50     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
51         if (em_ptr->r_ptr->kind_flags.has(MonsterKindType::DEMON))
52             em_ptr->r_ptr->r_kind_flags.set(MonsterKindType::DEMON);
53         if (em_ptr->r_ptr->kind_flags.has(MonsterKindType::UNDEAD))
54             em_ptr->r_ptr->r_kind_flags.set(MonsterKindType::UNDEAD);
55         if (em_ptr->r_ptr->kind_flags.has(MonsterKindType::NONLIVING))
56             em_ptr->r_ptr->r_kind_flags.set(MonsterKindType::NONLIVING);
57     }
58
59     em_ptr->note = _("には効果がなかった。", " is unaffected.");
60     em_ptr->obvious = false;
61     em_ptr->dam = 0;
62     return PROCESS_CONTINUE;
63 }
64
65 /*!
66  * @todo リファクタリング前のコード時点で、単に耐性があるだけでもダメージ0だった.
67  */
68 process_result effect_monster_death_ray(PlayerType *player_ptr, effect_monster_type *em_ptr)
69 {
70     if (em_ptr->seen)
71         em_ptr->obvious = true;
72
73     if (!monster_living(em_ptr->m_ptr->r_idx)) {
74         if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr)) {
75             if (em_ptr->r_ptr->kind_flags.has(MonsterKindType::DEMON))
76                 em_ptr->r_ptr->r_kind_flags.set(MonsterKindType::DEMON);
77             if (em_ptr->r_ptr->kind_flags.has(MonsterKindType::UNDEAD))
78                 em_ptr->r_ptr->r_kind_flags.set(MonsterKindType::UNDEAD);
79             if (em_ptr->r_ptr->kind_flags.has(MonsterKindType::NONLIVING))
80                 em_ptr->r_ptr->r_kind_flags.set(MonsterKindType::NONLIVING);
81         }
82
83         em_ptr->note = _("には完全な耐性がある!", " is immune.");
84         em_ptr->obvious = false;
85         em_ptr->dam = 0;
86         return PROCESS_CONTINUE;
87     }
88
89     bool has_resistance = (em_ptr->r_ptr->kind_flags.has(MonsterKindType::UNIQUE) && (randint1(888) != 666));
90     has_resistance |= (((em_ptr->r_ptr->level + randint1(20)) > randint1((em_ptr->caster_lev / 2) + randint1(10))) && randint1(100) != 66);
91
92     if (has_resistance) {
93         em_ptr->note = _("には耐性がある!", " resists!");
94         em_ptr->obvious = false;
95         em_ptr->dam = 0;
96     }
97
98     return PROCESS_CONTINUE;
99 }
100
101 process_result effect_monster_kill_wall(PlayerType *player_ptr, effect_monster_type *em_ptr)
102 {
103     if ((em_ptr->r_ptr->flags3 & (RF3_HURT_ROCK)) == 0) {
104         em_ptr->dam = 0;
105         return PROCESS_CONTINUE;
106     }
107
108     if (em_ptr->seen)
109         em_ptr->obvious = true;
110
111     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
112         em_ptr->r_ptr->r_flags3 |= (RF3_HURT_ROCK);
113
114     em_ptr->note = _("の皮膚がただれた!", " loses some skin!");
115     em_ptr->note_dies = _("はドロドロに溶けた!", " dissolves!");
116     return PROCESS_CONTINUE;
117 }
118
119 process_result effect_monster_hand_doom(effect_monster_type *em_ptr)
120 {
121     if (em_ptr->seen)
122         em_ptr->obvious = true;
123
124     if (em_ptr->r_ptr->kind_flags.has(MonsterKindType::UNIQUE)) {
125         em_ptr->note = _("には効果がなかった。", " is unaffected.");
126         em_ptr->dam = 0;
127         return PROCESS_CONTINUE;
128     }
129
130     if ((em_ptr->who > 0) ? ((em_ptr->caster_lev + randint1(em_ptr->dam)) > (em_ptr->r_ptr->level + 10 + randint1(20)))
131                           : (((em_ptr->caster_lev / 2) + randint1(em_ptr->dam)) > (em_ptr->r_ptr->level + randint1(200)))) {
132         em_ptr->dam = ((40 + randint1(20)) * em_ptr->m_ptr->hp) / 100;
133         if (em_ptr->m_ptr->hp < em_ptr->dam)
134             em_ptr->dam = em_ptr->m_ptr->hp - 1;
135     } else {
136         em_ptr->note = _("は破滅の手に耐え切った!", "resists!");
137         em_ptr->dam = 0;
138     }
139
140     return PROCESS_CONTINUE;
141 }
142
143 /*!
144  * @brief 剣術「幻惑」の効果をモンスターに与える
145  * @param player_ptr プレイヤーの情報へのポインタ
146  * @param effect_monster_type モンスターの効果情報へのポインタ
147  * @details
148  * 精神のないモンスター、寝ているモンスターには無効。
149  * 3回試行し、それぞれ2/5で失敗。
150  * 寝た場合は試行終了。
151  * 与える効果は減速、朦朧、混乱、睡眠。
152  */
153 process_result effect_monster_engetsu(PlayerType *player_ptr, effect_monster_type *em_ptr)
154 {
155     if (em_ptr->seen)
156         em_ptr->obvious = true;
157
158     if (any_bits(em_ptr->r_ptr->flags2, RF2_EMPTY_MIND)) {
159         em_ptr->note = _("には効果がなかった。", " is unaffected.");
160         em_ptr->dam = 0;
161         em_ptr->skipped = true;
162         if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
163             set_bits(em_ptr->r_ptr->r_flags2, RF2_EMPTY_MIND);
164         return PROCESS_CONTINUE;
165     }
166
167     if (monster_csleep_remaining(em_ptr->m_ptr)) {
168         em_ptr->note = _("には効果がなかった。", " is unaffected.");
169         em_ptr->dam = 0;
170         em_ptr->skipped = true;
171         return PROCESS_CONTINUE;
172     }
173
174     bool done = false;
175     for (int i = 0; i < 3; i++) {
176         if (randint0(5) < 2)
177             continue;
178
179         int power = 10 + randint1((em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10));
180         if (em_ptr->r_ptr->level > power)
181             continue;
182
183         switch (randint0(4)) {
184         case 0:
185             if (em_ptr->r_ptr->kind_flags.has_not(MonsterKindType::UNIQUE)) {
186                 if (set_monster_slow(player_ptr, em_ptr->g_ptr->m_idx, monster_slow_remaining(em_ptr->m_ptr) + 50)) {
187                     em_ptr->note = _("の動きが遅くなった。", " starts moving slower.");
188                 }
189                 done = true;
190             }
191             break;
192         case 1:
193             if (em_ptr->r_ptr->kind_flags.has(MonsterKindType::UNIQUE)) {
194                 em_ptr->do_stun = 0;
195             } else {
196                 em_ptr->do_stun = damroll((player_ptr->lev / 10) + 3, (em_ptr->dam)) + 1;
197                 done = true;
198             }
199             break;
200         case 2:
201             if (em_ptr->r_ptr->kind_flags.has(MonsterKindType::UNIQUE) || any_bits(em_ptr->r_ptr->flags3, RF3_NO_CONF)) {
202                 if (any_bits(em_ptr->r_ptr->flags3, RF3_NO_CONF)) {
203                     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
204                         set_bits(em_ptr->r_ptr->r_flags3, RF3_NO_CONF);
205                 }
206                 em_ptr->do_conf = 0;
207             } else {
208                 /* Go to sleep (much) later */
209                 em_ptr->note = _("は混乱したようだ。", " looks confused.");
210                 em_ptr->do_conf = 10 + randint1(15);
211                 done = true;
212             }
213             break;
214         default:
215             if (em_ptr->r_ptr->kind_flags.has(MonsterKindType::UNIQUE) || any_bits(em_ptr->r_ptr->flags3, RF3_NO_SLEEP)) {
216                 if (any_bits(em_ptr->r_ptr->flags3, RF3_NO_SLEEP)) {
217                     if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
218                         set_bits(em_ptr->r_ptr->r_flags3, RF3_NO_SLEEP);
219                 }
220                 em_ptr->do_sleep = 0;
221             } else {
222                 /* Go to sleep (much) later */
223                 em_ptr->note = _("は眠り込んでしまった!", " falls asleep!");
224                 em_ptr->do_sleep = 500;
225                 done = true;
226             }
227             break;
228         }
229
230         if (em_ptr->do_sleep > 0)
231             break;
232     }
233
234     if (!done) {
235         em_ptr->note = _("には効果がなかった。", " is unaffected.");
236         em_ptr->obvious = false;
237     }
238
239     em_ptr->dam = 0;
240     return PROCESS_CONTINUE;
241 }
242
243 process_result effect_monster_genocide(PlayerType *player_ptr, effect_monster_type *em_ptr)
244 {
245     if (em_ptr->seen)
246         em_ptr->obvious = true;
247
248     std::string_view spell_name(_("モンスター消滅", "Genocide One"));
249     if (genocide_aux(player_ptr, em_ptr->g_ptr->m_idx, em_ptr->dam, !em_ptr->who, (em_ptr->r_ptr->level + 1) / 2, spell_name.data())) {
250         if (em_ptr->seen_msg)
251             msg_format(_("%sは消滅した!", "%^s disappeared!"), em_ptr->m_name);
252         chg_virtue(player_ptr, V_VITALITY, -1);
253         return PROCESS_TRUE;
254     }
255
256     em_ptr->skipped = true;
257     return PROCESS_CONTINUE;
258 }
259
260 process_result effect_monster_photo(PlayerType *player_ptr, effect_monster_type *em_ptr)
261 {
262     if (!em_ptr->who)
263         msg_format(_("%sを写真に撮った。", "You take a photograph of %s."), em_ptr->m_name);
264
265     if (em_ptr->r_ptr->flags3 & (RF3_HURT_LITE)) {
266         if (em_ptr->seen)
267             em_ptr->obvious = true;
268
269         if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
270             em_ptr->r_ptr->r_flags3 |= (RF3_HURT_LITE);
271
272         em_ptr->note = _("は光に身をすくめた!", " cringes from the light!");
273         em_ptr->note_dies = _("は光を受けてしぼんでしまった!", " shrivels away in the light!");
274     } else {
275         em_ptr->dam = 0;
276     }
277
278     em_ptr->photo = em_ptr->m_ptr->r_idx;
279     return PROCESS_CONTINUE;
280 }
281
282 process_result effect_monster_wounds(effect_monster_type *em_ptr)
283 {
284     if (em_ptr->seen)
285         em_ptr->obvious = true;
286
287     if (randint0(100 + em_ptr->dam) < (em_ptr->r_ptr->level + 50)) {
288         em_ptr->note = _("には効果がなかった。", " is unaffected.");
289         em_ptr->dam = 0;
290     }
291
292     return PROCESS_CONTINUE;
293 }
294
295 /*!
296  * @brief 魔法の効果によって様々なメッセーを出力したり与えるダメージの増減を行ったりする
297  * @param em_ptr モンスター効果構造体への参照ポインタ
298  * @return ここのスイッチングで終るならTRUEかFALSE、後続処理を実行するならCONTINUE
299  */
300 process_result switch_effects_monster(PlayerType *player_ptr, effect_monster_type *em_ptr, CapturedMonsterType *cap_mon_ptr)
301 {
302     switch (em_ptr->attribute) {
303     case AttributeType::PSY_SPEAR:
304     case AttributeType::MISSILE:
305     case AttributeType::DEBUG:
306     case AttributeType::MANA:
307     case AttributeType::METEOR:
308     case AttributeType::BLOOD_CURSE:
309     case AttributeType::SEEKER:
310     case AttributeType::SUPER_RAY:
311     case AttributeType::MONSTER_MELEE:
312     case AttributeType::MONSTER_SHOOT:
313         return effect_monster_nothing(em_ptr);
314     case AttributeType::ACID:
315         return effect_monster_acid(player_ptr, em_ptr);
316     case AttributeType::ELEC:
317         return effect_monster_elec(player_ptr, em_ptr);
318     case AttributeType::FIRE:
319         return effect_monster_fire(player_ptr, em_ptr);
320     case AttributeType::COLD:
321         return effect_monster_cold(player_ptr, em_ptr);
322     case AttributeType::POIS:
323         return effect_monster_pois(player_ptr, em_ptr);
324     case AttributeType::NUKE:
325         return effect_monster_nuke(player_ptr, em_ptr);
326     case AttributeType::HELL_FIRE:
327         return effect_monster_hell_fire(player_ptr, em_ptr);
328     case AttributeType::HOLY_FIRE:
329         return effect_monster_holy_fire(player_ptr, em_ptr);
330     case AttributeType::PLASMA:
331         return effect_monster_plasma(player_ptr, em_ptr);
332     case AttributeType::NETHER:
333         return effect_monster_nether(player_ptr, em_ptr);
334     case AttributeType::WATER:
335         return effect_monster_water(player_ptr, em_ptr);
336     case AttributeType::CHAOS:
337         return effect_monster_chaos(player_ptr, em_ptr);
338     case AttributeType::SHARDS:
339         return effect_monster_shards(player_ptr, em_ptr);
340     case AttributeType::ROCKET:
341         return effect_monster_rocket(player_ptr, em_ptr);
342     case AttributeType::SOUND:
343         return effect_monster_sound(player_ptr, em_ptr);
344     case AttributeType::CONFUSION:
345         return effect_monster_confusion(player_ptr, em_ptr);
346     case AttributeType::DISENCHANT:
347         return effect_monster_disenchant(player_ptr, em_ptr);
348     case AttributeType::NEXUS:
349         return effect_monster_nexus(player_ptr, em_ptr);
350     case AttributeType::FORCE:
351         return effect_monster_force(player_ptr, em_ptr);
352     case AttributeType::INERTIAL:
353         return effect_monster_inertial(player_ptr, em_ptr);
354     case AttributeType::TIME:
355         return effect_monster_time(player_ptr, em_ptr);
356     case AttributeType::GRAVITY:
357         return effect_monster_gravity(player_ptr, em_ptr);
358     case AttributeType::DISINTEGRATE:
359         return effect_monster_disintegration(player_ptr, em_ptr);
360     case AttributeType::PSI:
361         return effect_monster_psi(player_ptr, em_ptr);
362     case AttributeType::PSI_DRAIN:
363         return effect_monster_psi_drain(player_ptr, em_ptr);
364     case AttributeType::TELEKINESIS:
365         return effect_monster_telekinesis(player_ptr, em_ptr);
366     case AttributeType::DOMINATION:
367         return effect_monster_domination(player_ptr, em_ptr);
368     case AttributeType::ICE:
369         return effect_monster_icee_bolt(player_ptr, em_ptr);
370     case AttributeType::HYPODYNAMIA:
371         return effect_monster_hypodynamia(player_ptr, em_ptr);
372     case AttributeType::DEATH_RAY:
373         return effect_monster_death_ray(player_ptr, em_ptr);
374     case AttributeType::OLD_POLY:
375         return effect_monster_old_poly(em_ptr);
376     case AttributeType::OLD_CLONE:
377         return effect_monster_old_clone(player_ptr, em_ptr);
378     case AttributeType::STAR_HEAL:
379         return effect_monster_star_heal(player_ptr, em_ptr);
380     case AttributeType::OLD_HEAL:
381         return effect_monster_old_heal(player_ptr, em_ptr);
382     case AttributeType::OLD_SPEED:
383         return effect_monster_old_speed(player_ptr, em_ptr);
384     case AttributeType::OLD_SLOW:
385         return effect_monster_old_slow(player_ptr, em_ptr);
386     case AttributeType::OLD_SLEEP:
387         return effect_monster_old_sleep(player_ptr, em_ptr);
388     case AttributeType::STASIS_EVIL:
389         return effect_monster_stasis(em_ptr, true);
390     case AttributeType::STASIS:
391         return effect_monster_stasis(em_ptr, false);
392     case AttributeType::CHARM:
393         return effect_monster_charm(player_ptr, em_ptr);
394     case AttributeType::CONTROL_UNDEAD:
395         return effect_monster_control_undead(player_ptr, em_ptr);
396     case AttributeType::CONTROL_DEMON:
397         return effect_monster_control_demon(player_ptr, em_ptr);
398     case AttributeType::CONTROL_ANIMAL:
399         return effect_monster_control_animal(player_ptr, em_ptr);
400     case AttributeType::CHARM_LIVING:
401         return effect_monster_charm_living(player_ptr, em_ptr);
402     case AttributeType::OLD_CONF:
403         return effect_monster_old_conf(player_ptr, em_ptr);
404     case AttributeType::STUN:
405         return effect_monster_stun(em_ptr);
406     case AttributeType::LITE_WEAK:
407         return effect_monster_lite_weak(player_ptr, em_ptr);
408     case AttributeType::LITE:
409         return effect_monster_lite(player_ptr, em_ptr);
410     case AttributeType::DARK:
411         return effect_monster_dark(player_ptr, em_ptr);
412     case AttributeType::KILL_WALL:
413         return effect_monster_kill_wall(player_ptr, em_ptr);
414     case AttributeType::AWAY_UNDEAD:
415         return effect_monster_away_undead(player_ptr, em_ptr);
416     case AttributeType::AWAY_EVIL:
417         return effect_monster_away_evil(player_ptr, em_ptr);
418     case AttributeType::AWAY_ALL:
419         return effect_monster_away_all(player_ptr, em_ptr);
420     case AttributeType::TURN_UNDEAD:
421         return effect_monster_turn_undead(player_ptr, em_ptr);
422     case AttributeType::TURN_EVIL:
423         return effect_monster_turn_evil(player_ptr, em_ptr);
424     case AttributeType::TURN_ALL:
425         return effect_monster_turn_all(em_ptr);
426     case AttributeType::DISP_UNDEAD:
427         return effect_monster_disp_undead(player_ptr, em_ptr);
428     case AttributeType::DISP_EVIL:
429         return effect_monster_disp_evil(player_ptr, em_ptr);
430     case AttributeType::DISP_GOOD:
431         return effect_monster_disp_good(player_ptr, em_ptr);
432     case AttributeType::DISP_LIVING:
433         return effect_monster_disp_living(em_ptr);
434     case AttributeType::DISP_DEMON:
435         return effect_monster_disp_demon(player_ptr, em_ptr);
436     case AttributeType::DISP_ALL:
437         return effect_monster_disp_all(em_ptr);
438     case AttributeType::DRAIN_MANA:
439         return effect_monster_drain_mana(player_ptr, em_ptr);
440     case AttributeType::MIND_BLAST:
441         return effect_monster_mind_blast(player_ptr, em_ptr);
442     case AttributeType::BRAIN_SMASH:
443         return effect_monster_brain_smash(player_ptr, em_ptr);
444     case AttributeType::CAUSE_1:
445         return effect_monster_curse_1(em_ptr);
446     case AttributeType::CAUSE_2:
447         return effect_monster_curse_2(em_ptr);
448     case AttributeType::CAUSE_3:
449         return effect_monster_curse_3(em_ptr);
450     case AttributeType::CAUSE_4:
451         return effect_monster_curse_4(em_ptr);
452     case AttributeType::HAND_DOOM:
453         return effect_monster_hand_doom(em_ptr);
454     case AttributeType::CAPTURE:
455         return effect_monster_capture(player_ptr, em_ptr, cap_mon_ptr);
456     case AttributeType::ATTACK:
457         return do_cmd_attack(player_ptr, em_ptr->y, em_ptr->x, i2enum<combat_options>(em_ptr->dam)) ? PROCESS_TRUE : PROCESS_FALSE;
458     case AttributeType::ENGETSU:
459         return effect_monster_engetsu(player_ptr, em_ptr);
460     case AttributeType::GENOCIDE:
461         return effect_monster_genocide(player_ptr, em_ptr);
462     case AttributeType::PHOTO:
463         return effect_monster_photo(player_ptr, em_ptr);
464     case AttributeType::CRUSADE:
465         return effect_monster_crusade(player_ptr, em_ptr);
466     case AttributeType::WOUNDS:
467         return effect_monster_wounds(em_ptr);
468     case AttributeType::E_GENOCIDE:
469         return effect_monster_elemental_genocide(player_ptr, em_ptr);
470     case AttributeType::VOID_MAGIC:
471         return effect_monster_void(player_ptr, em_ptr);
472     case AttributeType::ABYSS:
473         return effect_monster_abyss(player_ptr, em_ptr);
474     default: {
475         em_ptr->skipped = true;
476         em_ptr->dam = 0;
477         return PROCESS_CONTINUE;
478     }
479     }
480 }