OSDN Git Service

[Refactor] #3903 realm-hissatsu.cpp から呼び出しているget_direction() の周辺コードをget_neighbor...
authorHourier <66951241+Hourier@users.noreply.github.com>
Mon, 8 Apr 2024 13:44:59 +0000 (22:44 +0900)
committerHourier <66951241+Hourier@users.noreply.github.com>
Sat, 20 Apr 2024 00:58:54 +0000 (09:58 +0900)
src/realm/realm-hissatsu.cpp

index 753503a..1c04346 100644 (file)
@@ -100,9 +100,6 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
         }
 
         if (cast) {
-            DIRECTION cdir;
-            POSITION y, x;
-
             if (!get_direction(player_ptr, &dir)) {
                 return std::nullopt;
             }
@@ -110,6 +107,7 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
                 return std::nullopt;
             }
 
+            int cdir;
             for (cdir = 0; cdir < 8; cdir++) {
                 if (cdd[cdir] == dir) {
                     break;
@@ -120,26 +118,24 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
                 return std::nullopt;
             }
 
-            y = player_ptr->y + ddy_cdd[cdir];
-            x = player_ptr->x + ddx_cdd[cdir];
-            if (player_ptr->current_floor_ptr->grid_array[y][x].has_monster()) {
-                do_cmd_attack(player_ptr, y, x, HISSATSU_NONE);
+            const auto pos = player_ptr->get_position();
+            Pos2D pos_cdd(pos.y + ddy_cdd[cdir], pos.x + ddx_cdd[cdir]);
+            if (player_ptr->current_floor_ptr->get_grid(pos_cdd).has_monster()) {
+                do_cmd_attack(player_ptr, pos_cdd.y, pos_cdd.x, HISSATSU_NONE);
             } else {
                 msg_print(_("攻撃は空を切った。", "You attack the empty air."));
             }
 
-            y = player_ptr->y + ddy_cdd[(cdir + 7) % 8];
-            x = player_ptr->x + ddx_cdd[(cdir + 7) % 8];
-            if (player_ptr->current_floor_ptr->grid_array[y][x].has_monster()) {
-                do_cmd_attack(player_ptr, y, x, HISSATSU_NONE);
+            pos_cdd = Pos2D(pos.y + ddy_cdd[(cdir + 7) % 8], pos.x + ddx_cdd[(cdir + 7) % 8]);
+            if (player_ptr->current_floor_ptr->get_grid(pos_cdd).has_monster()) {
+                do_cmd_attack(player_ptr, pos_cdd.y, pos_cdd.x, HISSATSU_NONE);
             } else {
                 msg_print(_("攻撃は空を切った。", "You attack the empty air."));
             }
 
-            y = player_ptr->y + ddy_cdd[(cdir + 1) % 8];
-            x = player_ptr->x + ddx_cdd[(cdir + 1) % 8];
-            if (player_ptr->current_floor_ptr->grid_array[y][x].has_monster()) {
-                do_cmd_attack(player_ptr, y, x, HISSATSU_NONE);
+            pos_cdd = Pos2D(pos.y + ddy_cdd[(cdir + 1) % 8], pos.x + ddx_cdd[(cdir + 1) % 8]);
+            if (player_ptr->current_floor_ptr->get_grid(pos_cdd).has_monster()) {
+                do_cmd_attack(player_ptr, pos_cdd.y, pos_cdd.x, HISSATSU_NONE);
             } else {
                 msg_print(_("攻撃は空を切った。", "You attack the empty air."));
             }
@@ -171,8 +167,6 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
         }
 
         if (cast) {
-            POSITION y, x;
-
             if (!get_direction(player_ptr, &dir)) {
                 return std::nullopt;
             }
@@ -180,11 +174,9 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
                 return std::nullopt;
             }
 
-            y = player_ptr->y + ddy[dir];
-            x = player_ptr->x + ddx[dir];
-
-            if (player_ptr->current_floor_ptr->grid_array[y][x].has_monster()) {
-                do_cmd_attack(player_ptr, y, x, HISSATSU_FIRE);
+            const auto pos = player_ptr->get_neighbor(dir);
+            if (player_ptr->current_floor_ptr->get_grid(pos).has_monster()) {
+                do_cmd_attack(player_ptr, pos.y, pos.x, HISSATSU_FIRE);
             } else {
                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
                 return std::nullopt;
@@ -214,8 +206,6 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
         }
 
         if (cast) {
-            POSITION y, x;
-
             if (!get_direction(player_ptr, &dir)) {
                 return std::nullopt;
             }
@@ -223,11 +213,9 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
                 return std::nullopt;
             }
 
-            y = player_ptr->y + ddy[dir];
-            x = player_ptr->x + ddx[dir];
-
-            if (player_ptr->current_floor_ptr->grid_array[y][x].has_monster()) {
-                do_cmd_attack(player_ptr, y, x, HISSATSU_MINEUCHI);
+            const auto pos = player_ptr->get_neighbor(dir);
+            if (player_ptr->current_floor_ptr->get_grid(pos).has_monster()) {
+                do_cmd_attack(player_ptr, pos.y, pos.x, HISSATSU_MINEUCHI);
             } else {
                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
                 return std::nullopt;
@@ -264,8 +252,6 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
         }
 
         if (cast) {
-            POSITION y, x;
-
             if (player_ptr->riding) {
                 msg_print(_("乗馬中には無理だ。", "You cannot do it when riding."));
                 return std::nullopt;
@@ -278,27 +264,24 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
             if (dir == 5) {
                 return std::nullopt;
             }
-            y = player_ptr->y + ddy[dir];
-            x = player_ptr->x + ddx[dir];
 
-            const auto *floor_ptr = player_ptr->current_floor_ptr;
-            const auto &grid = floor_ptr->grid_array[y][x];
+            const auto pos = player_ptr->get_neighbor(dir);
+            const auto &floor = *player_ptr->current_floor_ptr;
+            const auto &grid = floor.get_grid(pos);
             if (!grid.has_monster()) {
                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
                 return std::nullopt;
             }
 
-            do_cmd_attack(player_ptr, y, x, HISSATSU_NONE);
+            do_cmd_attack(player_ptr, pos.y, pos.x, HISSATSU_NONE);
             if (!player_can_enter(player_ptr, grid.feat, 0) || is_trap(player_ptr, grid.feat)) {
                 break;
             }
 
-            y += ddy[dir];
-            x += ddx[dir];
-
+            const Pos2D pos_neighbor(pos.y + ddy[dir], pos.x + ddx[dir]);
             if (player_can_enter(player_ptr, grid.feat, 0) && !is_trap(player_ptr, grid.feat) && !grid.m_idx) {
                 msg_print(nullptr);
-                (void)move_player_effect(player_ptr, y, x, MPE_FORGET_FLOW | MPE_HANDLE_STUFF | MPE_DONT_PICKUP);
+                (void)move_player_effect(player_ptr, pos_neighbor.y, pos_neighbor.x, MPE_FORGET_FLOW | MPE_HANDLE_STUFF | MPE_DONT_PICKUP);
             }
         }
         break;
@@ -312,20 +295,18 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
         }
 
         if (cast) {
-            POSITION y, x;
-
             if (!get_direction(player_ptr, &dir)) {
                 return std::nullopt;
             }
+
             if (dir == 5) {
                 return std::nullopt;
             }
 
-            y = player_ptr->y + ddy[dir];
-            x = player_ptr->x + ddx[dir];
-
-            if (player_ptr->current_floor_ptr->grid_array[y][x].has_monster()) {
-                do_cmd_attack(player_ptr, y, x, HISSATSU_POISON);
+            const auto pos = player_ptr->get_neighbor(dir);
+            const auto &floor = *player_ptr->current_floor_ptr;
+            if (floor.get_grid(pos).has_monster()) {
+                do_cmd_attack(player_ptr, pos.y, pos.x, HISSATSU_POISON);
             } else {
                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
                 return std::nullopt;
@@ -343,20 +324,18 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
         }
 
         if (cast) {
-            POSITION y, x;
-
             if (!get_direction(player_ptr, &dir)) {
                 return std::nullopt;
             }
+
             if (dir == 5) {
                 return std::nullopt;
             }
 
-            y = player_ptr->y + ddy[dir];
-            x = player_ptr->x + ddx[dir];
-
-            if (player_ptr->current_floor_ptr->grid_array[y][x].has_monster()) {
-                do_cmd_attack(player_ptr, y, x, HISSATSU_ZANMA);
+            const auto pos = player_ptr->get_neighbor(dir);
+            const auto &floor = *player_ptr->current_floor_ptr;
+            if (floor.get_grid(pos).has_monster()) {
+                do_cmd_attack(player_ptr, pos.y, pos.x, HISSATSU_ZANMA);
             } else {
                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
                 return std::nullopt;
@@ -373,21 +352,19 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
         }
 
         if (cast) {
-            POSITION y, x;
-
             if (!get_direction(player_ptr, &dir)) {
                 return std::nullopt;
             }
+
             if (dir == 5) {
                 return std::nullopt;
             }
 
-            y = player_ptr->y + ddy[dir];
-            x = player_ptr->x + ddx[dir];
-
-            const auto &floor = *player_ptr->current_floor_ptr;
-            if (player_ptr->current_floor_ptr->grid_array[y][x].has_monster()) {
-                do_cmd_attack(player_ptr, y, x, HISSATSU_NONE);
+            const auto pos = player_ptr->get_neighbor(dir);
+            auto &floor = *player_ptr->current_floor_ptr;
+            const auto &grid = floor.get_grid(pos);
+            if (grid.has_monster()) {
+                do_cmd_attack(player_ptr, pos.y, pos.x, HISSATSU_NONE);
             } else {
                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
                 return std::nullopt;
@@ -395,34 +372,32 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
             if (floor.get_dungeon_definition().flags.has(DungeonFeatureType::NO_MELEE)) {
                 return "";
             }
-            if (player_ptr->current_floor_ptr->grid_array[y][x].has_monster()) {
-                int i;
-                POSITION ty = y, tx = x;
-                POSITION oy = y, ox = x;
-                MONSTER_IDX m_idx = player_ptr->current_floor_ptr->grid_array[y][x].m_idx;
-                auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
+            if (grid.has_monster()) {
+                Pos2D target(pos.y, pos.x);
+                Pos2D origin(pos.y, pos.x);
+                auto m_idx = grid.m_idx;
+                auto *m_ptr = &floor.m_list[m_idx];
                 const auto m_name = monster_desc(player_ptr, m_ptr, 0);
-
-                for (i = 0; i < 5; i++) {
-                    y += ddy[dir];
-                    x += ddx[dir];
-                    if (is_cave_empty_bold(player_ptr, y, x)) {
-                        ty = y;
-                        tx = x;
+                Pos2D neighbor(pos.y, pos.x);
+                for (auto i = 0; i < 5; i++) {
+                    neighbor.y += ddy[dir];
+                    neighbor.x += ddx[dir];
+                    if (is_cave_empty_bold(player_ptr, neighbor.y, neighbor.x)) {
+                        target = Pos2D(neighbor.y, neighbor.x);
                     } else {
                         break;
                     }
                 }
-                if ((ty != oy) || (tx != ox)) {
+                if (target != origin) {
                     msg_format(_("%sを吹き飛ばした!", "You blow %s away!"), m_name.data());
-                    player_ptr->current_floor_ptr->grid_array[oy][ox].m_idx = 0;
-                    player_ptr->current_floor_ptr->grid_array[ty][tx].m_idx = m_idx;
-                    m_ptr->fy = ty;
-                    m_ptr->fx = tx;
+                    floor.get_grid(origin).m_idx = 0;
+                    floor.get_grid(target).m_idx = m_idx;
+                    m_ptr->fy = target.y;
+                    m_ptr->fx = target.x;
 
                     update_monster(player_ptr, m_idx, true);
-                    lite_spot(player_ptr, oy, ox);
-                    lite_spot(player_ptr, ty, tx);
+                    lite_spot(player_ptr, origin.y, origin.x);
+                    lite_spot(player_ptr, target.y, target.x);
 
                     if (m_ptr->get_monrace().brightness_flags.has_any_of(ld_mask)) {
                         RedrawingFlagsUpdater::get_instance().set_flag(StatusRecalculatingFlag::MONSTER_LITE);
@@ -463,28 +438,26 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
         }
 
         if (cast) {
-            POSITION y, x;
-
             if (!get_direction(player_ptr, &dir)) {
                 return std::nullopt;
             }
+
             if (dir == 5) {
                 return std::nullopt;
             }
 
-            y = player_ptr->y + ddy[dir];
-            x = player_ptr->x + ddx[dir];
-
-            if (player_ptr->current_floor_ptr->grid_array[y][x].has_monster()) {
-                do_cmd_attack(player_ptr, y, x, HISSATSU_HAGAN);
+            const auto pos = player_ptr->get_neighbor(dir);
+            const auto &floor = *player_ptr->current_floor_ptr;
+            if (floor.get_grid(pos).has_monster()) {
+                do_cmd_attack(player_ptr, pos.y, pos.x, HISSATSU_HAGAN);
             }
 
-            if (!cave_has_flag_bold(player_ptr->current_floor_ptr, y, x, TerrainCharacteristics::HURT_ROCK)) {
+            if (!cave_has_flag_bold(player_ptr->current_floor_ptr, pos.y, pos.x, TerrainCharacteristics::HURT_ROCK)) {
                 break;
             }
 
             /* Destroy the feature */
-            cave_alter_feat(player_ptr, y, x, TerrainCharacteristics::HURT_ROCK);
+            cave_alter_feat(player_ptr, pos.y, pos.x, TerrainCharacteristics::HURT_ROCK);
             RedrawingFlagsUpdater::get_instance().set_flag(StatusRecalculatingFlag::FLOW);
         }
         break;
@@ -499,20 +472,18 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
         }
 
         if (cast) {
-            POSITION y, x;
-
             if (!get_direction(player_ptr, &dir)) {
                 return std::nullopt;
             }
+
             if (dir == 5) {
                 return std::nullopt;
             }
 
-            y = player_ptr->y + ddy[dir];
-            x = player_ptr->x + ddx[dir];
-
-            if (player_ptr->current_floor_ptr->grid_array[y][x].has_monster()) {
-                do_cmd_attack(player_ptr, y, x, HISSATSU_COLD);
+            const auto pos = player_ptr->get_neighbor(dir);
+            const auto &floor = *player_ptr->current_floor_ptr;
+            if (floor.get_grid(pos).has_monster()) {
+                do_cmd_attack(player_ptr, pos.y, pos.x, HISSATSU_COLD);
             } else {
                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
                 return std::nullopt;
@@ -530,20 +501,18 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
         }
 
         if (cast) {
-            POSITION y, x;
-
             if (!get_direction(player_ptr, &dir)) {
                 return std::nullopt;
             }
+
             if (dir == 5) {
                 return std::nullopt;
             }
 
-            y = player_ptr->y + ddy[dir];
-            x = player_ptr->x + ddx[dir];
-
-            if (player_ptr->current_floor_ptr->grid_array[y][x].has_monster()) {
-                do_cmd_attack(player_ptr, y, x, HISSATSU_KYUSHO);
+            const auto pos = player_ptr->get_neighbor(dir);
+            const auto &floor = *player_ptr->current_floor_ptr;
+            if (floor.get_grid(pos).has_monster()) {
+                do_cmd_attack(player_ptr, pos.y, pos.x, HISSATSU_KYUSHO);
             } else {
                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
                 return std::nullopt;
@@ -560,20 +529,18 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
         }
 
         if (cast) {
-            POSITION y, x;
-
             if (!get_direction(player_ptr, &dir)) {
                 return std::nullopt;
             }
+
             if (dir == 5) {
                 return std::nullopt;
             }
 
-            y = player_ptr->y + ddy[dir];
-            x = player_ptr->x + ddx[dir];
-
-            if (player_ptr->current_floor_ptr->grid_array[y][x].has_monster()) {
-                do_cmd_attack(player_ptr, y, x, HISSATSU_MAJIN);
+            const auto pos = player_ptr->get_neighbor(dir);
+            const auto &floor = *player_ptr->current_floor_ptr;
+            if (floor.get_grid(pos).has_monster()) {
+                do_cmd_attack(player_ptr, pos.y, pos.x, HISSATSU_MAJIN);
             } else {
                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
                 return std::nullopt;
@@ -591,20 +558,18 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
         }
 
         if (cast) {
-            POSITION y, x;
-
             if (!get_direction(player_ptr, &dir)) {
                 return std::nullopt;
             }
+
             if (dir == 5) {
                 return std::nullopt;
             }
 
-            y = player_ptr->y + ddy[dir];
-            x = player_ptr->x + ddx[dir];
-
-            if (player_ptr->current_floor_ptr->grid_array[y][x].has_monster()) {
-                do_cmd_attack(player_ptr, y, x, HISSATSU_SUTEMI);
+            const auto pos = player_ptr->get_neighbor(dir);
+            const auto &floor = *player_ptr->current_floor_ptr;
+            if (floor.get_grid(pos).has_monster()) {
+                do_cmd_attack(player_ptr, pos.y, pos.x, HISSATSU_SUTEMI);
             } else {
                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
                 return std::nullopt;
@@ -622,20 +587,18 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
         }
 
         if (cast) {
-            POSITION y, x;
-
             if (!get_direction(player_ptr, &dir)) {
                 return std::nullopt;
             }
+
             if (dir == 5) {
                 return std::nullopt;
             }
 
-            y = player_ptr->y + ddy[dir];
-            x = player_ptr->x + ddx[dir];
-
-            if (player_ptr->current_floor_ptr->grid_array[y][x].has_monster()) {
-                do_cmd_attack(player_ptr, y, x, HISSATSU_ELEC);
+            const auto pos = player_ptr->get_neighbor(dir);
+            const auto &floor = *player_ptr->current_floor_ptr;
+            if (floor.get_grid(pos).has_monster()) {
+                do_cmd_attack(player_ptr, pos.y, pos.x, HISSATSU_ELEC);
             } else {
                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
                 return std::nullopt;
@@ -669,25 +632,25 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
         }
 
         if (cast) {
-            POSITION y = 0, x = 0;
             auto current_cut = player_ptr->effects()->cut()->current();
             short new_cut = current_cut < 300 ? current_cut + 300 : current_cut * 2;
             (void)BadStatusSetter(player_ptr).set_cut(new_cut);
+            const auto &floor = *player_ptr->current_floor_ptr;
             for (dir = 0; dir < 8; dir++) {
-                y = player_ptr->y + ddy_ddd[dir];
-                x = player_ptr->x + ddx_ddd[dir];
-                auto *g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
-                auto *m_ptr = &player_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
-                if (!g_ptr->has_monster() || (!m_ptr->ml && !cave_has_flag_bold(player_ptr->current_floor_ptr, y, x, TerrainCharacteristics::PROJECT))) {
+                const auto pos = player_ptr->get_position();
+                const Pos2D pos_ddd(pos.y + ddy_ddd[dir], pos.x + ddx_ddd[dir]);
+                const auto &grid = floor.get_grid(pos_ddd);
+                const auto &monster = floor.m_list[grid.m_idx];
+                if (!grid.has_monster() || (!monster.ml && !cave_has_flag_bold(&floor, pos_ddd.y, pos_ddd.x, TerrainCharacteristics::PROJECT))) {
                     continue;
                 }
 
-                if (m_ptr->has_living_flag()) {
-                    do_cmd_attack(player_ptr, y, x, HISSATSU_SEKIRYUKA);
+                if (monster.has_living_flag()) {
+                    do_cmd_attack(player_ptr, pos_ddd.y, pos_ddd.x, HISSATSU_SEKIRYUKA);
                     continue;
                 }
 
-                const auto m_name = monster_desc(player_ptr, m_ptr, 0);
+                const auto m_name = monster_desc(player_ptr, &monster, 0);
                 msg_format(_("%sには効果がない!", "%s is unharmed!"), m_name.data());
             }
         }
@@ -702,20 +665,18 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
         }
 
         if (cast) {
-            POSITION y, x;
-
             if (!get_direction(player_ptr, &dir)) {
                 return std::nullopt;
             }
+
             if (dir == 5) {
                 return std::nullopt;
             }
 
-            y = player_ptr->y + ddy[dir];
-            x = player_ptr->x + ddx[dir];
-
-            if (player_ptr->current_floor_ptr->grid_array[y][x].has_monster()) {
-                do_cmd_attack(player_ptr, y, x, HISSATSU_QUAKE);
+            const auto pos = player_ptr->get_neighbor(dir);
+            const auto &floor = *player_ptr->current_floor_ptr;
+            if (floor.get_grid(pos).has_monster()) {
+                do_cmd_attack(player_ptr, pos.y, pos.x, HISSATSU_QUAKE);
             } else {
                 earthquake(player_ptr, player_ptr->y, player_ptr->x, 10, 0);
             }
@@ -793,8 +754,6 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
         }
 
         if (cast) {
-            int i;
-
             if (!get_direction(player_ptr, &dir)) {
                 return std::nullopt;
             }
@@ -802,20 +761,13 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
                 return std::nullopt;
             }
 
-            const auto &floor = *player_ptr->current_floor_ptr;
-            for (i = 0; i < 3; i++) {
-                POSITION y, x;
-                POSITION ny, nx;
-                MONSTER_IDX m_idx;
-                Grid *g_ptr;
-                MonsterEntity *m_ptr;
-
-                y = player_ptr->y + ddy[dir];
-                x = player_ptr->x + ddx[dir];
-                g_ptr = &player_ptr->current_floor_ptr->grid_array[y][x];
-
-                if (g_ptr->has_monster()) {
-                    do_cmd_attack(player_ptr, y, x, HISSATSU_3DAN);
+            auto &floor = *player_ptr->current_floor_ptr;
+            for (auto i = 0; i < 3; i++) {
+                const Pos2D pos = player_ptr->get_neighbor(dir);
+                auto &grid = floor.get_grid(pos);
+
+                if (grid.has_monster()) {
+                    do_cmd_attack(player_ptr, pos.y, pos.x, HISSATSU_3DAN);
                 } else {
                     msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
                     return std::nullopt;
@@ -826,17 +778,16 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
                 }
 
                 /* Monster is dead? */
-                if (!g_ptr->has_monster()) {
+                if (!grid.has_monster()) {
                     break;
                 }
 
-                ny = y + ddy[dir];
-                nx = x + ddx[dir];
-                m_idx = g_ptr->m_idx;
-                m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
+                const Pos2D pos_new(pos.y + ddy[dir], pos.x + ddx[dir]);
+                const auto m_idx = grid.m_idx;
+                auto &monster = floor.m_list[m_idx];
 
                 /* Monster cannot move back? */
-                if (!monster_can_enter(player_ptr, ny, nx, &m_ptr->get_monrace(), 0)) {
+                if (!monster_can_enter(player_ptr, pos_new.y, pos_new.x, &monster.get_monrace(), 0)) {
                     /* -more- */
                     if (i < 2) {
                         msg_print(nullptr);
@@ -844,22 +795,22 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
                     continue;
                 }
 
-                g_ptr->m_idx = 0;
-                player_ptr->current_floor_ptr->grid_array[ny][nx].m_idx = m_idx;
-                m_ptr->fy = ny;
-                m_ptr->fx = nx;
+                grid.m_idx = 0;
+                floor.get_grid(pos_new).m_idx = m_idx;
+                monster.fy = pos_new.y;
+                monster.fx = pos_new.x;
 
                 update_monster(player_ptr, m_idx, true);
 
                 /* Redraw the old spot */
-                lite_spot(player_ptr, y, x);
+                lite_spot(player_ptr, pos.y, pos.x);
 
                 /* Redraw the new spot */
-                lite_spot(player_ptr, ny, nx);
+                lite_spot(player_ptr, pos_new.y, pos_new.x);
 
                 /* Player can move forward? */
-                if (player_can_enter(player_ptr, g_ptr->feat, 0)) {
-                    if (!move_player_effect(player_ptr, y, x, MPE_FORGET_FLOW | MPE_HANDLE_STUFF | MPE_DONT_PICKUP)) {
+                if (player_can_enter(player_ptr, grid.feat, 0)) {
+                    if (!move_player_effect(player_ptr, pos.y, pos.x, MPE_FORGET_FLOW | MPE_HANDLE_STUFF | MPE_DONT_PICKUP)) {
                         break;
                     }
                 } else {
@@ -884,20 +835,18 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
         }
 
         if (cast) {
-            POSITION y, x;
-
             if (!get_direction(player_ptr, &dir)) {
                 return std::nullopt;
             }
+
             if (dir == 5) {
                 return std::nullopt;
             }
 
-            y = player_ptr->y + ddy[dir];
-            x = player_ptr->x + ddx[dir];
-
-            if (player_ptr->current_floor_ptr->grid_array[y][x].has_monster()) {
-                do_cmd_attack(player_ptr, y, x, HISSATSU_DRAIN);
+            const auto pos = player_ptr->get_neighbor(dir);
+            const auto &floor = *player_ptr->current_floor_ptr;
+            if (floor.get_grid(pos).has_monster()) {
+                do_cmd_attack(player_ptr, pos.y, pos.x, HISSATSU_DRAIN);
             } else {
                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
                 return std::nullopt;
@@ -1034,41 +983,38 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
         }
 
         if (cast) {
-            int total_damage = 0, basedam, i;
-            POSITION y, x;
-            ItemEntity *o_ptr;
-
             if (!get_direction(player_ptr, &dir)) {
                 return std::nullopt;
             }
+
             if (dir == 5) {
                 return std::nullopt;
             }
 
-            y = player_ptr->y + ddy[dir];
-            x = player_ptr->x + ddx[dir];
-
-            auto &floor = *player_ptr->current_floor_ptr;
+            const auto pos = player_ptr->get_neighbor(dir);
+            const auto &floor = *player_ptr->current_floor_ptr;
             if (floor.get_dungeon_definition().flags.has(DungeonFeatureType::NO_MELEE)) {
                 msg_print(_("なぜか攻撃することができない。", "Something prevents you from attacking."));
                 return "";
             }
+
             msg_print(_("武器を大きく振り下ろした。", "You swing your weapon downward."));
-            for (i = 0; i < 2; i++) {
-                int damage;
+            auto total_damage = 0;
+            for (auto i = 0; i < 2; i++) {
                 if (!has_melee_weapon(player_ptr, INVEN_MAIN_HAND + i)) {
                     break;
                 }
-                o_ptr = &player_ptr->inventory_list[INVEN_MAIN_HAND + i];
-                basedam = (o_ptr->dd * (o_ptr->ds + 1)) * 50;
-                damage = o_ptr->to_d * 100;
+
+                const auto &item = player_ptr->inventory_list[INVEN_MAIN_HAND + i];
+                auto basedam = (item.dd * (item.ds + 1)) * 50;
+                auto damage = item.to_d * 100;
 
                 // @todo ヴォーパルの多重定義.
-                if (o_ptr->is_specific_artifact(FixedArtifactId::VORPAL_BLADE) || o_ptr->is_specific_artifact(FixedArtifactId::CHAINSWORD)) {
+                if (item.is_specific_artifact(FixedArtifactId::VORPAL_BLADE) || item.is_specific_artifact(FixedArtifactId::CHAINSWORD)) {
                     /* vorpal blade */
                     basedam *= 5;
                     basedam /= 3;
-                } else if (o_ptr->get_flags().has(TR_VORPAL)) {
+                } else if (item.get_flags().has(TR_VORPAL)) {
                     /* vorpal flag only */
                     basedam *= 11;
                     basedam /= 9;
@@ -1079,9 +1025,9 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
                 total_damage += (damage / 100);
             }
 
-            const auto is_bold = cave_has_flag_bold(&floor, y, x, TerrainCharacteristics::PROJECT);
+            const auto is_bold = cave_has_flag_bold(&floor, pos.y, pos.x, TerrainCharacteristics::PROJECT);
             constexpr auto flags = PROJECT_KILL | PROJECT_JUMP | PROJECT_ITEM;
-            project(player_ptr, 0, (is_bold ? 5 : 0), y, x, total_damage * 3 / 2, AttributeType::METEOR, flags);
+            project(player_ptr, 0, (is_bold ? 5 : 0), pos.y, pos.x, total_damage * 3 / 2, AttributeType::METEOR, flags);
         }
         break;
 
@@ -1095,20 +1041,18 @@ std::optional<std::string> do_hissatsu_spell(PlayerType *player_ptr, SPELL_IDX s
         }
 
         if (cast) {
-            POSITION y, x;
-
             if (!get_direction(player_ptr, &dir)) {
                 return std::nullopt;
             }
+
             if (dir == 5) {
                 return std::nullopt;
             }
 
-            y = player_ptr->y + ddy[dir];
-            x = player_ptr->x + ddx[dir];
-
-            if (player_ptr->current_floor_ptr->grid_array[y][x].has_monster()) {
-                do_cmd_attack(player_ptr, y, x, HISSATSU_UNDEAD);
+            const auto pos = player_ptr->get_neighbor(dir);
+            const auto &floor = *player_ptr->current_floor_ptr;
+            if (floor.get_grid(pos).has_monster()) {
+                do_cmd_attack(player_ptr, pos.y, pos.x, HISSATSU_UNDEAD);
             } else {
                 msg_print(_("その方向にはモンスターはいません。", "There is no monster."));
                 return std::nullopt;