* @param m_idx モンスターID
* @return モンスターがペットであればTRUE
*/
-static bool decide_pet_movement_direction(player_type *target_ptr, DIRECTION *mm, MONSTER_IDX m_idx)
+static bool decide_pet_movement_direction(MonsterSweepGrid *msd)
{
- monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
- if (!is_pet(m_ptr))
+ monster_type *m_ptr = &msd->target_ptr->current_floor_ptr->m_list[msd->m_idx];
+ if (!is_pet(m_ptr)) {
return false;
-
- bool avoid = ((target_ptr->pet_follow_distance < 0) && (m_ptr->cdis <= (0 - target_ptr->pet_follow_distance)));
- bool lonely = (!avoid && (m_ptr->cdis > target_ptr->pet_follow_distance));
+ }
+
+ bool avoid = ((msd->target_ptr->pet_follow_distance < 0) && (m_ptr->cdis <= (0 - msd->target_ptr->pet_follow_distance)));
+ bool lonely = (!avoid && (m_ptr->cdis > msd->target_ptr->pet_follow_distance));
bool distant = (m_ptr->cdis > PET_SEEK_DIST);
- mm[0] = mm[1] = mm[2] = mm[3] = 5;
- if (get_enemy_dir(target_ptr, m_idx, mm))
- return true;
- if (!avoid && !lonely && !distant)
+ msd->mm[0] = msd->mm[1] = msd->mm[2] = msd->mm[3] = 5;
+ if (get_enemy_dir(msd->target_ptr, msd->m_idx, msd->mm)) {
return true;
+ }
- POSITION dis = target_ptr->pet_follow_distance;
- if (target_ptr->pet_follow_distance > PET_SEEK_DIST) {
- target_ptr->pet_follow_distance = PET_SEEK_DIST;
+ if (!avoid && !lonely && !distant) {
+ return true;
+ }
+
+ POSITION dis = msd->target_ptr->pet_follow_distance;
+ if (msd->target_ptr->pet_follow_distance > PET_SEEK_DIST) {
+ msd->target_ptr->pet_follow_distance = PET_SEEK_DIST;
}
- (void)get_movable_grid(target_ptr, m_idx, mm);
- target_ptr->pet_follow_distance = (s16b)dis;
+ (void)msd->get_movable_grid();
+ msd->target_ptr->pet_follow_distance = (s16b)dis;
return true;
}
return true;
}
- if (random_walk(target_ptr, mm, m_ptr))
+ if (random_walk(target_ptr, mm, m_ptr)) {
return true;
-
+ }
+
if ((r_ptr->flags1 & RF1_NEVER_MOVE) && (m_ptr->cdis > 1)) {
mm[0] = mm[1] = mm[2] = mm[3] = 5;
return true;
}
- if (decide_pet_movement_direction(target_ptr, mm, m_idx))
+ MonsterSweepGrid msd(target_ptr, m_idx, mm);
+ if (decide_pet_movement_direction(&msd)) {
return true;
-
+ }
+
if (!is_hostile(m_ptr)) {
mm[0] = mm[1] = mm[2] = mm[3] = 5;
get_enemy_dir(target_ptr, m_idx, mm);
return true;
}
- if (!get_movable_grid(target_ptr, m_idx, mm))
- return false;
-
- return true;
+ return msd.get_movable_grid();
}
#include "system/player-type-definition.h"
#include "target/projection-path-calculator.h"
+MonsterSweepGrid::MonsterSweepGrid(player_type *target_ptr, MONSTER_IDX m_idx, DIRECTION *mm)
+ : target_ptr(target_ptr)
+ , m_idx(m_idx)
+ , mm(mm)
+{
+}
+
/*!
* @brief モンスターがプレイヤーから逃走するかどうかを返す /
* Returns whether a given monster will try to run from the player.
* Note that this function is responsible for about one to five percent\n
* of the processor use in normal conditions...\n
*/
-static bool mon_will_run(player_type *target_ptr, MONSTER_IDX m_idx)
+bool MonsterSweepGrid::mon_will_run()
{
monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
monster_race *r_ptr = &r_info[m_ptr->r_idx];
* @param xp 適したマスのX座標を返す参照ポインタ
* @return 有効なマスがあった場合TRUEを返す
*/
-static bool sweep_ranged_attack_grid(player_type *target_ptr, MONSTER_IDX m_idx, POSITION *yp, POSITION *xp)
+bool MonsterSweepGrid::sweep_ranged_attack_grid(POSITION *yp, POSITION *xp)
{
floor_type *floor_ptr = target_ptr->current_floor_ptr;
monster_type *m_ptr = &floor_ptr->m_list[m_idx];
* being close enough to chase directly. I have no idea what will\n
* happen if you combine "smell" with low "aaf" values.\n
*/
-static void sweep_movable_grid(player_type *target_ptr, MONSTER_IDX m_idx, POSITION *yp, POSITION *xp, bool no_flow)
+void MonsterSweepGrid::sweep_movable_grid(POSITION *yp, POSITION *xp, bool no_flow)
{
grid_type *g_ptr;
floor_type *floor_ptr = target_ptr->current_floor_ptr;
monster_race *r_ptr = &r_info[m_ptr->r_idx];
if (r_ptr->ability_flags.has_any_of(RF_ABILITY_ATTACK_MASK)) {
- if (sweep_ranged_attack_grid(target_ptr, m_idx, yp, xp))
+ if (sweep_ranged_attack_grid(yp, xp))
return;
}
* but instead of heading directly for it, the monster should "swerve"\n
* around the player so that he has a smaller chance of getting hit.\n
*/
-static bool sweep_runnable_away_grid(floor_type *floor_ptr, MONSTER_IDX m_idx, POSITION *yp, POSITION *xp)
+bool MonsterSweepGrid::sweep_runnable_away_grid(POSITION *yp, POSITION *xp)
{
POSITION gy = 0, gx = 0;
+ auto *floor_ptr = this->target_ptr->current_floor_ptr;
monster_type *m_ptr = &floor_ptr->m_list[m_idx];
monster_race *r_ptr = &r_info[m_ptr->r_idx];
POSITION fy = m_ptr->fy;
* @return 有効方向があった場合TRUEを返す
* @todo 分割したいが条件が多すぎて適切な関数名と詳細処理を追いきれない……
*/
-bool get_movable_grid(player_type *target_ptr, MONSTER_IDX m_idx, DIRECTION *mm)
+bool MonsterSweepGrid::get_movable_grid()
{
floor_type *floor_ptr = target_ptr->current_floor_ptr;
monster_type *m_ptr = &floor_ptr->m_list[m_idx];
POSITION y2 = target_ptr->y;
POSITION x2 = target_ptr->x;
bool done = false;
- bool will_run = mon_will_run(target_ptr, m_idx);
+ bool will_run = mon_will_run();
grid_type *g_ptr;
bool no_flow = m_ptr->mflag2.has(MFLAG2::NOFLOW) && grid_cost(&floor_ptr->grid_array[m_ptr->fy][m_ptr->fx], r_ptr) > 2;
bool can_pass_wall = ((r_ptr->flags2 & RF2_PASS_WALL) != 0) && ((m_idx != target_ptr->riding) || has_pass_wall(target_ptr));
}
if (!done) {
- sweep_movable_grid(target_ptr, m_idx, &y2, &x2, no_flow);
+ sweep_movable_grid(&y2, &x2, no_flow);
y = m_ptr->fy - y2;
x = m_ptr->fx - x2;
}
int tmp_x = (-x);
int tmp_y = (-y);
if (find_safety(target_ptr, m_idx, &y, &x) && !no_flow) {
- if (sweep_runnable_away_grid(target_ptr->current_floor_ptr, m_idx, &y, &x))
+ if (sweep_runnable_away_grid(&y, &x))
done = true;
}
#include "system/angband.h"
-typedef struct player_type player_type;
-bool get_movable_grid(player_type *target_ptr, MONSTER_IDX m_idx, DIRECTION *mm);
+struct floor_type;
+struct player_type;
+class MonsterSweepGrid {
+public:
+ MonsterSweepGrid(player_type *target_ptr, MONSTER_IDX m_idx, DIRECTION *mm);
+ MonsterSweepGrid() = delete;
+ virtual ~MonsterSweepGrid() = default;
+ player_type *target_ptr;
+ MONSTER_IDX m_idx;
+ DIRECTION *mm;
+ bool get_movable_grid();
+
+private:
+ bool sweep_runnable_away_grid(POSITION *yp, POSITION *xp);
+ void sweep_movable_grid(POSITION *yp, POSITION *xp, bool no_flow);
+ bool sweep_ranged_attack_grid(POSITION *yp, POSITION *xp);
+ bool mon_will_run();
+};