bool process_monster_attack_to_monster(player_type *target_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx, grid_type *g_ptr, bool can_cross);
bool exe_monster_attack_to_monster(player_type *target_ptr, MONSTER_IDX m_idx, grid_type *g_ptr);
+bool process_monster_movement(player_type *target_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx, DIRECTION *mm, POSITION oy, POSITION ox, int *count);
bool process_post_dig_wall(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx);
bool update_riding_monster(player_type *target_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx, POSITION oy, POSITION ox, POSITION ny, POSITION nx);
{
monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
monster_race *r_ptr = &r_info[m_ptr->r_idx];
- monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
DIRECTION mm[8];
turn_flags tmp_flags;
if (!decide_monster_movement_direction(target_ptr, mm, m_idx, aware)) return;
int count = 0;
- for (int i = 0; mm[i]; i++)
- {
- int d = mm[i];
- if (d == 5) d = ddd[randint0(8)];
-
- POSITION ny = oy + ddy[d];
- POSITION nx = ox + ddx[d];
- if (!in_bounds2(target_ptr->current_floor_ptr, ny, nx)) continue;
-
- grid_type *g_ptr;
- g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
- bool can_cross = monster_can_cross_terrain(target_ptr, g_ptr->feat, r_ptr, turn_flags_ptr->is_riding_mon ? CEM_RIDING : 0);
-
- if (!process_wall(target_ptr, turn_flags_ptr, m_ptr, ny, nx, can_cross))
- {
- if (!process_door(target_ptr, turn_flags_ptr, m_ptr, ny, nx))
- return;
- }
-
- if (!process_protection_rune(target_ptr, turn_flags_ptr, m_ptr, ny, nx))
- {
- if (!process_explosive_rune(target_ptr, turn_flags_ptr, m_ptr, ny, nx))
- return;
- }
-
- exe_monster_attack_to_player(target_ptr, turn_flags_ptr, m_idx, ny, nx);
- if (process_monster_attack_to_monster(target_ptr, turn_flags_ptr, m_idx, g_ptr, can_cross)) return;
-
- if (turn_flags_ptr->is_riding_mon)
- {
- if (!target_ptr->riding_ryoute && !MON_MONFEAR(&target_ptr->current_floor_ptr->m_list[target_ptr->riding])) turn_flags_ptr->do_move = FALSE;
- }
-
- if (!process_post_dig_wall(target_ptr, turn_flags_ptr, m_ptr, ny, nx)) return;
-
- if (turn_flags_ptr->must_alter_to_move && (r_ptr->flags7 & RF7_AQUATIC))
- {
- if (!monster_can_cross_terrain(target_ptr, g_ptr->feat, r_ptr, turn_flags_ptr->is_riding_mon ? CEM_RIDING : 0))
- turn_flags_ptr->do_move = FALSE;
- }
-
- if (turn_flags_ptr->do_move && !can_cross && !turn_flags_ptr->did_kill_wall && !turn_flags_ptr->did_bash_door)
- turn_flags_ptr->do_move = FALSE;
-
- if (turn_flags_ptr->do_move && (r_ptr->flags1 & RF1_NEVER_MOVE))
- {
- if (is_original_ap_and_seen(target_ptr, m_ptr))
- r_ptr->r_flags1 |= (RF1_NEVER_MOVE);
-
- turn_flags_ptr->do_move = FALSE;
- }
-
- if (!turn_flags_ptr->do_move)
- {
- if (turn_flags_ptr->do_turn) break;
-
- continue;
- }
-
- turn_flags_ptr->do_turn = TRUE;
- feature_type *f_ptr;
- f_ptr = &f_info[g_ptr->feat];
- if (have_flag(f_ptr->flags, FF_TREE))
- {
- if (!(r_ptr->flags7 & RF7_CAN_FLY) && !(r_ptr->flags8 & RF8_WILD_WOOD))
- {
- m_ptr->energy_need += ENERGY_NEED();
- }
- }
-
- if (!update_riding_monster(target_ptr, turn_flags_ptr, m_idx, oy, ox, ny, nx)) break;
-
- if (m_ptr->ml &&
- (disturb_move ||
- (disturb_near && (m_ptr->mflag & MFLAG_VIEW) && projectable(target_ptr, target_ptr->y, target_ptr->x, m_ptr->fy, m_ptr->fx)) ||
- (disturb_high && ap_r_ptr->r_tkills && ap_r_ptr->level >= target_ptr->lev)))
- {
- if (is_hostile(m_ptr))
- disturb(target_ptr, FALSE, TRUE);
- }
-
- bool is_takable_or_killable = g_ptr->o_idx > 0;
- is_takable_or_killable &= (r_ptr->flags2 & (RF2_TAKE_ITEM | RF2_KILL_ITEM)) != 0;
-
- bool is_pickup_items = (target_ptr->pet_extra_flags & PF_PICKUP_ITEMS) != 0;
- is_pickup_items &= (r_ptr->flags2 & RF2_TAKE_ITEM) != 0;
-
- is_takable_or_killable &= !is_pet(m_ptr) || is_pickup_items;
- if (!is_takable_or_killable)
- {
- if (turn_flags_ptr->do_turn) break;
-
- continue;
- }
-
- update_object_by_monster_movement(target_ptr, turn_flags_ptr, m_idx, ny, nx);
-
- if (turn_flags_ptr->do_turn) break;
-
- count++;
- }
+ if(!process_monster_movement(target_ptr, turn_flags_ptr, m_idx, mm, oy, ox, &count)) return;
/*
* Forward movements failed, but now received LOS attack!
/*!
+ * @brief モンスターの移動に関するメインルーチン
+ * @param target_ptr プレーヤーへの参照ポインタ
+ * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
+ * @param m_idx モンスターID
+ * @param mm モンスターの移動方向
+ * @param oy 移動前の、モンスターのY座標
+ * @param ox 移動前の、モンスターのX座標
+ * @param count 移動回数 (のはず todo)
+ * @return 移動が阻害される何か (ドア等)があったらFALSE
+ */
+bool process_monster_movement(player_type *target_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx, DIRECTION *mm, POSITION oy, POSITION ox, int *count)
+{
+ for (int i = 0; mm[i]; i++)
+ {
+ int d = mm[i];
+ if (d == 5) d = ddd[randint0(8)];
+
+ POSITION ny = oy + ddy[d];
+ POSITION nx = ox + ddx[d];
+ if (!in_bounds2(target_ptr->current_floor_ptr, ny, nx)) continue;
+
+ grid_type *g_ptr;
+ g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
+ monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
+ monster_race *r_ptr = &r_info[m_ptr->r_idx];
+ bool can_cross = monster_can_cross_terrain(target_ptr, g_ptr->feat, r_ptr, turn_flags_ptr->is_riding_mon ? CEM_RIDING : 0);
+
+ if (!process_wall(target_ptr, turn_flags_ptr, m_ptr, ny, nx, can_cross))
+ {
+ if (!process_door(target_ptr, turn_flags_ptr, m_ptr, ny, nx))
+ return FALSE;
+ }
+
+ if (!process_protection_rune(target_ptr, turn_flags_ptr, m_ptr, ny, nx))
+ {
+ if (!process_explosive_rune(target_ptr, turn_flags_ptr, m_ptr, ny, nx))
+ return FALSE;
+ }
+
+ exe_monster_attack_to_player(target_ptr, turn_flags_ptr, m_idx, ny, nx);
+ if (process_monster_attack_to_monster(target_ptr, turn_flags_ptr, m_idx, g_ptr, can_cross)) return FALSE;
+
+ if (turn_flags_ptr->is_riding_mon)
+ {
+ if (!target_ptr->riding_ryoute && !MON_MONFEAR(&target_ptr->current_floor_ptr->m_list[target_ptr->riding])) turn_flags_ptr->do_move = FALSE;
+ }
+
+ if (!process_post_dig_wall(target_ptr, turn_flags_ptr, m_ptr, ny, nx)) return FALSE;
+
+ if (turn_flags_ptr->must_alter_to_move && (r_ptr->flags7 & RF7_AQUATIC))
+ {
+ if (!monster_can_cross_terrain(target_ptr, g_ptr->feat, r_ptr, turn_flags_ptr->is_riding_mon ? CEM_RIDING : 0))
+ turn_flags_ptr->do_move = FALSE;
+ }
+
+ if (turn_flags_ptr->do_move && !can_cross && !turn_flags_ptr->did_kill_wall && !turn_flags_ptr->did_bash_door)
+ turn_flags_ptr->do_move = FALSE;
+
+ if (turn_flags_ptr->do_move && (r_ptr->flags1 & RF1_NEVER_MOVE))
+ {
+ if (is_original_ap_and_seen(target_ptr, m_ptr))
+ r_ptr->r_flags1 |= (RF1_NEVER_MOVE);
+
+ turn_flags_ptr->do_move = FALSE;
+ }
+
+ if (!turn_flags_ptr->do_move)
+ {
+ if (turn_flags_ptr->do_turn) break;
+
+ continue;
+ }
+
+ turn_flags_ptr->do_turn = TRUE;
+ feature_type *f_ptr;
+ f_ptr = &f_info[g_ptr->feat];
+ if (have_flag(f_ptr->flags, FF_TREE))
+ {
+ if (!(r_ptr->flags7 & RF7_CAN_FLY) && !(r_ptr->flags8 & RF8_WILD_WOOD))
+ {
+ m_ptr->energy_need += ENERGY_NEED();
+ }
+ }
+
+ if (!update_riding_monster(target_ptr, turn_flags_ptr, m_idx, oy, ox, ny, nx)) break;
+
+ monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
+ if (m_ptr->ml &&
+ (disturb_move ||
+ (disturb_near && (m_ptr->mflag & MFLAG_VIEW) && projectable(target_ptr, target_ptr->y, target_ptr->x, m_ptr->fy, m_ptr->fx)) ||
+ (disturb_high && ap_r_ptr->r_tkills && ap_r_ptr->level >= target_ptr->lev)))
+ {
+ if (is_hostile(m_ptr))
+ disturb(target_ptr, FALSE, TRUE);
+ }
+
+ bool is_takable_or_killable = g_ptr->o_idx > 0;
+ is_takable_or_killable &= (r_ptr->flags2 & (RF2_TAKE_ITEM | RF2_KILL_ITEM)) != 0;
+
+ bool is_pickup_items = (target_ptr->pet_extra_flags & PF_PICKUP_ITEMS) != 0;
+ is_pickup_items &= (r_ptr->flags2 & RF2_TAKE_ITEM) != 0;
+
+ is_takable_or_killable &= !is_pet(m_ptr) || is_pickup_items;
+ if (!is_takable_or_killable)
+ {
+ if (turn_flags_ptr->do_turn) break;
+
+ continue;
+ }
+
+ update_object_by_monster_movement(target_ptr, turn_flags_ptr, m_idx, ny, nx);
+
+ if (turn_flags_ptr->do_turn) break;
+
+ *count++;
+ }
+
+ return TRUE;
+}
+
+
+/*!
* @brief モンスターによる壁の透過・破壊を行う
* @param target_ptr プレーヤーへの参照ポインタ
* @param m_ptr モンスターへの参照ポインタ
* @param target_ptr プレーヤーへの参照ポインタ
* @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
* @param m_idx モンスターID
- * @param ny モンスターのY座標
- * @param nx モンスターのX座標
+ * @param ny 移動後の、モンスターのY座標
+ * @param nx 移動後の、モンスターのX座標
* @return なし
* @details
* 反攻撃の洞窟など、直接攻撃ができない場所では処理をスキップする