OSDN Git Service

[Refactor] #3650 Grid::get_feat_mimic() から地形特性を得ていた箇所をget_terrain_mimic() に置換した
[hengbandforosx/hengbandosx.git] / src / action / run-execution.cpp
index 789d583..ac8a6cc 100644 (file)
@@ -1,4 +1,4 @@
-/*!
+/*!
  * @file run-execution.cpp
  * @brief プレイヤーの走行処理実装
  */
@@ -10,7 +10,6 @@
 #include "floor/floor-util.h"
 #include "floor/geometry.h"
 #include "game-option/disturbance-options.h"
-#include "grid/feature.h"
 #include "grid/grid.h"
 #include "main/sound-definitions-table.h"
 #include "main/sound-of-music.h"
 #include "player/player-status.h"
 #include "system/floor-type-definition.h"
 #include "system/grid-type-definition.h"
-#include "system/monster-type-definition.h"
-#include "system/object-type-definition.h"
+#include "system/item-entity.h"
+#include "system/monster-entity.h"
 #include "system/player-type-definition.h"
+#include "system/terrain-type-definition.h"
 #include "util/bit-flags-calculator.h"
 #include "view/display-messages.h"
 
@@ -49,35 +49,38 @@ static bool find_breakleft;
 /*!
  * @brief ダッシュ移動処理中、移動先のマスが既知の壁かどうかを判定する /
  * Hack -- Check for a "known wall" (see below)
- * @param creature_ptr プレーヤーへの参照ポインタ
+ * @param player_ptr   プレイヤーへの参照ポインタ
  * @param dir 想定する移動方向ID
  * @param y 移動元のY座標
  * @param x 移動元のX座標
  * @return 移動先が既知の壁ならばTRUE
  */
-static bool see_wall(player_type *creature_ptr, DIRECTION dir, POSITION y, POSITION x)
+static bool see_wall(PlayerType *player_ptr, DIRECTION dir, POSITION y, POSITION x)
 {
-    y += ddy[dir];
-    x += ddx[dir];
-    floor_type *floor_ptr = creature_ptr->current_floor_ptr;
-    if (!in_bounds2(floor_ptr, y, x))
+    auto *floor_ptr = player_ptr->current_floor_ptr;
+    const Pos2D pos(y + ddy[dir], x + ddx[dir]);
+    if (!in_bounds2(floor_ptr, pos.y, pos.x)) {
         return false;
+    }
 
-    grid_type *g_ptr;
-    g_ptr = &floor_ptr->grid_array[y][x];
-    if (!g_ptr->is_mark())
+    const auto &grid = floor_ptr->get_grid(pos);
+    if (!grid.is_mark()) {
         return false;
+    }
 
-    s16b feat = g_ptr->get_feat_mimic();
-    feature_type *f_ptr = &f_info[feat];
-    if (!player_can_enter(creature_ptr, feat, 0))
-        return !has_flag(f_ptr->flags, FF_DOOR);
+    const auto terrain_id = grid.get_feat_mimic();
+    const auto &terrain = grid.get_terrain_mimic();
+    if (!player_can_enter(player_ptr, terrain_id, 0)) {
+        return terrain.flags.has_not(TerrainCharacteristics::DOOR);
+    }
 
-    if (has_flag(f_ptr->flags, FF_AVOID_RUN) && !ignore_avoid_run)
+    if (terrain.flags.has(TerrainCharacteristics::AVOID_RUN) && !ignore_avoid_run) {
         return true;
+    }
 
-    if (!has_flag(f_ptr->flags, FF_MOVE) && !has_flag(f_ptr->flags, FF_CAN_FLY))
-        return !has_flag(f_ptr->flags, FF_DOOR);
+    if (terrain.flags.has_none_of({ TerrainCharacteristics::MOVE, TerrainCharacteristics::CAN_FLY })) {
+        return terrain.flags.has_not(TerrainCharacteristics::DOOR);
+    }
 
     return false;
 }
@@ -85,7 +88,7 @@ static bool see_wall(player_type *creature_ptr, DIRECTION dir, POSITION y, POSIT
 /*!
  * @brief ダッシュ処理の導入 /
  * Initialize the running algorithm for a new direction.
- * @param creature_ptr プレーヤーへの参照ポインタ
+ * @param player_ptr   プレイヤーへの参照ポインタ
  * @param dir 導入の移動先
  * @details
  * Diagonal Corridor -- allow diaginal entry into corridors.\n
@@ -99,7 +102,7 @@ static bool see_wall(player_type *creature_ptr, DIRECTION dir, POSITION y, POSIT
  *       \#x\#                  \@x\#\n
  *       \@\@p.                  p\n
  */
-static void run_init(player_type *creature_ptr, DIRECTION dir)
+static void run_init(PlayerType *player_ptr, DIRECTION dir)
 {
     find_current = dir;
     find_prevdir = dir;
@@ -109,30 +112,31 @@ static void run_init(player_type *creature_ptr, DIRECTION dir)
     bool deepright = false;
     bool shortright = false;
     bool shortleft = false;
-    creature_ptr->run_py = creature_ptr->y;
-    creature_ptr->run_px = creature_ptr->x;
-    int row = creature_ptr->y + ddy[dir];
-    int col = creature_ptr->x + ddx[dir];
-    ignore_avoid_run = cave_has_flag_bold(creature_ptr->current_floor_ptr, row, col, FF_AVOID_RUN);
+    player_ptr->run_py = player_ptr->y;
+    player_ptr->run_px = player_ptr->x;
+    int row = player_ptr->y + ddy[dir];
+    int col = player_ptr->x + ddx[dir];
+    ignore_avoid_run = cave_has_flag_bold(player_ptr->current_floor_ptr, row, col, TerrainCharacteristics::AVOID_RUN);
     int i = chome[dir];
-    if (see_wall(creature_ptr, cycle[i + 1], creature_ptr->y, creature_ptr->x)) {
+    if (see_wall(player_ptr, cycle[i + 1], player_ptr->y, player_ptr->x)) {
         find_breakleft = true;
         shortleft = true;
-    } else if (see_wall(creature_ptr, cycle[i + 1], row, col)) {
+    } else if (see_wall(player_ptr, cycle[i + 1], row, col)) {
         find_breakleft = true;
         deepleft = true;
     }
 
-    if (see_wall(creature_ptr, cycle[i - 1], creature_ptr->y, creature_ptr->x)) {
+    if (see_wall(player_ptr, cycle[i - 1], player_ptr->y, player_ptr->x)) {
         find_breakright = true;
         shortright = true;
-    } else if (see_wall(creature_ptr, cycle[i - 1], row, col)) {
+    } else if (see_wall(player_ptr, cycle[i - 1], row, col)) {
         find_breakright = true;
         deepright = true;
     }
 
-    if (!find_breakleft || !find_breakright)
+    if (!find_breakleft || !find_breakright) {
         return;
+    }
 
     find_openarea = false;
     if (dir & 0x01) {
@@ -145,8 +149,9 @@ static void run_init(player_type *creature_ptr, DIRECTION dir)
         return;
     }
 
-    if (!see_wall(creature_ptr, cycle[i], row, col))
+    if (!see_wall(player_ptr, cycle[i], row, col)) {
         return;
+    }
 
     if (shortleft && !shortright) {
         find_prevdir = cycle[i - 2];
@@ -158,26 +163,29 @@ static void run_init(player_type *creature_ptr, DIRECTION dir)
 /*!
  * @brief ダッシュ移動処理中、移動先のマスか未知の地形かどうかを判定する /
  * Hack -- Check for an "unknown corner" (see below)
- * @param creature_ptr プレーヤーへの参照ポインタ
+ * @param player_ptr   プレイヤーへの参照ポインタ
  * @param dir 想定する移動方向ID
  * @param y 移動元のY座標
  * @param x 移動元のX座標
  * @return 移動先が未知の地形ならばTRUE
  */
-static bool see_nothing(player_type *creature_ptr, DIRECTION dir, POSITION y, POSITION x)
+static bool see_nothing(PlayerType *player_ptr, DIRECTION dir, POSITION y, POSITION x)
 {
     y += ddy[dir];
     x += ddx[dir];
 
-    floor_type *floor_ptr = creature_ptr->current_floor_ptr;
-    if (!in_bounds2(floor_ptr, y, x))
+    auto *floor_ptr = player_ptr->current_floor_ptr;
+    if (!in_bounds2(floor_ptr, y, x)) {
         return true;
+    }
 
-    if (floor_ptr->grid_array[y][x].is_mark())
+    if (floor_ptr->grid_array[y][x].is_mark()) {
         return false;
+    }
 
-    if (player_can_see_bold(creature_ptr, y, x))
+    if (player_can_see_bold(player_ptr, y, x)) {
         return false;
+    }
 
     return true;
 }
@@ -185,19 +193,21 @@ static bool see_nothing(player_type *creature_ptr, DIRECTION dir, POSITION y, PO
 /*!
  * @brief ダッシュ移動が継続できるかどうかの判定 /
  * Update the current "run" path
- * @param creature_ptr プレーヤーへの参照ポインタ
+ * @param player_ptr   プレイヤーへの参照ポインタ
  * @return 立ち止まるべき条件が満たされたらTRUE
  * ダッシュ移動が継続できるならばTRUEを返す。
  * Return TRUE if the running should be stopped
  */
-static bool run_test(player_type *creature_ptr)
+static bool run_test(PlayerType *player_ptr)
 {
-    DIRECTION prev_dir = find_prevdir;
-    int max = (prev_dir & 0x01) + 1;
-    floor_type *floor_ptr = creature_ptr->current_floor_ptr;
-    if ((disturb_trap_detect || alert_trap_detect) && creature_ptr->dtrap && !(floor_ptr->grid_array[creature_ptr->y][creature_ptr->x].info & CAVE_IN_DETECT)) {
-        creature_ptr->dtrap = false;
-        if (!(floor_ptr->grid_array[creature_ptr->y][creature_ptr->x].info & CAVE_UNSAFE)) {
+    const auto prev_dir = find_prevdir;
+    const auto max = (prev_dir & 0x01) + 1;
+    const auto &floor = *player_ptr->current_floor_ptr;
+    const auto p_pos = player_ptr->get_position();
+    const auto &p_grid = floor.get_grid(p_pos);
+    if ((disturb_trap_detect || alert_trap_detect) && player_ptr->dtrap && !(p_grid.info & CAVE_IN_DETECT)) {
+        player_ptr->dtrap = false;
+        if (!(p_grid.info & CAVE_UNSAFE)) {
             if (alert_trap_detect) {
                 msg_print(_("* 注意:この先はトラップの感知範囲外です! *", "*Leaving trap detect region!*"));
             }
@@ -209,53 +219,51 @@ static bool run_test(player_type *creature_ptr)
         }
     }
 
-    DIRECTION check_dir = 0;
-    int option = 0, option2 = 0;
-    for (int i = -max; i <= max; i++) {
-        DIRECTION new_dir = cycle[chome[prev_dir] + i];
-        int row = creature_ptr->y + ddy[new_dir];
-        int col = creature_ptr->x + ddx[new_dir];
-        grid_type *g_ptr;
-        g_ptr = &floor_ptr->grid_array[row][col];
-        FEAT_IDX feat = g_ptr->get_feat_mimic();
-        feature_type *f_ptr;
-        f_ptr = &f_info[feat];
-        if (g_ptr->m_idx) {
-            monster_type *m_ptr = &floor_ptr->m_list[g_ptr->m_idx];
-            if (m_ptr->ml)
+    auto check_dir = 0;
+    auto option = 0;
+    auto option2 = 0;
+    for (auto i = -max; i <= max; i++) {
+        int new_dir = cycle[chome[prev_dir] + i];
+        const Pos2D pos(player_ptr->y + ddy[new_dir], player_ptr->x + ddx[new_dir]);
+        const auto &grid = floor.get_grid(pos);
+        if (grid.m_idx) {
+            const auto &monster = floor.m_list[grid.m_idx];
+            if (monster.ml) {
                 return true;
+            }
         }
 
-        for (const auto this_o_idx : g_ptr->o_idx_list) {
-            object_type *o_ptr;
-            o_ptr = &floor_ptr->o_list[this_o_idx];
-            if (o_ptr->marked & OM_FOUND)
+        for (const auto this_o_idx : grid.o_idx_list) {
+            const auto &item = floor.o_list[this_o_idx];
+            if (item.marked.has(OmType::FOUND)) {
                 return true;
+            }
         }
 
-        bool inv = true;
-        if (g_ptr->is_mark()) {
-            bool notice = has_flag(f_ptr->flags, FF_NOTICE);
-            if (notice && has_flag(f_ptr->flags, FF_MOVE)) {
-                if (find_ignore_doors && has_flag(f_ptr->flags, FF_DOOR) && has_flag(f_ptr->flags, FF_CLOSE)) {
+        auto inv = true;
+        if (grid.is_mark()) {
+            const auto &terrain = grid.get_terrain_mimic();
+            auto notice = terrain.flags.has(TerrainCharacteristics::NOTICE);
+            if (notice && terrain.flags.has(TerrainCharacteristics::MOVE)) {
+                if (find_ignore_doors && terrain.flags.has_all_of({ TerrainCharacteristics::DOOR, TerrainCharacteristics::CLOSE })) {
                     notice = false;
-                } else if (find_ignore_stairs && has_flag(f_ptr->flags, FF_STAIRS)) {
+                } else if (find_ignore_stairs && terrain.flags.has(TerrainCharacteristics::STAIRS)) {
                     notice = false;
-                } else if (has_flag(f_ptr->flags, FF_LAVA) && (has_immune_fire(creature_ptr) || is_invuln(creature_ptr))) {
+                } else if (terrain.flags.has(TerrainCharacteristics::LAVA) && (has_immune_fire(player_ptr) || is_invuln(player_ptr))) {
                     notice = false;
-                } else if (has_flag(f_ptr->flags, FF_WATER) && has_flag(f_ptr->flags, FF_DEEP)
-                    && (creature_ptr->levitation || creature_ptr->can_swim || (calc_inventory_weight(creature_ptr) <= calc_weight_limit(creature_ptr)))) {
+                } else if (terrain.flags.has_all_of({ TerrainCharacteristics::WATER, TerrainCharacteristics::DEEP }) && (player_ptr->levitation || player_ptr->can_swim || (calc_inventory_weight(player_ptr) <= calc_weight_limit(player_ptr)))) {
                     notice = false;
                 }
             }
 
-            if (notice)
+            if (notice) {
                 return true;
+            }
 
             inv = false;
         }
 
-        if (!inv && see_wall(creature_ptr, 0, row, col)) {
+        if (!inv && see_wall(player_ptr, 0, pos.y, pos.x)) {
             if (find_openarea) {
                 if (i < 0) {
                     find_breakright = true;
@@ -267,19 +275,22 @@ static bool run_test(player_type *creature_ptr)
             continue;
         }
 
-        if (find_openarea)
+        if (find_openarea) {
             continue;
+        }
 
         if (!option) {
             option = new_dir;
             continue;
         }
 
-        if (option2)
+        if (option2) {
             return true;
+        }
 
-        if (option != cycle[chome[prev_dir] + i - 1])
+        if (option != cycle[chome[prev_dir] + i - 1]) {
             return true;
+        }
 
         if (new_dir & 0x01) {
             check_dir = cycle[chome[prev_dir] + i - 2];
@@ -294,48 +305,53 @@ static bool run_test(player_type *creature_ptr)
 
     if (find_openarea) {
         for (int i = -max; i < 0; i++) {
-            if (!see_wall(creature_ptr, cycle[chome[prev_dir] + i], creature_ptr->y, creature_ptr->x)) {
-                if (find_breakright)
+            if (!see_wall(player_ptr, cycle[chome[prev_dir] + i], player_ptr->y, player_ptr->x)) {
+                if (find_breakright) {
                     return true;
+                }
             } else {
-                if (find_breakleft)
+                if (find_breakleft) {
                     return true;
+                }
             }
         }
 
         for (int i = max; i > 0; i--) {
-            if (!see_wall(creature_ptr, cycle[chome[prev_dir] + i], creature_ptr->y, creature_ptr->x)) {
-                if (find_breakleft)
+            if (!see_wall(player_ptr, cycle[chome[prev_dir] + i], player_ptr->y, player_ptr->x)) {
+                if (find_breakleft) {
                     return true;
+                }
             } else {
-                if (find_breakright)
+                if (find_breakright) {
                     return true;
+                }
             }
         }
 
-        return see_wall(creature_ptr, find_current, creature_ptr->y, creature_ptr->x);
+        return see_wall(player_ptr, find_current, player_ptr->y, player_ptr->x);
     }
 
-    if (!option)
+    if (!option) {
         return true;
+    }
 
     if (!option2) {
         find_current = option;
         find_prevdir = option;
-        return see_wall(creature_ptr, find_current, creature_ptr->y, creature_ptr->x);
+        return see_wall(player_ptr, find_current, player_ptr->y, player_ptr->x);
     } else if (!find_cut) {
         find_current = option;
         find_prevdir = option2;
-        return see_wall(creature_ptr, find_current, creature_ptr->y, creature_ptr->x);
+        return see_wall(player_ptr, find_current, player_ptr->y, player_ptr->x);
     }
 
-    int row = creature_ptr->y + ddy[option];
-    int col = creature_ptr->x + ddx[option];
-    if (!see_wall(creature_ptr, option, row, col) || !see_wall(creature_ptr, check_dir, row, col)) {
-        if (see_nothing(creature_ptr, option, row, col) && see_nothing(creature_ptr, option2, row, col)) {
+    int row = player_ptr->y + ddy[option];
+    int col = player_ptr->x + ddx[option];
+    if (!see_wall(player_ptr, option, row, col) || !see_wall(player_ptr, check_dir, row, col)) {
+        if (see_nothing(player_ptr, option, row, col) && see_nothing(player_ptr, option2, row, col)) {
             find_current = option;
             find_prevdir = option2;
-            return see_wall(creature_ptr, find_current, creature_ptr->y, creature_ptr->x);
+            return see_wall(player_ptr, find_current, player_ptr->y, player_ptr->x);
         }
 
         return true;
@@ -344,47 +360,48 @@ static bool run_test(player_type *creature_ptr)
     if (find_cut) {
         find_current = option2;
         find_prevdir = option2;
-        return see_wall(creature_ptr, find_current, creature_ptr->y, creature_ptr->x);
+        return see_wall(player_ptr, find_current, player_ptr->y, player_ptr->x);
     }
 
     find_current = option;
     find_prevdir = option2;
-    return see_wall(creature_ptr, find_current, creature_ptr->y, creature_ptr->x);
+    return see_wall(player_ptr, find_current, player_ptr->y, player_ptr->x);
 }
 
 /*!
  * @brief 継続的なダッシュ処理 /
  * Take one step along the current "run" path
- * @param creature_ptr プレーヤーへの参照ポインタ
+ * @param player_ptr   プレイヤーへの参照ポインタ
  * @param dir 移動を試みる方向ID
  */
-void run_step(player_type *creature_ptr, DIRECTION dir)
+void run_step(PlayerType *player_ptr, DIRECTION dir)
 {
     if (dir) {
         ignore_avoid_run = true;
-        if (see_wall(creature_ptr, dir, creature_ptr->y, creature_ptr->x)) {
+        if (see_wall(player_ptr, dir, player_ptr->y, player_ptr->x)) {
             sound(SOUND_HITWALL);
             msg_print(_("その方向には走れません。", "You cannot run in that direction."));
-            disturb(creature_ptr, false, false);
+            disturb(player_ptr, false, false);
             return;
         }
 
-        run_init(creature_ptr, dir);
+        run_init(player_ptr, dir);
     } else {
-        if (run_test(creature_ptr)) {
-            disturb(creature_ptr, false, false);
+        if (run_test(player_ptr)) {
+            disturb(player_ptr, false, false);
             return;
         }
     }
 
-    if (--creature_ptr->running <= 0)
+    if (--player_ptr->running <= 0) {
         return;
+    }
 
-    PlayerEnergy(creature_ptr).set_player_turn_energy(100);
-    exe_movement(creature_ptr, find_current, false, false);
-    if (player_bold(creature_ptr, creature_ptr->run_py, creature_ptr->run_px)) {
-        creature_ptr->run_py = 0;
-        creature_ptr->run_px = 0;
-        disturb(creature_ptr, false, false);
+    PlayerEnergy(player_ptr).set_player_turn_energy(100);
+    exe_movement(player_ptr, find_current, false, false);
+    if (player_ptr->is_located_at_running_destination()) {
+        player_ptr->run_py = 0;
+        player_ptr->run_px = 0;
+        disturb(player_ptr, false, false);
     }
 }