OSDN Git Service

[Refactor] RIDING を新定義に合わせた
[hengbandforosx/hengbandosx.git] / src / monster / monster-processor.cpp
index 18cd9e9..83c6afe 100644 (file)
@@ -1,4 +1,4 @@
-/*!
+/*!
  * @brief モンスターの特殊技能とターン経過処理 (移動等)/ Monster spells and movement for passaging a turn
  * @date 2014/01/17
  * @author
@@ -15,7 +15,6 @@
 #include "monster/monster-processor.h"
 #include "avatar/avatar.h"
 #include "cmd-io/cmd-dump.h"
-#include "core/player-update-types.h"
 #include "core/speed-table.h"
 #include "floor/cave.h"
 #include "floor/geometry.h"
 #include "player/special-defense-types.h"
 #include "spell-realm/spells-hex.h"
 #include "spell/summon-types.h"
+#include "system/angband-system.h"
 #include "system/floor-type-definition.h"
 #include "system/grid-type-definition.h"
-#include "system/monster-race-definition.h"
-#include "system/monster-type-definition.h"
+#include "system/monster-entity.h"
+#include "system/monster-race-info.h"
 #include "system/player-type-definition.h"
+#include "system/redrawing-flags-updater.h"
 #include "target/projection-path-calculator.h"
 #include "view/display-messages.h"
 
@@ -81,7 +82,7 @@ bool cast_spell(PlayerType *player_ptr, MONSTER_IDX m_idx, bool aware);
 bool process_monster_fear(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx);
 
 void sweep_monster_process(PlayerType *player_ptr);
-bool decide_process_continue(PlayerType *player_ptr, monster_type *m_ptr);
+bool decide_process_continue(PlayerType *player_ptr, MonsterEntity *m_ptr);
 
 /*!
  * @brief モンスター単体の1ターン行動処理メインルーチン /
@@ -115,7 +116,7 @@ bool decide_process_continue(PlayerType *player_ptr, monster_type *m_ptr);
 void process_monster(PlayerType *player_ptr, MONSTER_IDX m_idx)
 {
     auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
-    auto *r_ptr = &r_info[m_ptr->r_idx];
+    auto *r_ptr = &m_ptr->get_monrace();
     turn_flags tmp_flags;
     turn_flags *turn_flags_ptr = init_turn_flags(player_ptr->riding, m_idx, &tmp_flags);
     turn_flags_ptr->see_m = is_seen(player_ptr, m_ptr);
@@ -123,11 +124,27 @@ void process_monster(PlayerType *player_ptr, MONSTER_IDX m_idx)
     decide_drop_from_monster(player_ptr, m_idx, turn_flags_ptr->is_riding_mon);
     if (m_ptr->mflag2.has(MonsterConstantFlagType::CHAMELEON) && one_in_(13) && !m_ptr->is_asleep()) {
         choose_new_monster(player_ptr, m_idx, false, MonsterRace::empty_id());
-        r_ptr = &r_info[m_ptr->r_idx];
+        r_ptr = &m_ptr->get_monrace();
     }
 
     turn_flags_ptr->aware = process_stealth(player_ptr, m_idx);
-    if (vanish_summoned_children(player_ptr, m_idx, turn_flags_ptr->see_m) || process_quantum_effect(player_ptr, m_idx, turn_flags_ptr->see_m) || explode_grenade(player_ptr, m_idx) || runaway_monster(player_ptr, turn_flags_ptr, m_idx) || !awake_monster(player_ptr, m_idx)) {
+    if (vanish_summoned_children(player_ptr, m_idx, turn_flags_ptr->see_m)) {
+        return;
+    }
+
+    if (process_quantum_effect(player_ptr, m_idx, turn_flags_ptr->see_m)) {
+        return;
+    }
+
+    if (explode_grenade(player_ptr, m_idx)) {
+        return;
+    }
+
+    if (runaway_monster(player_ptr, turn_flags_ptr, m_idx)) {
+        return;
+    }
+
+    if (!awake_monster(player_ptr, m_idx)) {
         return;
     }
 
@@ -136,7 +153,7 @@ void process_monster(PlayerType *player_ptr, MONSTER_IDX m_idx)
     }
 
     if (turn_flags_ptr->is_riding_mon) {
-        player_ptr->update |= PU_BONUS;
+        RedrawingFlagsUpdater::get_instance().set_flag(StatusRecalculatingFlag::BONUS);
     }
 
     process_angar(player_ptr, m_idx, turn_flags_ptr->see_m);
@@ -162,7 +179,7 @@ void process_monster(PlayerType *player_ptr, MONSTER_IDX m_idx)
     }
 
     int count = 0;
-    if (!process_monster_movement(player_ptr, turn_flags_ptr, m_idx, mm, oy, ox, &count)) {
+    if (!process_monster_movement(player_ptr, turn_flags_ptr, m_idx, mm, { oy, ox }, &count)) {
         return;
     }
 
@@ -174,7 +191,7 @@ void process_monster(PlayerType *player_ptr, MONSTER_IDX m_idx)
         m_ptr->mflag2.reset(MonsterConstantFlagType::NOFLOW);
     }
 
-    if (!turn_flags_ptr->do_turn && !turn_flags_ptr->do_move && !monster_fear_remaining(m_ptr) && !turn_flags_ptr->is_riding_mon && turn_flags_ptr->aware) {
+    if (!turn_flags_ptr->do_turn && !turn_flags_ptr->do_move && !m_ptr->is_fearful() && !turn_flags_ptr->is_riding_mon && turn_flags_ptr->aware) {
         if (r_ptr->freq_spell && randint1(100) <= r_ptr->freq_spell) {
             if (make_attack_spell(player_ptr, m_idx)) {
                 return;
@@ -182,7 +199,8 @@ void process_monster(PlayerType *player_ptr, MONSTER_IDX m_idx)
         }
     }
 
-    update_player_type(player_ptr, turn_flags_ptr, r_ptr);
+    update_map_flags(turn_flags_ptr);
+    update_lite_flags(turn_flags_ptr, r_ptr);
     update_monster_race_flags(player_ptr, turn_flags_ptr, m_ptr);
 
     if (!process_monster_fear(player_ptr, turn_flags_ptr, m_idx)) {
@@ -190,7 +208,7 @@ void process_monster(PlayerType *player_ptr, MONSTER_IDX m_idx)
     }
 
     if (m_ptr->ml) {
-        chg_virtue(player_ptr, V_COMPASSION, -1);
+        chg_virtue(player_ptr, Virtue::COMPASSION, -1);
     }
 }
 
@@ -208,7 +226,7 @@ bool process_stealth(PlayerType *player_ptr, MONSTER_IDX m_idx)
     }
 
     auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
-    auto *r_ptr = &r_info[m_ptr->r_idx];
+    auto *r_ptr = &m_ptr->get_monrace();
     int tmp = player_ptr->lev * 6 + (player_ptr->skill_stl + 10) * 4;
     if (player_ptr->monlite) {
         tmp /= 3;
@@ -234,8 +252,8 @@ bool process_stealth(PlayerType *player_ptr, MONSTER_IDX m_idx)
 void decide_drop_from_monster(PlayerType *player_ptr, MONSTER_IDX m_idx, bool is_riding_mon)
 {
     auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
-    auto *r_ptr = &r_info[m_ptr->r_idx];
-    if (!is_riding_mon || ((r_ptr->flags7 & RF7_RIDING) != 0)) {
+    auto *r_ptr = &m_ptr->get_monrace();
+    if (!is_riding_mon || r_ptr->misc_flags.has(MonsterMiscType::RIDING)) {
         return;
     }
 
@@ -243,9 +261,8 @@ void decide_drop_from_monster(PlayerType *player_ptr, MONSTER_IDX m_idx, bool is
 #ifdef JP
         msg_print("地面に落とされた。");
 #else
-        GAME_TEXT m_name[MAX_NLEN];
-        monster_desc(player_ptr, m_name, &player_ptr->current_floor_ptr->m_list[player_ptr->riding], 0);
-        msg_format("You have fallen from %s.", m_name);
+        const auto m_name = monster_desc(player_ptr, &player_ptr->current_floor_ptr->m_list[player_ptr->riding], 0);
+        msg_format("You have fallen from %s.", m_name.data());
 #endif
     }
 }
@@ -271,15 +288,13 @@ bool vanish_summoned_children(PlayerType *player_ptr, MONSTER_IDX m_idx, bool se
     }
 
     if (see_m) {
-        GAME_TEXT m_name[MAX_NLEN];
-        monster_desc(player_ptr, m_name, m_ptr, 0);
-        msg_format(_("%sは消え去った!", "%^s disappears!"), m_name);
+        const auto m_name = monster_desc(player_ptr, m_ptr, 0);
+        msg_format(_("%sは消え去った!", "%s^ disappears!"), m_name.data());
     }
 
-    if (record_named_pet && m_ptr->is_pet() && m_ptr->nickname) {
-        GAME_TEXT m_name[MAX_NLEN];
-        monster_desc(player_ptr, m_name, m_ptr, MD_INDEF_VISIBLE);
-        exe_write_diary(player_ptr, DIARY_NAMED_PET, RECORD_NAMED_PET_LOSE_PARENT, m_name);
+    if (record_named_pet && m_ptr->is_named_pet()) {
+        const auto m_name = monster_desc(player_ptr, m_ptr, MD_INDEF_VISIBLE);
+        exe_write_diary(player_ptr, DiaryKind::NAMED_PET, RECORD_NAMED_PET_LOSE_PARENT, m_name);
     }
 
     delete_monster_idx(player_ptr, m_idx);
@@ -295,7 +310,7 @@ bool vanish_summoned_children(PlayerType *player_ptr, MONSTER_IDX m_idx, bool se
 bool awake_monster(PlayerType *player_ptr, MONSTER_IDX m_idx)
 {
     auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
-    auto *r_ptr = &r_info[m_ptr->r_idx];
+    auto *r_ptr = &m_ptr->get_monrace();
     if (!m_ptr->is_asleep()) {
         return true;
     }
@@ -306,9 +321,8 @@ bool awake_monster(PlayerType *player_ptr, MONSTER_IDX m_idx)
 
     (void)set_monster_csleep(player_ptr, m_idx, 0);
     if (m_ptr->ml) {
-        GAME_TEXT m_name[MAX_NLEN];
-        monster_desc(player_ptr, m_name, m_ptr, 0);
-        msg_format(_("%^sが目を覚ました。", "%^s wakes up."), m_name);
+        const auto m_name = monster_desc(player_ptr, m_ptr, 0);
+        msg_format(_("%s^が目を覚ました。", "%s^ wakes up."), m_name.data());
     }
 
     if (is_original_ap_and_seen(player_ptr, m_ptr) && (r_ptr->r_wake < MAX_UCHAR)) {
@@ -326,23 +340,22 @@ bool awake_monster(PlayerType *player_ptr, MONSTER_IDX m_idx)
  */
 void process_angar(PlayerType *player_ptr, MONSTER_IDX m_idx, bool see_m)
 {
-    auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
-    auto *r_ptr = &r_info[m_ptr->r_idx];
-    bool gets_angry = false;
-    if (m_ptr->is_friendly() && has_aggravate(player_ptr)) {
+    auto &monster = player_ptr->current_floor_ptr->m_list[m_idx];
+    const auto &monrace = monster.get_monrace();
+    auto gets_angry = monster.is_friendly() && has_aggravate(player_ptr);
+    const auto should_aggravate = monster.is_pet();
+    auto has_hostile = monrace.kind_flags.has(MonsterKindType::UNIQUE) || (monrace.population_flags.has(MonsterPopulationType::NAZGUL));
+    has_hostile &= monster_has_hostile_align(player_ptr, nullptr, 10, -10, &monrace);
+    const auto has_resist_all = monrace.resistance_flags.has(MonsterResistanceType::RESIST_ALL);
+    if (should_aggravate && (has_hostile || has_resist_all)) {
         gets_angry = true;
     }
 
-    if (m_ptr->is_pet() && (((r_ptr->kind_flags.has(MonsterKindType::UNIQUE) || (r_ptr->population_flags.has(MonsterPopulationType::NAZGUL))) && monster_has_hostile_align(player_ptr, nullptr, 10, -10, r_ptr)) || r_ptr->resistance_flags.has(MonsterResistanceType::RESIST_ALL))) {
-        gets_angry = true;
-    }
-
-    if (player_ptr->phase_out || !gets_angry) {
+    if (AngbandSystem::get_instance().is_phase_out() || !gets_angry) {
         return;
     }
 
-    GAME_TEXT m_name[MAX_NLEN];
-    monster_desc(player_ptr, m_name, m_ptr, m_ptr->is_pet() ? MD_ASSUME_VISIBLE : 0);
+    const auto m_name = monster_desc(player_ptr, &monster, monster.is_pet() ? MD_ASSUME_VISIBLE : 0);
 
     /* When riding a hostile alignment pet */
     if (player_ptr->riding == m_idx) {
@@ -350,7 +363,7 @@ void process_angar(PlayerType *player_ptr, MONSTER_IDX m_idx, bool see_m)
             return;
         }
 
-        msg_format(_("%^sが突然暴れだした!", "%^s suddenly begins unruly!"), m_name);
+        msg_format(_("%s^が突然暴れだした!", "%s^ suddenly begins unruly!"), m_name.data());
         if (!process_fall_off_horse(player_ptr, 1, true)) {
             return;
         }
@@ -358,11 +371,11 @@ void process_angar(PlayerType *player_ptr, MONSTER_IDX m_idx, bool see_m)
         msg_format(_("あなたは振り落とされた。", "You have fallen."));
     }
 
-    if (m_ptr->is_pet() || see_m) {
-        msg_format(_("%^sは突然敵にまわった!", "%^s suddenly becomes hostile!"), m_name);
+    if (monster.is_pet() || see_m) {
+        msg_format(_("%s^は突然敵にまわった!", "%s^ suddenly becomes hostile!"), m_name.data());
     }
 
-    set_hostile(player_ptr, m_ptr);
+    monster.set_hostile();
 }
 
 /*!
@@ -391,8 +404,14 @@ bool explode_grenade(PlayerType *player_ptr, MONSTER_IDX m_idx)
 void process_special(PlayerType *player_ptr, MONSTER_IDX m_idx)
 {
     auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
-    auto *r_ptr = &r_info[m_ptr->r_idx];
-    if (r_ptr->ability_flags.has_not(MonsterAbilityType::SPECIAL) || (m_ptr->r_idx != MonsterRaceId::OHMU) || player_ptr->current_floor_ptr->inside_arena || player_ptr->phase_out || (r_ptr->freq_spell == 0) || (randint1(100) > r_ptr->freq_spell)) {
+    auto *r_ptr = &m_ptr->get_monrace();
+    auto can_do_special = r_ptr->ability_flags.has(MonsterAbilityType::SPECIAL);
+    can_do_special &= m_ptr->r_idx == MonsterRaceId::OHMU;
+    can_do_special &= !player_ptr->current_floor_ptr->inside_arena;
+    can_do_special &= !AngbandSystem::get_instance().is_phase_out();
+    can_do_special &= r_ptr->freq_spell != 0;
+    can_do_special &= randint1(100) <= r_ptr->freq_spell;
+    if (!can_do_special) {
         return;
     }
 
@@ -424,8 +443,8 @@ void process_special(PlayerType *player_ptr, MONSTER_IDX m_idx)
 bool decide_monster_multiplication(PlayerType *player_ptr, MONSTER_IDX m_idx, POSITION oy, POSITION ox)
 {
     auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
-    auto *r_ptr = &r_info[m_ptr->r_idx];
-    if (((r_ptr->flags2 & RF2_MULTIPLY) == 0) || (player_ptr->current_floor_ptr->num_repro >= MAX_REPRO)) {
+    auto *r_ptr = &m_ptr->get_monrace();
+    if (((r_ptr->flags2 & RF2_MULTIPLY) == 0) || (player_ptr->current_floor_ptr->num_repro >= MAX_REPRODUCTION)) {
         return false;
     }
 
@@ -446,7 +465,8 @@ bool decide_monster_multiplication(PlayerType *player_ptr, MONSTER_IDX m_idx, PO
         k = 8;
     }
 
-    if ((k < 4) && (!k || !randint0(k * MON_MULT_ADJ))) {
+    constexpr auto chance_reproduction = 8;
+    if ((k < 4) && (!k || !randint0(k * chance_reproduction))) {
         if (multiply_monster(player_ptr, m_idx, false, (m_ptr->is_pet() ? PM_FORCE_PET : 0))) {
             if (player_ptr->current_floor_ptr->m_list[hack_m_idx_ii].ml && is_original_ap_and_seen(player_ptr, m_ptr)) {
                 r_ptr->r_flags2 |= RF2_MULTIPLY;
@@ -468,18 +488,20 @@ bool decide_monster_multiplication(PlayerType *player_ptr, MONSTER_IDX m_idx, PO
  */
 bool cast_spell(PlayerType *player_ptr, MONSTER_IDX m_idx, bool aware)
 {
-    auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
-    auto *r_ptr = &r_info[m_ptr->r_idx];
-    if ((r_ptr->freq_spell == 0) || (randint1(100) > r_ptr->freq_spell)) {
+    auto &floor = *player_ptr->current_floor_ptr;
+    const auto &monster_from = floor.m_list[m_idx];
+    const auto &monrace = monster_from.get_monrace();
+    if ((monrace.freq_spell == 0) || (randint1(100) > monrace.freq_spell)) {
         return false;
     }
 
     bool counterattack = false;
-    if (m_ptr->target_y) {
-        MONSTER_IDX t_m_idx = player_ptr->current_floor_ptr->grid_array[m_ptr->target_y][m_ptr->target_x].m_idx;
-        const auto &target_ref = player_ptr->current_floor_ptr->m_list[t_m_idx];
-        const auto is_projectable = projectable(player_ptr, m_ptr->fy, m_ptr->fx, m_ptr->target_y, m_ptr->target_x);
-        if (t_m_idx && are_enemies(player_ptr, *m_ptr, target_ref) && is_projectable) {
+    if (monster_from.target_y) {
+        Pos2D pos(monster_from.target_y, monster_from.target_x);
+        const auto t_m_idx = floor.get_grid(pos).m_idx;
+        const auto &monster_to = floor.m_list[t_m_idx];
+        const auto is_projectable = projectable(player_ptr, monster_from.fy, monster_from.fx, monster_from.target_y, monster_from.target_x);
+        if (t_m_idx && monster_from.is_hostile_to_melee(monster_to) && is_projectable) {
             counterattack = true;
         }
     }
@@ -508,7 +530,7 @@ bool cast_spell(PlayerType *player_ptr, MONSTER_IDX m_idx, bool aware)
 bool process_monster_fear(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx)
 {
     auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
-    bool is_battle_determined = !turn_flags_ptr->do_turn && !turn_flags_ptr->do_move && monster_fear_remaining(m_ptr) && turn_flags_ptr->aware;
+    bool is_battle_determined = !turn_flags_ptr->do_turn && !turn_flags_ptr->do_move && m_ptr->is_fearful() && turn_flags_ptr->aware;
     if (!is_battle_determined) {
         return false;
     }
@@ -518,9 +540,8 @@ bool process_monster_fear(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MO
         return true;
     }
 
-    GAME_TEXT m_name[MAX_NLEN];
-    monster_desc(player_ptr, m_name, m_ptr, 0);
-    msg_format(_("%^sは戦いを決意した!", "%^s turns to fight!"), m_name);
+    const auto m_name = monster_desc(player_ptr, m_ptr, 0);
+    msg_format(_("%s^は戦いを決意した!", "%s^ turns to fight!"), m_name.data());
     return true;
 }
 
@@ -559,14 +580,13 @@ bool process_monster_fear(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MO
  */
 void process_monsters(PlayerType *player_ptr)
 {
-    old_race_flags tmp_flags;
-    old_race_flags *old_race_flags_ptr = init_old_race_flags(&tmp_flags);
+    const auto old_monrace_id = player_ptr->monster_race_idx;
+    old_race_flags tmp_flags(old_monrace_id);
+    old_race_flags *old_race_flags_ptr = &tmp_flags;
     player_ptr->current_floor_ptr->monster_noise = false;
-    MonsterRaceId old_monster_race_idx = player_ptr->monster_race_idx;
-    save_old_race_flags(player_ptr->monster_race_idx, old_race_flags_ptr);
     sweep_monster_process(player_ptr);
     hack_m_idx = 0;
-    if (!MonsterRace(player_ptr->monster_race_idx).is_valid() || (player_ptr->monster_race_idx != old_monster_race_idx)) {
+    if (!MonsterRace(player_ptr->monster_race_idx).is_valid() || (player_ptr->monster_race_idx != old_monrace_id)) {
         return;
     }
 
@@ -581,7 +601,7 @@ void sweep_monster_process(PlayerType *player_ptr)
 {
     auto *floor_ptr = player_ptr->current_floor_ptr;
     for (MONSTER_IDX i = floor_ptr->m_max - 1; i >= 1; i--) {
-        monster_type *m_ptr;
+        MonsterEntity *m_ptr;
         m_ptr = &floor_ptr->m_list[i];
 
         if (player_ptr->leaving) {
@@ -597,11 +617,11 @@ void sweep_monster_process(PlayerType *player_ptr)
             continue;
         }
 
-        if ((m_ptr->cdis >= AAF_LIMIT) || !decide_process_continue(player_ptr, m_ptr)) {
+        if ((m_ptr->cdis >= MAX_MONSTER_SENSING) || !decide_process_continue(player_ptr, m_ptr)) {
             continue;
         }
 
-        byte speed = (player_ptr->riding == i) ? player_ptr->pspeed : decide_monster_speed(m_ptr);
+        byte speed = (player_ptr->riding == i) ? player_ptr->pspeed : m_ptr->get_temporary_speed();
         m_ptr->energy_need -= speed_to_energy(speed);
         if (m_ptr->energy_need > 0) {
             continue;
@@ -627,19 +647,20 @@ void sweep_monster_process(PlayerType *player_ptr)
  * @param m_ptr モンスターへの参照ポインタ
  * @return 後続処理が必要ならTRUE
  */
-bool decide_process_continue(PlayerType *player_ptr, monster_type *m_ptr)
+bool decide_process_continue(PlayerType *player_ptr, MonsterEntity *m_ptr)
 {
-    monster_race *r_ptr;
-    r_ptr = &r_info[m_ptr->r_idx];
+    const auto &monrace = m_ptr->get_monrace();
     if (!player_ptr->no_flowed) {
         m_ptr->mflag2.reset(MonsterConstantFlagType::NOFLOW);
     }
 
-    if (m_ptr->cdis <= (m_ptr->is_pet() ? (r_ptr->aaf > MAX_SIGHT ? MAX_SIGHT : r_ptr->aaf) : r_ptr->aaf)) {
+    if (m_ptr->cdis <= (m_ptr->is_pet() ? (monrace.aaf > MAX_PLAYER_SIGHT ? MAX_PLAYER_SIGHT : monrace.aaf) : monrace.aaf)) {
         return true;
     }
 
-    if ((m_ptr->cdis <= MAX_SIGHT || player_ptr->phase_out) && (player_has_los_bold(player_ptr, m_ptr->fy, m_ptr->fx) || has_aggravate(player_ptr))) {
+    auto should_continue = (m_ptr->cdis <= MAX_PLAYER_SIGHT) || AngbandSystem::get_instance().is_phase_out();
+    should_continue &= player_ptr->current_floor_ptr->has_los({ m_ptr->fy, m_ptr->fx }) || has_aggravate(player_ptr);
+    if (should_continue) {
         return true;
     }