OSDN Git Service

[Refactor] Grid::has_monster()の定義
[hengbandforosx/hengbandosx.git] / src / monster-floor / monster-move.cpp
index cbe4435..c486fed 100644 (file)
@@ -1,4 +1,4 @@
-/*!
+/*!
  * @brief モンスターの移動に関する処理
  * @date 2020/03/08
  * @author Hourier
@@ -6,7 +6,6 @@
 
 #include "monster-floor/monster-move.h"
 #include "core/disturbance.h"
-#include "core/player-update-types.h"
 #include "core/speed-table.h"
 #include "core/window-redrawer.h"
 #include "effect/attribute-types.h"
 #include "monster-attack/monster-attack-processor.h"
 #include "monster-floor/monster-object.h"
 #include "monster-race/monster-race.h"
-#include "monster-race/race-flags1.h"
-#include "monster-race/race-flags2.h"
-#include "monster-race/race-flags7.h"
-#include "monster-race/race-flags8.h"
 #include "monster-race/race-indice-types.h"
 #include "monster/monster-describer.h"
 #include "monster/monster-flag-types.h"
 #include "monster/monster-update.h"
 #include "pet/pet-util.h"
 #include "player/player-status-flags.h"
+#include "system/angband-system.h"
 #include "system/floor-type-definition.h"
 #include "system/grid-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 "system/terrain-type-definition.h"
 #include "target/projection-path-calculator.h"
 #include "util/bit-flags-calculator.h"
 #include "view/display-messages.h"
 
-static bool check_hp_for_feat_destruction(TerrainType *f_ptr, MonsterEntity *m_ptr)
+static bool check_hp_for_terrain_destruction(const TerrainType &terrain, const MonsterEntity &monster)
 {
-    return f_ptr->flags.has_not(TerrainCharacteristics::GLASS) || monraces_info[m_ptr->r_idx].behavior_flags.has(MonsterBehaviorType::STUPID) || (m_ptr->hp >= std::max(m_ptr->maxhp / 3, 200));
+    auto can_destroy = terrain.flags.has_not(TerrainCharacteristics::GLASS);
+    can_destroy |= monster.get_monrace().behavior_flags.has(MonsterBehaviorType::STUPID);
+    can_destroy |= monster.hp >= std::max(monster.maxhp / 3, 200);
+    return can_destroy;
 }
 
 /*!
  * @brief モンスターによる壁の透過・破壊を行う
  * @param player_ptr プレイヤーへの参照ポインタ
- * @param m_ptr モンスターへの参照ポインタ
- * @param ny モンスターのY座標
- * @param nx モンスターのX座標
+ * @param monster モンスターへの参照
+ * @param pos モンスターの移動先座標
  * @param can_cross モンスターが地形を踏破できるならばTRUE
  * @return 透過も破壊もしなかった場合はFALSE、それ以外はTRUE
  */
-static bool process_wall(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MonsterEntity *m_ptr, POSITION ny, POSITION nx, bool can_cross)
+static bool process_wall(PlayerType *player_ptr, turn_flags *turn_flags_ptr, const MonsterEntity &monster, const Pos2D &pos, bool can_cross)
 {
-    auto *r_ptr = &monraces_info[m_ptr->r_idx];
-    grid_type *g_ptr;
-    g_ptr = &player_ptr->current_floor_ptr->grid_array[ny][nx];
-    TerrainType *f_ptr;
-    f_ptr = &terrains_info[g_ptr->feat];
-    if (player_bold(player_ptr, ny, nx)) {
+    const auto &grid = player_ptr->current_floor_ptr->get_grid(pos);
+    const auto &terrain = grid.get_terrain();
+    if (player_ptr->is_located_at(pos)) {
         turn_flags_ptr->do_move = true;
         return true;
     }
 
-    if (g_ptr->m_idx > 0) {
+    if (grid.has_monster()) {
         turn_flags_ptr->do_move = true;
         return true;
     }
 
-    if (r_ptr->feature_flags.has(MonsterFeatureType::KILL_WALL) && (can_cross ? f_ptr->flags.has_not(TerrainCharacteristics::LOS) : !turn_flags_ptr->is_riding_mon) && f_ptr->flags.has(TerrainCharacteristics::HURT_DISI) && f_ptr->flags.has_not(TerrainCharacteristics::PERMANENT) && check_hp_for_feat_destruction(f_ptr, m_ptr)) {
+    using Mft = MonsterFeatureType;
+    using Tc = TerrainCharacteristics;
+    const auto &monrace = monster.get_monrace();
+    auto can_kill_wall = monrace.feature_flags.has(Mft::KILL_WALL);
+    can_kill_wall &= can_cross ? terrain.flags.has_not(Tc::LOS) : !turn_flags_ptr->is_riding_mon;
+    can_kill_wall &= terrain.flags.has(Tc::HURT_DISI);
+    can_kill_wall &= terrain.flags.has_not(Tc::PERMANENT);
+    can_kill_wall &= check_hp_for_terrain_destruction(terrain, monster);
+    if (can_kill_wall) {
         turn_flags_ptr->do_move = true;
         if (!can_cross) {
             turn_flags_ptr->must_alter_to_move = true;
@@ -90,7 +94,7 @@ static bool process_wall(PlayerType *player_ptr, turn_flags *turn_flags_ptr, Mon
     }
 
     turn_flags_ptr->do_move = true;
-    if ((r_ptr->feature_flags.has(MonsterFeatureType::PASS_WALL)) && (!turn_flags_ptr->is_riding_mon || has_pass_wall(player_ptr)) && f_ptr->flags.has(TerrainCharacteristics::CAN_PASS)) {
+    if ((monrace.feature_flags.has(Mft::PASS_WALL)) && (!turn_flags_ptr->is_riding_mon || has_pass_wall(player_ptr)) && terrain.flags.has(Tc::CAN_PASS)) {
         turn_flags_ptr->did_pass_wall = true;
     }
 
@@ -101,31 +105,33 @@ static bool process_wall(PlayerType *player_ptr, turn_flags *turn_flags_ptr, Mon
  * @brief モンスターが普通のドアを開ける処理
  * @param player_ptr プレイヤーへの参照ポインタ
  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
- * @param m_ptr モンスターへの参照ポインタ
- * @param ny モンスターのY座標
- * @param nx ã\83¢ã\83³ã\82¹ã\82¿ã\83¼ã\81®X座æ¨\99
- * @return ここではドアを開けず、ガラスのドアを開ける可能性があるならTRUE
+ * @param monster モンスターへの参照
+ * @param pos モンスターの移動先座標
+ * @return ã\83\89ã\82¢ã\82\92æ\89\93ã\81¡ç ´ã\82\8bã\81ªã\82\89ã\81\93ã\81\93ã\81§ã\81®å\87¦ç\90\86ã\81¯å®\9fè¡\8cã\81\9bã\81\9atrueã\80\81é\96\8bã\81\91ã\82\8bã\81 ã\81\91ã\81ªã\82\89é\96\8bã\81\91ã\81¦falseã\82\92è¿\94ã\81\99
+ * @todo 関数名と処理内容が不一致、後で直す
  */
-static bool bash_normal_door(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MonsterEntity *m_ptr, POSITION ny, POSITION nx)
+static bool bash_normal_door(PlayerType *player_ptr, turn_flags *turn_flags_ptr, const MonsterEntity &monster, const Pos2D &pos)
 {
-    auto *r_ptr = &monraces_info[m_ptr->r_idx];
-    grid_type *g_ptr;
-    g_ptr = &player_ptr->current_floor_ptr->grid_array[ny][nx];
-    TerrainType *f_ptr;
-    f_ptr = &terrains_info[g_ptr->feat];
+    const auto &monrace = monster.get_monrace();
+    const auto &grid = player_ptr->current_floor_ptr->get_grid(pos);
+    const auto &terrain = grid.get_terrain();
     turn_flags_ptr->do_move = false;
-    if ((r_ptr->behavior_flags.has_not(MonsterBehaviorType::OPEN_DOOR)) || f_ptr->flags.has_not(TerrainCharacteristics::OPEN) || (m_ptr->is_pet() && ((player_ptr->pet_extra_flags & PF_OPEN_DOORS) == 0))) {
+    using Tc = TerrainCharacteristics;
+    auto can_bash = monrace.behavior_flags.has_not(MonsterBehaviorType::OPEN_DOOR);
+    can_bash |= terrain.flags.has_not(Tc::OPEN);
+    can_bash |= monster.is_pet() && ((player_ptr->pet_extra_flags & PF_OPEN_DOORS) == 0);
+    if (can_bash) {
         return true;
     }
 
-    if (f_ptr->power == 0) {
+    if (terrain.power == 0) {
         turn_flags_ptr->did_open_door = true;
         turn_flags_ptr->do_turn = true;
         return false;
     }
 
-    if (randint0(m_ptr->hp / 10) > f_ptr->power) {
-        cave_alter_feat(player_ptr, ny, nx, TerrainCharacteristics::DISARM);
+    if (randint0(monster.hp / 10) > terrain.power) {
+        cave_alter_feat(player_ptr, pos.y, pos.x, Tc::DISARM);
         turn_flags_ptr->do_turn = true;
         return false;
     }
@@ -137,22 +143,27 @@ static bool bash_normal_door(PlayerType *player_ptr, turn_flags *turn_flags_ptr,
  * @brief モンスターがガラスのドアを開ける処理
  * @param player_ptr プレイヤーへの参照ポインタ
  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
- * @param m_ptr モンスターへの参照ポインタ
- * @param g_ptr グリッドへの参照ポインタ
- * @param f_ptr 地形への参照ポインタ
+ * @param monster モンスターへの参照
+ * @param terrain 地形への参照
+ * @param may_bash ドアを打ち破るならtrue、開けるだけならfalse
+ * @todo 関数名と処理内容が不一致、後で直す
  */
-static void bash_glass_door(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MonsterEntity *m_ptr, TerrainType *f_ptr, bool may_bash)
+static void bash_glass_door(PlayerType *player_ptr, turn_flags *turn_flags_ptr, const MonsterEntity &monster, const TerrainType &terrain, bool may_bash)
 {
-    auto *r_ptr = &monraces_info[m_ptr->r_idx];
-    if (!may_bash || (r_ptr->behavior_flags.has_not(MonsterBehaviorType::BASH_DOOR)) || f_ptr->flags.has_not(TerrainCharacteristics::BASH) || (m_ptr->is_pet() && ((player_ptr->pet_extra_flags & PF_OPEN_DOORS) == 0))) {
+    const auto &monrace = monster.get_monrace();
+    auto can_bash = may_bash;
+    can_bash &= monrace.behavior_flags.has(MonsterBehaviorType::BASH_DOOR);
+    can_bash &= terrain.flags.has(TerrainCharacteristics::BASH);
+    can_bash &= !monster.is_pet() || any_bits(player_ptr->pet_extra_flags, PF_OPEN_DOORS);
+    if (!can_bash) {
         return;
     }
 
-    if (!check_hp_for_feat_destruction(f_ptr, m_ptr) || (randint0(m_ptr->hp / 10) <= f_ptr->power)) {
+    if (!check_hp_for_terrain_destruction(terrain, monster) || (randint0(monster.hp / 10) <= terrain.power)) {
         return;
     }
 
-    if (f_ptr->flags.has(TerrainCharacteristics::GLASS)) {
+    if (terrain.flags.has(TerrainCharacteristics::GLASS)) {
         msg_print(_("ガラスが砕ける音がした!", "You hear glass breaking!"));
     } else {
         msg_print(_("ドアを叩き開ける音がした!", "You hear a door burst open!"));
@@ -171,40 +182,44 @@ static void bash_glass_door(PlayerType *player_ptr, turn_flags *turn_flags_ptr,
  * @brief モンスターによるドアの開放・破壊を行う
  * @param player_ptr プレイヤーへの参照ポインタ
  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
- * @param m_ptr モンスターへの参照ポインタ
- * @param ny モンスターのY座標
- * @param nx モンスターのX座標
+ * @param monster モンスターへの参照
+ * @param pos モンスターの移動先座標
  * @return モンスターが死亡した場合のみFALSE
  */
-static bool process_door(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MonsterEntity *m_ptr, POSITION ny, POSITION nx)
+static bool process_door(PlayerType *player_ptr, turn_flags *turn_flags_ptr, const MonsterEntity &monster, const Pos2D &pos)
 {
-    auto *r_ptr = &monraces_info[m_ptr->r_idx];
-    const auto &g_ref = player_ptr->current_floor_ptr->grid_array[ny][nx];
-    if (!is_closed_door(player_ptr, g_ref.feat)) {
+    auto &monrace = monster.get_monrace();
+    const auto &grid = player_ptr->current_floor_ptr->get_grid(pos);
+    if (!is_closed_door(player_ptr, grid.feat)) {
         return true;
     }
 
-    auto *terrain_ptr = &terrains_info[g_ref.feat];
-    auto may_bash = bash_normal_door(player_ptr, turn_flags_ptr, m_ptr, ny, nx);
-    bash_glass_door(player_ptr, turn_flags_ptr, m_ptr, terrain_ptr, may_bash);
+    auto &terrain = grid.get_terrain();
+    auto may_bash = bash_normal_door(player_ptr, turn_flags_ptr, monster, pos);
+    bash_glass_door(player_ptr, turn_flags_ptr, monster, terrain, may_bash);
     if (!turn_flags_ptr->did_open_door && !turn_flags_ptr->did_bash_door) {
         return true;
     }
 
-    const auto is_open = feat_state(player_ptr->current_floor_ptr, g_ref.feat, TerrainCharacteristics::OPEN) == g_ref.feat;
-    if (turn_flags_ptr->did_bash_door && ((randint0(100) < 50) || is_open || terrain_ptr->flags.has(TerrainCharacteristics::GLASS))) {
-        cave_alter_feat(player_ptr, ny, nx, TerrainCharacteristics::BASH);
-        if (!m_ptr->is_valid()) {
-            player_ptr->update |= (PU_FLOW);
-            player_ptr->window_flags |= (PW_OVERHEAD | PW_DUNGEON);
-            if (is_original_ap_and_seen(player_ptr, m_ptr)) {
-                r_ptr->r_behavior_flags.set(MonsterBehaviorType::BASH_DOOR);
+    const auto is_open = feat_state(player_ptr->current_floor_ptr, grid.feat, TerrainCharacteristics::OPEN) == grid.feat;
+    if (turn_flags_ptr->did_bash_door && ((randint0(100) < 50) || is_open || terrain.flags.has(TerrainCharacteristics::GLASS))) {
+        cave_alter_feat(player_ptr, pos.y, pos.x, TerrainCharacteristics::BASH);
+        if (!monster.is_valid()) {
+            auto &rfu = RedrawingFlagsUpdater::get_instance();
+            rfu.set_flag(StatusRecalculatingFlag::FLOW);
+            static constexpr auto flags = {
+                SubWindowRedrawingFlag::OVERHEAD,
+                SubWindowRedrawingFlag::DUNGEON,
+            };
+            rfu.set_flags(flags);
+            if (is_original_ap_and_seen(player_ptr, &monster)) {
+                monrace.r_behavior_flags.set(MonsterBehaviorType::BASH_DOOR);
             }
 
             return false;
         }
     } else {
-        cave_alter_feat(player_ptr, ny, nx, TerrainCharacteristics::OPEN);
+        cave_alter_feat(player_ptr, pos.y, pos.x, TerrainCharacteristics::OPEN);
     }
 
     turn_flags_ptr->do_view = true;
@@ -216,33 +231,34 @@ static bool process_door(PlayerType *player_ptr, turn_flags *turn_flags_ptr, Mon
  * @param player_ptr プレイヤーへの参照ポインタ
  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
  * @param m_ptr モンスターへの参照ポインタ
- * @param ny モンスターのY座標
- * @param nx モンスターのX座標
- * @return ルーンのある/なし
+ * @param pos モンスターの移動先座標
+ * @return ルーンに侵入できるか否か
  */
-static bool process_protection_rune(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MonsterEntity *m_ptr, POSITION ny, POSITION nx)
+static bool process_protection_rune(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MonsterEntity *m_ptr, const Pos2D &pos)
 {
-    grid_type *g_ptr;
-    g_ptr = &player_ptr->current_floor_ptr->grid_array[ny][nx];
-    auto *r_ptr = &monraces_info[m_ptr->r_idx];
-    if (!turn_flags_ptr->do_move || !g_ptr->is_rune_protection() || ((r_ptr->behavior_flags.has(MonsterBehaviorType::NEVER_BLOW)) && player_bold(player_ptr, ny, nx))) {
+    auto &grid = player_ptr->current_floor_ptr->get_grid(pos);
+    const auto &monrace = m_ptr->get_monrace();
+    auto can_enter = turn_flags_ptr->do_move;
+    can_enter &= grid.is_rune_protection();
+    can_enter &= (monrace.behavior_flags.has_not(MonsterBehaviorType::NEVER_BLOW)) || !player_ptr->is_located_at(pos);
+    if (!can_enter) {
         return false;
     }
 
     turn_flags_ptr->do_move = false;
-    if (m_ptr->is_pet() || (randint1(BREAK_RUNE_PROTECTION) >= r_ptr->level)) {
+    if (m_ptr->is_pet() || (randint1(BREAK_RUNE_PROTECTION) >= monrace.level)) {
         return true;
     }
 
-    if (g_ptr->is_mark()) {
+    if (grid.is_mark()) {
         msg_print(_("守りのルーンが壊れた!", "The rune of protection is broken!"));
     }
 
-    g_ptr->info &= ~(CAVE_MARK);
-    g_ptr->info &= ~(CAVE_OBJECT);
-    g_ptr->mimic = 0;
+    grid.info &= ~(CAVE_MARK);
+    grid.info &= ~(CAVE_OBJECT);
+    grid.mimic = 0;
     turn_flags_ptr->do_move = true;
-    note_spot(player_ptr, ny, nx);
+    note_spot(player_ptr, pos.y, pos.x);
     return true;
 }
 
@@ -251,16 +267,17 @@ static bool process_protection_rune(PlayerType *player_ptr, turn_flags *turn_fla
  * @param player_ptr プレイヤーへの参照ポインタ
  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
  * @param m_ptr モンスターへの参照ポインタ
- * @param ny モンスターのY座標
- * @param nx モンスターのX座標
+ * @param pos モンスターの移動先座標
  * @return モンスターが死亡した場合のみFALSE
  */
-static bool process_explosive_rune(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MonsterEntity *m_ptr, POSITION ny, POSITION nx)
+static bool process_explosive_rune(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MonsterEntity *m_ptr, const Pos2D &pos)
 {
-    grid_type *g_ptr;
-    g_ptr = &player_ptr->current_floor_ptr->grid_array[ny][nx];
-    auto *r_ptr = &monraces_info[m_ptr->r_idx];
-    if (!turn_flags_ptr->do_move || !g_ptr->is_rune_explosion() || ((r_ptr->behavior_flags.has(MonsterBehaviorType::NEVER_BLOW)) && player_bold(player_ptr, ny, nx))) {
+    auto &grid = player_ptr->current_floor_ptr->get_grid(pos);
+    const auto &monrace = m_ptr->get_monrace();
+    auto should_explode = turn_flags_ptr->do_move;
+    should_explode &= grid.is_rune_explosion();
+    should_explode &= (monrace.behavior_flags.has_not(MonsterBehaviorType::NEVER_BLOW)) || !player_ptr->is_located_at(pos);
+    if (!should_explode) {
         return true;
     }
 
@@ -269,22 +286,22 @@ static bool process_explosive_rune(PlayerType *player_ptr, turn_flags *turn_flag
         return true;
     }
 
-    if (randint1(BREAK_RUNE_EXPLOSION) > r_ptr->level) {
-        if (g_ptr->info & CAVE_MARK) {
+    if (randint1(BREAK_RUNE_EXPLOSION) > monrace.level) {
+        if (grid.info & CAVE_MARK) {
             msg_print(_("ルーンが爆発した!", "The rune explodes!"));
             BIT_FLAGS project_flags = PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP | PROJECT_NO_HANGEKI;
-            project(player_ptr, 0, 2, ny, nx, 2 * (player_ptr->lev + damroll(7, 7)), AttributeType::MANA, project_flags);
+            project(player_ptr, 0, 2, pos.y, pos.x, 2 * (player_ptr->lev + damroll(7, 7)), AttributeType::MANA, project_flags);
         }
     } else {
         msg_print(_("爆発のルーンは解除された。", "An explosive rune was disarmed."));
     }
 
-    g_ptr->info &= ~(CAVE_MARK);
-    g_ptr->info &= ~(CAVE_OBJECT);
-    g_ptr->mimic = 0;
+    grid.info &= ~(CAVE_MARK);
+    grid.info &= ~(CAVE_OBJECT);
+    grid.mimic = 0;
 
-    note_spot(player_ptr, ny, nx);
-    lite_spot(player_ptr, ny, nx);
+    note_spot(player_ptr, pos.y, pos.x);
+    lite_spot(player_ptr, pos.y, pos.x);
 
     if (!m_ptr->is_valid()) {
         return false;
@@ -298,44 +315,45 @@ static bool process_explosive_rune(PlayerType *player_ptr, turn_flags *turn_flag
  * @brief モンスターが壁を掘った後続処理を実行する
  * @param player_ptr プレイヤーへの参照ポインタ
  * @turn_flags_ptr ターン経過処理フラグへの参照ポインタ
- * @param m_ptr モンスターへの参照ポインタ
- * @param ny モンスターのY座標
- * @param nx モンスターのX座標
+ * @param monster モンスターへの参照
+ * @param pos モンスターの移動先座標
  * @return モンスターが死亡した場合のみFALSE
  */
-static bool process_post_dig_wall(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MonsterEntity *m_ptr, POSITION ny, POSITION nx)
+static bool process_post_dig_wall(PlayerType *player_ptr, turn_flags *turn_flags_ptr, const MonsterEntity &monster, const Pos2D &pos)
 {
-    auto *r_ptr = &monraces_info[m_ptr->r_idx];
-    grid_type *g_ptr;
-    g_ptr = &player_ptr->current_floor_ptr->grid_array[ny][nx];
-    TerrainType *f_ptr;
-    f_ptr = &terrains_info[g_ptr->feat];
+    auto &monrace = monster.get_monrace();
+    const auto &grid = player_ptr->current_floor_ptr->get_grid(pos);
+    const auto &terrain = grid.get_terrain();
     if (!turn_flags_ptr->did_kill_wall || !turn_flags_ptr->do_move) {
         return true;
     }
 
     constexpr auto chance_sound = 20;
     if (one_in_(chance_sound)) {
-        if (f_ptr->flags.has(TerrainCharacteristics::GLASS)) {
+        if (terrain.flags.has(TerrainCharacteristics::GLASS)) {
             msg_print(_("何かの砕ける音が聞こえる。", "There is a crashing sound."));
         } else {
             msg_print(_("ギシギシいう音が聞こえる。", "There is a grinding sound."));
         }
     }
 
-    cave_alter_feat(player_ptr, ny, nx, TerrainCharacteristics::HURT_DISI);
+    cave_alter_feat(player_ptr, pos.y, pos.x, TerrainCharacteristics::HURT_DISI);
 
-    if (!m_ptr->is_valid()) {
-        player_ptr->update |= (PU_FLOW);
-        player_ptr->window_flags |= (PW_OVERHEAD | PW_DUNGEON);
-        if (is_original_ap_and_seen(player_ptr, m_ptr)) {
-            r_ptr->r_feature_flags.set(MonsterFeatureType::KILL_WALL);
+    if (!monster.is_valid()) {
+        auto &rfu = RedrawingFlagsUpdater::get_instance();
+        rfu.set_flag(StatusRecalculatingFlag::FLOW);
+        static constexpr auto flags = {
+            SubWindowRedrawingFlag::OVERHEAD,
+            SubWindowRedrawingFlag::DUNGEON,
+        };
+        rfu.set_flags(flags);
+        if (is_original_ap_and_seen(player_ptr, &monster)) {
+            monrace.r_feature_flags.set(MonsterFeatureType::KILL_WALL);
         }
 
         return false;
     }
 
-    f_ptr = &terrains_info[g_ptr->feat];
     turn_flags_ptr->do_view = true;
     turn_flags_ptr->do_turn = true;
     return true;
@@ -347,13 +365,12 @@ static bool process_post_dig_wall(PlayerType *player_ptr, turn_flags *turn_flags
  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
  * @param m_idx モンスターID
  * @param mm モンスターの移動方向
- * @param oy 移動前の、モンスターのY座標
- * @param ox 移動前の、モンスターのX座標
+ * @param pos モンスターの移動前座標
  * @param count 移動回数 (のはず todo)
  * @return 移動が阻害される何か (ドア等)があったらFALSE
  * @todo 少し長いが、これといってブロックとしてまとまった部分もないので暫定でこのままとする
  */
-bool process_monster_movement(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx, DIRECTION *mm, POSITION oy, POSITION ox, int *count)
+bool process_monster_movement(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx, DIRECTION *mm, const Pos2D &pos, int *count)
 {
     for (int i = 0; mm[i]; i++) {
         int d = mm[i];
@@ -361,48 +378,46 @@ bool process_monster_movement(PlayerType *player_ptr, turn_flags *turn_flags_ptr
             d = ddd[randint0(8)];
         }
 
-        POSITION ny = oy + ddy[d];
-        POSITION nx = ox + ddx[d];
-        if (!in_bounds2(player_ptr->current_floor_ptr, ny, nx)) {
+        const Pos2D pos_neighbor(pos.y + ddy[d], pos.x + ddx[d]);
+        if (!in_bounds2(player_ptr->current_floor_ptr, pos_neighbor.y, pos_neighbor.x)) {
             continue;
         }
 
-        grid_type *g_ptr;
-        g_ptr = &player_ptr->current_floor_ptr->grid_array[ny][nx];
-        auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
-        auto *r_ptr = &monraces_info[m_ptr->r_idx];
-        bool can_cross = monster_can_cross_terrain(player_ptr, g_ptr->feat, r_ptr, turn_flags_ptr->is_riding_mon ? CEM_RIDING : 0);
+        auto &grid = player_ptr->current_floor_ptr->get_grid(pos_neighbor);
+        auto &monster = player_ptr->current_floor_ptr->m_list[m_idx];
+        auto &monrace = monster.get_monrace();
+        bool can_cross = monster_can_cross_terrain(player_ptr, grid.feat, &monrace, turn_flags_ptr->is_riding_mon ? CEM_RIDING : 0);
 
-        if (!process_wall(player_ptr, turn_flags_ptr, m_ptr, ny, nx, can_cross)) {
-            if (!process_door(player_ptr, turn_flags_ptr, m_ptr, ny, nx)) {
+        if (!process_wall(player_ptr, turn_flags_ptr, monster, pos_neighbor, can_cross)) {
+            if (!process_door(player_ptr, turn_flags_ptr, monster, pos_neighbor)) {
                 return false;
             }
         }
 
-        if (!process_protection_rune(player_ptr, turn_flags_ptr, m_ptr, ny, nx)) {
-            if (!process_explosive_rune(player_ptr, turn_flags_ptr, m_ptr, ny, nx)) {
+        if (!process_protection_rune(player_ptr, turn_flags_ptr, &monster, pos_neighbor)) {
+            if (!process_explosive_rune(player_ptr, turn_flags_ptr, &monster, pos_neighbor)) {
                 return false;
             }
         }
 
-        exe_monster_attack_to_player(player_ptr, turn_flags_ptr, m_idx, ny, nx);
-        if (process_monster_attack_to_monster(player_ptr, turn_flags_ptr, m_idx, g_ptr, can_cross)) {
+        exe_monster_attack_to_player(player_ptr, turn_flags_ptr, m_idx, pos_neighbor);
+        if (process_monster_attack_to_monster(player_ptr, turn_flags_ptr, m_idx, &grid, can_cross)) {
             return false;
         }
 
         if (turn_flags_ptr->is_riding_mon) {
-            const auto &m_ref = player_ptr->current_floor_ptr->m_list[player_ptr->riding];
-            if (!player_ptr->riding_ryoute && !m_ref.is_fearful()) {
+            const auto &monster_riding = player_ptr->current_floor_ptr->m_list[player_ptr->riding];
+            if (!player_ptr->riding_ryoute && !monster_riding.is_fearful()) {
                 turn_flags_ptr->do_move = false;
             }
         }
 
-        if (!process_post_dig_wall(player_ptr, turn_flags_ptr, m_ptr, ny, nx)) {
+        if (!process_post_dig_wall(player_ptr, turn_flags_ptr, monster, pos_neighbor)) {
             return false;
         }
 
-        if (turn_flags_ptr->must_alter_to_move && r_ptr->feature_flags.has(MonsterFeatureType::AQUATIC)) {
-            if (!monster_can_cross_terrain(player_ptr, g_ptr->feat, r_ptr, turn_flags_ptr->is_riding_mon ? CEM_RIDING : 0)) {
+        if (turn_flags_ptr->must_alter_to_move && monrace.feature_flags.has(MonsterFeatureType::AQUATIC)) {
+            if (!monster_can_cross_terrain(player_ptr, grid.feat, &monrace, turn_flags_ptr->is_riding_mon ? CEM_RIDING : 0)) {
                 turn_flags_ptr->do_move = false;
             }
         }
@@ -411,9 +426,9 @@ bool process_monster_movement(PlayerType *player_ptr, turn_flags *turn_flags_ptr
             turn_flags_ptr->do_move = false;
         }
 
-        if (turn_flags_ptr->do_move && r_ptr->behavior_flags.has(MonsterBehaviorType::NEVER_MOVE)) {
-            if (is_original_ap_and_seen(player_ptr, m_ptr)) {
-                r_ptr->r_behavior_flags.set(MonsterBehaviorType::NEVER_MOVE);
+        if (turn_flags_ptr->do_move && monrace.behavior_flags.has(MonsterBehaviorType::NEVER_MOVE)) {
+            if (is_original_ap_and_seen(player_ptr, &monster)) {
+                monrace.r_behavior_flags.set(MonsterBehaviorType::NEVER_MOVE);
             }
 
             turn_flags_ptr->do_move = false;
@@ -428,35 +443,35 @@ bool process_monster_movement(PlayerType *player_ptr, turn_flags *turn_flags_ptr
         }
 
         turn_flags_ptr->do_turn = true;
-        const auto &terrain_ref = terrains_info[g_ptr->feat];
-        auto can_recover_energy = terrain_ref.flags.has(TerrainCharacteristics::TREE);
-        can_recover_energy &= r_ptr->feature_flags.has_not(MonsterFeatureType::CAN_FLY);
-        can_recover_energy &= r_ptr->wilderness_flags.has_not(MonsterWildernessType::WILD_WOOD);
+        const auto &terrain = grid.get_terrain();
+        auto can_recover_energy = terrain.flags.has(TerrainCharacteristics::TREE);
+        can_recover_energy &= monrace.feature_flags.has_not(MonsterFeatureType::CAN_FLY);
+        can_recover_energy &= monrace.wilderness_flags.has_not(MonsterWildernessType::WILD_WOOD);
         if (can_recover_energy) {
-            m_ptr->energy_need += ENERGY_NEED();
+            monster.energy_need += ENERGY_NEED();
         }
 
-        if (!update_riding_monster(player_ptr, turn_flags_ptr, m_idx, oy, ox, ny, nx)) {
+        if (!update_riding_monster(player_ptr, turn_flags_ptr, m_idx, pos.y, pos.x, pos_neighbor.y, pos_neighbor.x)) {
             break;
         }
 
-        const auto &ap_r_ref = monraces_info[m_ptr->ap_r_idx];
-        const auto is_projectable = projectable(player_ptr, player_ptr->y, player_ptr->x, m_ptr->fy, m_ptr->fx);
-        const auto can_see = disturb_near && m_ptr->mflag.has(MonsterTemporaryFlagType::VIEW) && is_projectable;
+        const auto &ap_r_ref = monster.get_appearance_monrace();
+        const auto is_projectable = projectable(player_ptr, player_ptr->y, player_ptr->x, monster.fy, monster.fx);
+        const auto can_see = disturb_near && monster.mflag.has(MonsterTemporaryFlagType::VIEW) && is_projectable;
         const auto is_high_level = disturb_high && (ap_r_ref.r_tkills > 0) && (ap_r_ref.level >= player_ptr->lev);
-        if (m_ptr->ml && (disturb_move || can_see || is_high_level)) {
-            if (m_ptr->is_hostile()) {
+        if (monster.ml && (disturb_move || can_see || is_high_level)) {
+            if (monster.is_hostile()) {
                 disturb(player_ptr, false, true);
             }
         }
 
-        bool is_takable_or_killable = !g_ptr->o_idx_list.empty();
-        is_takable_or_killable &= r_ptr->behavior_flags.has_any_of({ MonsterBehaviorType::TAKE_ITEM, MonsterBehaviorType::KILL_ITEM });
+        bool is_takable_or_killable = !grid.o_idx_list.empty();
+        is_takable_or_killable &= monrace.behavior_flags.has_any_of({ MonsterBehaviorType::TAKE_ITEM, MonsterBehaviorType::KILL_ITEM });
 
         bool is_pickup_items = (player_ptr->pet_extra_flags & PF_PICKUP_ITEMS) != 0;
-        is_pickup_items &= r_ptr->behavior_flags.has(MonsterBehaviorType::TAKE_ITEM);
+        is_pickup_items &= monrace.behavior_flags.has(MonsterBehaviorType::TAKE_ITEM);
 
-        is_takable_or_killable &= !m_ptr->is_pet() || is_pickup_items;
+        is_takable_or_killable &= !monster.is_pet() || is_pickup_items;
         if (!is_takable_or_killable) {
             if (turn_flags_ptr->do_turn) {
                 break;
@@ -465,7 +480,7 @@ bool process_monster_movement(PlayerType *player_ptr, turn_flags *turn_flags_ptr
             continue;
         }
 
-        update_object_by_monster_movement(player_ptr, turn_flags_ptr, m_idx, ny, nx);
+        update_object_by_monster_movement(player_ptr, turn_flags_ptr, m_idx, pos_neighbor.y, pos_neighbor.x);
         if (turn_flags_ptr->do_turn) {
             break;
         }
@@ -483,23 +498,23 @@ static bool can_speak(const MonsterRaceInfo &ap_r_ref, MonsterSpeakType mon_spea
     return can_speak_all || can_speak_specific;
 }
 
-static std::string_view get_speak_filename(MonsterEntity *m_ptr)
+static std::string_view get_speak_filename(const MonsterEntity &monster)
 {
-    const auto &ap_r_ref = monraces_info[m_ptr->ap_r_idx];
-    if (m_ptr->is_fearful() && can_speak(ap_r_ref, MonsterSpeakType::SPEAK_FEAR)) {
+    const auto &ap_monrace = monster.get_appearance_monrace();
+    if (monster.is_fearful() && can_speak(ap_monrace, MonsterSpeakType::SPEAK_FEAR)) {
         return _("monfear_j.txt", "monfear.txt");
     }
 
     constexpr auto monspeak_txt(_("monspeak_j.txt", "monspeak.txt"));
-    if (m_ptr->is_pet() && can_speak(ap_r_ref, MonsterSpeakType::SPEAK_BATTLE)) {
+    if (monster.is_pet() && can_speak(ap_monrace, MonsterSpeakType::SPEAK_BATTLE)) {
         return monspeak_txt;
     }
 
-    if (m_ptr->is_friendly() && can_speak(ap_r_ref, MonsterSpeakType::SPEAK_FRIEND)) {
+    if (monster.is_friendly() && can_speak(ap_monrace, MonsterSpeakType::SPEAK_FRIEND)) {
         return _("monfrien_j.txt", "monfrien.txt");
     }
 
-    if (can_speak(ap_r_ref, MonsterSpeakType::SPEAK_BATTLE)) {
+    if (can_speak(ap_monrace, MonsterSpeakType::SPEAK_BATTLE)) {
         return monspeak_txt;
     }
 
@@ -516,35 +531,35 @@ static std::string_view get_speak_filename(MonsterEntity *m_ptr)
  */
 void process_speak_sound(PlayerType *player_ptr, MONSTER_IDX m_idx, POSITION oy, POSITION ox, bool aware)
 {
-    if (player_ptr->phase_out) {
+    if (AngbandSystem::get_instance().is_phase_out()) {
         return;
     }
 
-    auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
+    const auto &floor = *player_ptr->current_floor_ptr;
+    const auto &monster = floor.m_list[m_idx];
     constexpr auto chance_noise = 20;
-    if (m_ptr->ap_r_idx == MonsterRaceId::CYBER && one_in_(chance_noise) && !m_ptr->ml && (m_ptr->cdis <= MAX_PLAYER_SIGHT)) {
+    if (monster.ap_r_idx == MonsterRaceId::CYBER && one_in_(chance_noise) && !monster.ml && (monster.cdis <= MAX_PLAYER_SIGHT)) {
         if (disturb_minor) {
             disturb(player_ptr, false, false);
         }
         msg_print(_("重厚な足音が聞こえた。", "You hear heavy steps."));
     }
 
-    auto can_speak = monraces_info[m_ptr->ap_r_idx].speak_flags.any();
+    const auto can_speak = monster.get_appearance_monrace().speak_flags.any();
     constexpr auto chance_speak = 8;
-    if (!can_speak || !aware || !one_in_(chance_speak) || !player_has_los_bold(player_ptr, oy, ox) || !projectable(player_ptr, oy, ox, player_ptr->y, player_ptr->x)) {
+    if (!can_speak || !aware || !one_in_(chance_speak) || !floor.has_los({ oy, ox }) || !projectable(player_ptr, oy, ox, player_ptr->y, player_ptr->x)) {
         return;
     }
 
-    const auto m_name = m_ptr->ml ? monster_desc(player_ptr, m_ptr, 0) : std::string(_("それ", "It"));
-    char monmessage[1024];
-
-    auto filename = get_speak_filename(m_ptr);
+    const auto m_name = monster.ml ? monster_desc(player_ptr, &monster, 0) : std::string(_("それ", "It"));
+    auto filename = get_speak_filename(monster);
     if (filename.empty()) {
         return;
     }
 
-    if (get_rnd_line(filename.data(), enum2i(m_ptr->ap_r_idx), monmessage) == 0) {
-        msg_format(_("%^s%s", "%^s %s"), m_name.data(), monmessage);
+    const auto monmessage = get_random_line(filename.data(), enum2i(monster.ap_r_idx));
+    if (monmessage) {
+        msg_format(_("%s^%s", "%s^ %s"), m_name.data(), monmessage->data());
     }
 }