2 * 本ファイル内の行数はまともなレベルに落ち着いているので、一旦ここに留め置くこととする
3 * @brief 魔法種別による各種処理切り替え
6 * @todo どうしても「その他」に分類せざるを得ない魔法種別が残った
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"
40 process_result effect_monster_hypodynamia(PlayerType *player_ptr, effect_monster_type *em_ptr)
43 em_ptr->obvious = true;
45 if (monster_living(em_ptr->m_ptr->r_idx)) {
46 em_ptr->do_time = (em_ptr->dam + 7) / 8;
47 return PROCESS_CONTINUE;
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);
59 em_ptr->note = _("には効果がなかった。", " is unaffected.");
60 em_ptr->obvious = false;
62 return PROCESS_CONTINUE;
66 * @todo リファクタリング前のコード時点で、単に耐性があるだけでもダメージ0だった.
68 process_result effect_monster_death_ray(PlayerType *player_ptr, effect_monster_type *em_ptr)
71 em_ptr->obvious = true;
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);
83 em_ptr->note = _("には完全な耐性がある!", " is immune.");
84 em_ptr->obvious = false;
86 return PROCESS_CONTINUE;
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);
93 em_ptr->note = _("には耐性がある!", " resists!");
94 em_ptr->obvious = false;
98 return PROCESS_CONTINUE;
101 process_result effect_monster_kill_wall(PlayerType *player_ptr, effect_monster_type *em_ptr)
103 if ((em_ptr->r_ptr->flags3 & (RF3_HURT_ROCK)) == 0) {
105 return PROCESS_CONTINUE;
109 em_ptr->obvious = true;
111 if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
112 em_ptr->r_ptr->r_flags3 |= (RF3_HURT_ROCK);
114 em_ptr->note = _("の皮膚がただれた!", " loses some skin!");
115 em_ptr->note_dies = _("はドロドロに溶けた!", " dissolves!");
116 return PROCESS_CONTINUE;
119 process_result effect_monster_hand_doom(effect_monster_type *em_ptr)
122 em_ptr->obvious = true;
124 if (em_ptr->r_ptr->kind_flags.has(MonsterKindType::UNIQUE)) {
125 em_ptr->note = _("には効果がなかった。", " is unaffected.");
127 return PROCESS_CONTINUE;
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;
136 em_ptr->note = _("は破滅の手に耐え切った!", "resists!");
140 return PROCESS_CONTINUE;
144 * @brief 剣術「幻惑」の効果をモンスターに与える
145 * @param player_ptr プレイヤーの情報へのポインタ
146 * @param effect_monster_type モンスターの効果情報へのポインタ
148 * 精神のないモンスター、寝ているモンスターには無効。
153 process_result effect_monster_engetsu(PlayerType *player_ptr, effect_monster_type *em_ptr)
156 em_ptr->obvious = true;
158 if (any_bits(em_ptr->r_ptr->flags2, RF2_EMPTY_MIND)) {
159 em_ptr->note = _("には効果がなかった。", " is unaffected.");
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;
167 if (monster_csleep_remaining(em_ptr->m_ptr)) {
168 em_ptr->note = _("には効果がなかった。", " is unaffected.");
170 em_ptr->skipped = true;
171 return PROCESS_CONTINUE;
175 for (int i = 0; i < 3; i++) {
179 int power = 10 + randint1((em_ptr->dam - 10) < 1 ? 1 : (em_ptr->dam - 10));
180 if (em_ptr->r_ptr->level > power)
183 switch (randint0(4)) {
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.");
193 if (em_ptr->r_ptr->kind_flags.has(MonsterKindType::UNIQUE)) {
196 em_ptr->do_stun = damroll((player_ptr->lev / 10) + 3, (em_ptr->dam)) + 1;
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);
208 /* Go to sleep (much) later */
209 em_ptr->note = _("は混乱したようだ。", " looks confused.");
210 em_ptr->do_conf = 10 + randint1(15);
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);
220 em_ptr->do_sleep = 0;
222 /* Go to sleep (much) later */
223 em_ptr->note = _("は眠り込んでしまった!", " falls asleep!");
224 em_ptr->do_sleep = 500;
230 if (em_ptr->do_sleep > 0)
235 em_ptr->note = _("には効果がなかった。", " is unaffected.");
236 em_ptr->obvious = false;
240 return PROCESS_CONTINUE;
243 process_result effect_monster_genocide(PlayerType *player_ptr, effect_monster_type *em_ptr)
246 em_ptr->obvious = true;
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);
256 em_ptr->skipped = true;
257 return PROCESS_CONTINUE;
260 process_result effect_monster_photo(PlayerType *player_ptr, effect_monster_type *em_ptr)
263 msg_format(_("%sを写真に撮った。", "You take a photograph of %s."), em_ptr->m_name);
265 if (em_ptr->r_ptr->flags3 & (RF3_HURT_LITE)) {
267 em_ptr->obvious = true;
269 if (is_original_ap_and_seen(player_ptr, em_ptr->m_ptr))
270 em_ptr->r_ptr->r_flags3 |= (RF3_HURT_LITE);
272 em_ptr->note = _("は光に身をすくめた!", " cringes from the light!");
273 em_ptr->note_dies = _("は光を受けてしぼんでしまった!", " shrivels away in the light!");
278 em_ptr->photo = em_ptr->m_ptr->r_idx;
279 return PROCESS_CONTINUE;
282 process_result effect_monster_wounds(effect_monster_type *em_ptr)
285 em_ptr->obvious = true;
287 if (randint0(100 + em_ptr->dam) < (em_ptr->r_ptr->level + 50)) {
288 em_ptr->note = _("には効果がなかった。", " is unaffected.");
292 return PROCESS_CONTINUE;
296 * @brief 魔法の効果によって様々なメッセーを出力したり与えるダメージの増減を行ったりする
297 * @param em_ptr モンスター効果構造体への参照ポインタ
298 * @return ここのスイッチングで終るならTRUEかFALSE、後続処理を実行するならCONTINUE
300 process_result switch_effects_monster(PlayerType *player_ptr, effect_monster_type *em_ptr, CapturedMonsterType *cap_mon_ptr)
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);
475 em_ptr->skipped = true;
477 return PROCESS_CONTINUE;