OSDN Git Service

[Fix] 悪魔領域の血の呪いの追加効果発生場所が正しくない
[hengbandforosx/hengbandosx.git] / src / effect / effect-monster.cpp
index a5f9a08..725f97b 100644 (file)
@@ -1,4 +1,4 @@
-/*!
+/*!
  * @brief 魔法によるモンスターへの効果まとめ
  * @date 2020/04/29
  * @author Hourier
@@ -7,7 +7,6 @@
 #include "effect/effect-monster.h"
 #include "avatar/avatar.h"
 #include "core/disturbance.h"
-#include "core/player-redraw-types.h"
 #include "core/stuff-handler.h"
 #include "core/window-redrawer.h"
 #include "effect/attribute-types.h"
@@ -15,7 +14,6 @@
 #include "effect/effect-monster-switcher.h"
 #include "effect/effect-monster-util.h"
 #include "effect/spells-effect-util.h"
-#include "floor/cave.h"
 #include "floor/floor-object.h"
 #include "game-option/play-record-options.h"
 #include "grid/grid.h"
@@ -46,6 +44,7 @@
 #include "spell-kind/spells-polymorph.h"
 #include "spell-kind/spells-teleport.h"
 #include "sv-definition/sv-other-types.h"
+#include "system/angband-system.h"
 #include "system/baseitem-info.h"
 #include "system/floor-type-definition.h"
 #include "system/grid-type-definition.h"
@@ -53,6 +52,7 @@
 #include "system/monster-entity.h"
 #include "system/monster-race-info.h"
 #include "system/player-type-definition.h"
+#include "system/redrawing-flags-updater.h"
 #include "util/bit-flags-calculator.h"
 #include "util/string-processor.h"
 #include "view/display-messages.h"
@@ -64,7 +64,7 @@
  * @param em_ptr モンスター効果構造体への参照ポインタ
  * @return 効果が何もないならFALSE、何かあるならTRUE
  */
-static ProcessResult is_affective(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static ProcessResult is_affective(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
     if (!em_ptr->g_ptr->m_idx) {
         return ProcessResult::PROCESS_FALSE;
@@ -107,11 +107,11 @@ static ProcessResult is_affective(PlayerType *player_ptr, effect_monster_type *e
  * @param player_ptr プレイヤーへの参照ポインタ
  * @param em_ptr モンスター効果構造体への参照ポインタ
  */
-static void make_description_of_affecred_monster(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static void make_description_of_affecred_monster(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
     em_ptr->dam = (em_ptr->dam + em_ptr->r) / (em_ptr->r + 1);
-    angband_strcpy(em_ptr->m_name, monster_desc(player_ptr, em_ptr->m_ptr, 0).data(), sizeof(em_ptr->m_name));
-    angband_strcpy(em_ptr->m_poss, monster_desc(player_ptr, em_ptr->m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE).data(), sizeof(em_ptr->m_poss));
+    angband_strcpy(em_ptr->m_name, monster_desc(player_ptr, em_ptr->m_ptr, 0), sizeof(em_ptr->m_name));
+    angband_strcpy(em_ptr->m_poss, monster_desc(player_ptr, em_ptr->m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE), sizeof(em_ptr->m_poss));
 }
 
 /*!
@@ -123,7 +123,7 @@ static void make_description_of_affecred_monster(PlayerType *player_ptr, effect_
  * 完全な耐性を持っていたら、一部属性を除いて影響は及ぼさない
  * デバッグ属性、モンスター打撃、モンスター射撃であれば貫通する
  */
-static ProcessResult exe_affect_monster_by_effect(PlayerType *player_ptr, effect_monster_type *em_ptr, std::optional<CapturedMonsterType *> cap_mon_ptr)
+static ProcessResult exe_affect_monster_by_effect(PlayerType *player_ptr, EffectMonster *em_ptr, std::optional<CapturedMonsterType *> cap_mon_ptr)
 {
     const std::vector<AttributeType> effect_arrtibute = {
         AttributeType::OLD_CLONE,
@@ -179,13 +179,13 @@ static ProcessResult exe_affect_monster_by_effect(PlayerType *player_ptr, effect
  * @param player_ptr プレイヤーへの参照ポインタ
  * @param em_ptr モンスター効果構造体への参照ポインタ
  */
-static void effect_damage_killed_pet(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static void effect_damage_killed_pet(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
     bool sad = em_ptr->m_ptr->is_pet() && !(em_ptr->m_ptr->ml);
-    if (em_ptr->known && em_ptr->note) {
-        angband_strcpy(em_ptr->m_name, monster_desc(player_ptr, em_ptr->m_ptr, MD_TRUE_NAME).data(), sizeof(em_ptr->m_name));
+    if (em_ptr->known && !em_ptr->note.empty()) {
+        angband_strcpy(em_ptr->m_name, monster_desc(player_ptr, em_ptr->m_ptr, MD_TRUE_NAME), sizeof(em_ptr->m_name));
         if (em_ptr->see_s_msg) {
-            msg_format("%s^%s", em_ptr->m_name, em_ptr->note);
+            msg_format("%s^%s", em_ptr->m_name, em_ptr->note.data());
         } else {
             player_ptr->current_floor_ptr->monster_noise = true;
         }
@@ -207,10 +207,10 @@ static void effect_damage_killed_pet(PlayerType *player_ptr, effect_monster_type
  * @param player_ptr プレイヤーへの参照ポインタ
  * @param em_ptr モンスター効果構造体への参照ポインタ
  */
-static void effect_damage_makes_sleep(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static void effect_damage_makes_sleep(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
-    if (em_ptr->note && em_ptr->seen_msg) {
-        msg_format("%s^%s", em_ptr->m_name, em_ptr->note);
+    if (!em_ptr->note.empty() && em_ptr->seen_msg) {
+        msg_format("%s^%s", em_ptr->m_name, em_ptr->note.data());
     } else if (em_ptr->see_s_msg) {
         const auto pain_message = MonsterPainDescriber(player_ptr, em_ptr->g_ptr->m_idx).describe(em_ptr->dam);
         if (!pain_message.empty()) {
@@ -233,17 +233,19 @@ static void effect_damage_makes_sleep(PlayerType *player_ptr, effect_monster_typ
  * @details
  * モンスターIDがプレイヤー(0)の場合は処理しない。
  */
-static bool deal_effect_damage_from_monster(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static bool deal_effect_damage_from_monster(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
     if (em_ptr->who <= 0) {
         return false;
     }
 
+    auto &rfu = RedrawingFlagsUpdater::get_instance();
     if (player_ptr->health_who == em_ptr->g_ptr->m_idx) {
-        player_ptr->redraw |= (PR_HEALTH);
+        rfu.set_flag(MainWindowRedrawingFlag::HEALTH);
     }
+
     if (player_ptr->riding == em_ptr->g_ptr->m_idx) {
-        player_ptr->redraw |= (PR_UHEALTH);
+        rfu.set_flag(MainWindowRedrawingFlag::UHEALTH);
     }
 
     (void)set_monster_csleep(player_ptr, em_ptr->g_ptr->m_idx, 0);
@@ -263,7 +265,7 @@ static bool deal_effect_damage_from_monster(PlayerType *player_ptr, effect_monst
  * @param em_ptr モンスター効果構造体への参照ポインタ
  * @return 大賞モンスターが不潔な病人だった場合はTRUE、それ以外はFALSE
  */
-static bool heal_leaper(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static bool heal_leaper(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
     if (!em_ptr->heal_leper) {
         return false;
@@ -275,7 +277,7 @@ static bool heal_leaper(PlayerType *player_ptr, effect_monster_type *em_ptr)
 
     if (record_named_pet && em_ptr->m_ptr->is_named_pet()) {
         const auto m2_name = monster_desc(player_ptr, em_ptr->m_ptr, MD_INDEF_VISIBLE);
-        exe_write_diary(player_ptr, DIARY_NAMED_PET, RECORD_NAMED_PET_HEAL_LEPER, m2_name.data());
+        exe_write_diary(player_ptr, DiaryKind::NAMED_PET, RECORD_NAMED_PET_HEAL_LEPER, m2_name);
     }
 
     delete_monster_idx(player_ptr, em_ptr->g_ptr->m_idx);
@@ -290,7 +292,7 @@ static bool heal_leaper(PlayerType *player_ptr, effect_monster_type *em_ptr)
  * @details
  * em_ptr->do_fearによる恐怖メッセージもここで表示。
  */
-static bool deal_effect_damage_from_player(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static bool deal_effect_damage_from_player(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
     bool fear = false;
     MonsterDamageProcessor mdp(player_ptr, em_ptr->g_ptr->m_idx, em_ptr->dam, &fear, em_ptr->attribute);
@@ -302,8 +304,8 @@ static bool deal_effect_damage_from_player(PlayerType *player_ptr, effect_monste
         anger_monster(player_ptr, em_ptr->m_ptr);
     }
 
-    if (em_ptr->note && em_ptr->seen) {
-        msg_format(_("%s%s", "%s^%s"), em_ptr->m_name, em_ptr->note);
+    if (!em_ptr->note.empty() && em_ptr->seen) {
+        msg_format(_("%s%s", "%s^%s"), em_ptr->m_name, em_ptr->note.data());
     } else if (em_ptr->known && (em_ptr->dam || !em_ptr->do_fear)) {
         const auto pain_message = MonsterPainDescriber(player_ptr, em_ptr->g_ptr->m_idx).describe(em_ptr->dam);
         if (!pain_message.empty()) {
@@ -334,7 +336,7 @@ static bool deal_effect_damage_from_player(PlayerType *player_ptr, effect_monste
  * 3.プレイヤーによる効果ダメージの処理
  * 4.睡眠する処理
  */
-static void deal_effect_damage_to_monster(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static void deal_effect_damage_to_monster(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
     if (em_ptr->attribute == AttributeType::DRAIN_MANA) {
         return;
@@ -363,7 +365,7 @@ static void deal_effect_damage_to_monster(PlayerType *player_ptr, effect_monster
  * @param player_ptr プレイヤーへの参照ポインタ
  * @param em_ptr モンスター効果構造体への参照ポインタ
  */
-static void effect_makes_change_virtues(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static void effect_makes_change_virtues(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
     if ((em_ptr->who > 0) || !em_ptr->slept) {
         return;
@@ -382,7 +384,7 @@ static void effect_makes_change_virtues(PlayerType *player_ptr, effect_monster_t
  * @param player_ptr プレイヤーへの参照ポインタ
  * @param em_ptr モンスター効果構造体への参照ポインタ
  */
-static void affected_monster_prevents_bad_status(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static void affected_monster_prevents_bad_status(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
     const auto *r_ptr = em_ptr->r_ptr;
     auto can_avoid_polymorph = r_ptr->kind_flags.has(MonsterKindType::UNIQUE);
@@ -395,7 +397,7 @@ static void affected_monster_prevents_bad_status(PlayerType *player_ptr, effect_
     auto should_alive = r_ptr->kind_flags.has(MonsterKindType::UNIQUE);
     should_alive |= any_bits(r_ptr->flags1, RF1_QUESTOR);
     should_alive |= r_ptr->population_flags.has(MonsterPopulationType::NAZGUL);
-    if (should_alive && !player_ptr->phase_out && (em_ptr->who > 0) && (em_ptr->dam > em_ptr->m_ptr->hp)) {
+    if (should_alive && !AngbandSystem::get_instance().is_phase_out() && (em_ptr->who > 0) && (em_ptr->dam > em_ptr->m_ptr->hp)) {
         em_ptr->dam = em_ptr->m_ptr->hp;
     }
 }
@@ -406,12 +408,12 @@ static void affected_monster_prevents_bad_status(PlayerType *player_ptr, effect_
  * @param em_ptr モンスター効果構造体への参照ポインタ
  * @param stun_damage 朦朧値
  */
-static void effect_damage_piles_stun(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static void effect_damage_piles_stun(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
     const auto *r_ptr = em_ptr->r_ptr;
     auto can_avoid_stun = em_ptr->do_stun == 0;
     can_avoid_stun |= r_ptr->resistance_flags.has_any_of({ MonsterResistanceType::RESIST_SOUND, MonsterResistanceType::RESIST_FORCE });
-    can_avoid_stun |= any_bits(r_ptr->flags3, RF3_NO_STUN);
+    can_avoid_stun |= r_ptr->resistance_flags.has(MonsterResistanceType::NO_STUN);
     if (can_avoid_stun) {
         return;
     }
@@ -439,9 +441,9 @@ static void effect_damage_piles_stun(PlayerType *player_ptr, effect_monster_type
  * @param em_ptr モンスター効果構造体への参照ポインタ
  * @param stun_damage 混乱値
  */
-static void effect_damage_piles_confusion(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static void effect_damage_piles_confusion(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
-    if ((em_ptr->do_conf == 0) || (em_ptr->r_ptr->flags3 & RF3_NO_CONF) || em_ptr->r_ptr->resistance_flags.has_any_of(RFR_EFF_RESIST_CHAOS_MASK)) {
+    if ((em_ptr->do_conf == 0) || (em_ptr->r_ptr->resistance_flags.has(MonsterResistanceType::NO_CONF)) || em_ptr->r_ptr->resistance_flags.has_any_of(RFR_EFF_RESIST_CHAOS_MASK)) {
         return;
     }
 
@@ -470,9 +472,9 @@ static void effect_damage_piles_confusion(PlayerType *player_ptr, effect_monster
  * @details
  * 打撃ダメージによる恐怖もあるため、メッセージは後で表示。
  */
-static void effect_damage_piles_fear(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static void effect_damage_piles_fear(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
-    if (em_ptr->do_fear == 0 || any_bits(em_ptr->r_ptr->flags3, RF3_NO_FEAR)) {
+    if (em_ptr->do_fear == 0 || em_ptr->r_ptr->resistance_flags.has(MonsterResistanceType::NO_FEAR)) {
         return;
     }
 
@@ -484,7 +486,7 @@ static void effect_damage_piles_fear(PlayerType *player_ptr, effect_monster_type
  * @brief モンスターを衰弱させる
  * @param em_ptr モンスター効果構造体への参照ポインタ
  */
-static void effect_damage_makes_weak(effect_monster_type *em_ptr)
+static void effect_damage_makes_weak(EffectMonster *em_ptr)
 {
     if (em_ptr->do_time == 0) {
         return;
@@ -514,7 +516,7 @@ static void effect_damage_makes_weak(effect_monster_type *em_ptr)
  * @param player_ptr プレイヤーへの参照ポインタ
  * @param em_ptr モンスター効果構造体への参照ポインタ
  */
-static void effect_damage_makes_polymorph(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static void effect_damage_makes_polymorph(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
     if (!em_ptr->do_polymorph || (randint1(90) <= em_ptr->r_ptr->level)) {
         return;
@@ -530,7 +532,7 @@ static void effect_damage_makes_polymorph(PlayerType *player_ptr, effect_monster
     }
 
     em_ptr->m_ptr = &player_ptr->current_floor_ptr->m_list[em_ptr->g_ptr->m_idx];
-    em_ptr->r_ptr = &monraces_info[em_ptr->m_ptr->r_idx];
+    em_ptr->r_ptr = &em_ptr->m_ptr->get_monrace();
 }
 
 /*!
@@ -538,7 +540,7 @@ static void effect_damage_makes_polymorph(PlayerType *player_ptr, effect_monster
  * @param player_ptr プレイヤーへの参照ポインタ
  * @param em_ptr モンスター効果構造体への参照ポインタ
  */
-static void effect_damage_makes_teleport(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static void effect_damage_makes_teleport(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
     if (em_ptr->do_dist == 0) {
         return;
@@ -572,7 +574,7 @@ static void effect_damage_makes_teleport(PlayerType *player_ptr, effect_monster_
  * 2.ダメージ量が現HPを上回る場合
  * 3.通常時(デバフをかける)
  */
-static void effect_damage_gives_bad_status(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static void effect_damage_gives_bad_status(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
     int tmp_damage = em_ptr->dam;
     em_ptr->dam = mon_damage_mod(player_ptr, em_ptr->m_ptr, em_ptr->dam, (bool)(em_ptr->attribute == AttributeType::PSY_SPEAR));
@@ -604,14 +606,14 @@ static void effect_damage_gives_bad_status(PlayerType *player_ptr, effect_monste
  * 4.ダメージ処理及び恐怖メッセージ
  * 5.悪魔領域血の呪いによる事後処理
  */
-static void exe_affect_monster_by_damage(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static void exe_affect_monster_by_damage(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
     effect_makes_change_virtues(player_ptr, em_ptr);
     affected_monster_prevents_bad_status(player_ptr, em_ptr);
     effect_damage_gives_bad_status(player_ptr, em_ptr);
     deal_effect_damage_to_monster(player_ptr, em_ptr);
     if ((em_ptr->attribute == AttributeType::BLOOD_CURSE) && one_in_(4)) {
-        blood_curse_to_enemy(player_ptr, em_ptr->who);
+        blood_curse_to_enemy(player_ptr, em_ptr->g_ptr->m_idx);
     }
 }
 
@@ -620,14 +622,14 @@ static void exe_affect_monster_by_damage(PlayerType *player_ptr, effect_monster_
  * @param player_ptr プレイヤーへの参照ポインタ
  * @param em_ptr モンスター効果構造体への参照ポインタ
  */
-static void update_phase_out_stat(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static void update_phase_out_stat(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
-    if (!player_ptr->phase_out) {
+    if (!AngbandSystem::get_instance().is_phase_out()) {
         return;
     }
 
     player_ptr->health_who = em_ptr->g_ptr->m_idx;
-    player_ptr->redraw |= (PR_HEALTH);
+    RedrawingFlagsUpdater::get_instance().set_flag(MainWindowRedrawingFlag::HEALTH);
     handle_stuff(player_ptr);
 }
 
@@ -636,7 +638,7 @@ static void update_phase_out_stat(PlayerType *player_ptr, effect_monster_type *e
  * @param player_ptr プレイヤーへの参照ポインタ
  * @param em_ptr モンスター効果構造体への参照ポインタ
  */
-static void postprocess_by_effected_pet(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static void postprocess_by_effected_pet(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
     auto *m_ptr = em_ptr->m_ptr;
     if ((em_ptr->dam <= 0) || m_ptr->is_pet() || m_ptr->is_friendly()) {
@@ -652,7 +654,7 @@ static void postprocess_by_effected_pet(PlayerType *player_ptr, effect_monster_t
     }
 
     const auto &m_caster_ref = *em_ptr->m_caster_ptr;
-    if ((em_ptr->who > 0) && m_caster_ref.is_pet() && !player_bold(player_ptr, m_ptr->target_y, m_ptr->target_x)) {
+    if ((em_ptr->who > 0) && m_caster_ref.is_pet() && !player_ptr->is_located_at({ m_ptr->target_y, m_ptr->target_x })) {
         set_target(m_ptr, m_caster_ref.fy, m_caster_ref.fx);
     }
 }
@@ -662,7 +664,7 @@ static void postprocess_by_effected_pet(PlayerType *player_ptr, effect_monster_t
  * @param player_ptr プレイヤーへの参照ポインタ
  * @param em_ptr モンスター効果構造体への参照ポインタ
  */
-static void postprocess_by_riding_pet_effected(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static void postprocess_by_riding_pet_effected(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
     if (!player_ptr->riding || (player_ptr->riding != em_ptr->g_ptr->m_idx) || (em_ptr->dam <= 0)) {
         return;
@@ -681,7 +683,7 @@ static void postprocess_by_riding_pet_effected(PlayerType *player_ptr, effect_mo
  * @param em_ptr モンスター効果構造体への参照ポインタ
  * @details 写真のフラッシュは弱閃光属性
  */
-static void postprocess_by_taking_photo(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static void postprocess_by_taking_photo(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
     if (em_ptr->photo == 0) {
         return;
@@ -701,7 +703,7 @@ static void postprocess_by_taking_photo(PlayerType *player_ptr, effect_monster_t
  * @param player_ptr プレイヤーへの参照ポインタ
  * @param em_ptr モンスター効果構造体への参照ポインタ
  */
-static void exe_affect_monster_postprocess(PlayerType *player_ptr, effect_monster_type *em_ptr)
+static void exe_affect_monster_postprocess(PlayerType *player_ptr, EffectMonster *em_ptr)
 {
     postprocess_by_effected_pet(player_ptr, em_ptr);
     postprocess_by_riding_pet_effected(player_ptr, em_ptr);
@@ -733,8 +735,8 @@ bool affect_monster(
     PlayerType *player_ptr, MONSTER_IDX who, POSITION r, POSITION y, POSITION x, int dam, AttributeType attribute, BIT_FLAGS flag, bool see_s_msg,
     std::optional<CapturedMonsterType *> cap_mon_ptr)
 {
-    effect_monster_type tmp_effect;
-    effect_monster_type *em_ptr = initialize_effect_monster(player_ptr, &tmp_effect, who, r, y, x, dam, attribute, flag, see_s_msg);
+    EffectMonster tmp_effect(player_ptr, who, r, y, x, dam, attribute, flag, see_s_msg);
+    auto *em_ptr = &tmp_effect;
 
     make_description_of_affecred_monster(player_ptr, em_ptr);
 
@@ -761,7 +763,7 @@ bool affect_monster(
 
     lite_spot(player_ptr, em_ptr->y, em_ptr->x);
     if ((player_ptr->monster_race_idx == em_ptr->m_ptr->r_idx) && (em_ptr->seen || !monster_is_valid)) {
-        player_ptr->window_flags |= (PW_MONSTER_LORE);
+        RedrawingFlagsUpdater::get_instance().set_flag(SubWindowRedrawingFlag::MONSTER_LORE);
     }
 
     exe_affect_monster_postprocess(player_ptr, em_ptr);