-/*!
+/*!
* @file run-execution.cpp
* @brief プレイヤーの走行処理実装
*/
#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"
/*!
* @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;
}
/*!
* @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
* \#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;
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) {
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];
/*!
* @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;
}
/*!
* @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!*"));
}
}
}
- 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;
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];
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;
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);
}
}