*/
#include "monster-floor/monster-move.h"
+#include "core/disturbance.h"
+#include "core/player-update-types.h"
#include "core/speed-table.h"
+#include "core/window-redrawer.h"
#include "effect/effect-characteristics.h"
+#include "effect/effect-processor.h"
+#include "floor/cave.h"
#include "game-option/disturbance-options.h"
#include "grid/feature.h"
#include "io/files-util.h"
#include "monster/monster-status.h"
#include "monster/monster-update.h"
#include "pet/pet-util.h"
-#include "player/player-move.h"
-#include "spell/process-effect.h"
#include "spell/spell-types.h"
+#include "system/floor-type-definition.h"
+#include "target/projection-path-calculator.h"
#include "util/bit-flags-calculator.h"
#include "view/display-messages.h"
+#include "player/player-status-flags.h"
static bool check_hp_for_feat_destruction(feature_type *f_ptr, monster_type *m_ptr)
{
- return !have_flag(f_ptr->flags, FF_GLASS) ||
- (r_info[m_ptr->r_idx].flags2 & RF2_STUPID) ||
- (m_ptr->hp >= MAX(m_ptr->maxhp / 3, 200));
+ return !has_flag(f_ptr->flags, FF_GLASS) || (r_info[m_ptr->r_idx].flags2 & RF2_STUPID) || (m_ptr->hp >= MAX(m_ptr->maxhp / 3, 200));
}
-
/*!
- * @brief モンスターによる壁の透過・破壊を行う
- * @param target_ptr プレーヤーへの参照ポインタ
- * @param m_ptr モンスターへの参照ポインタ
- * @param ny モンスターのY座標
- * @param nx モンスターのX座標
- * @param can_cross モンスターが地形を踏破できるならばTRUE
- * @return 透過も破壊もしなかった場合はFALSE、それ以外はTRUE
- */
+ * @brief モンスターによる壁の透過・破壊を行う
+ * @param target_ptr プレーヤーへの参照ポインタ
+ * @param m_ptr モンスターへの参照ポインタ
+ * @param ny モンスターのY座標
+ * @param nx モンスターのX座標
+ * @param can_cross モンスターが地形を踏破できるならばTRUE
+ * @return 透過も破壊もしなかった場合はFALSE、それ以外はTRUE
+ */
static bool process_wall(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx, bool can_cross)
{
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
- grid_type *g_ptr;
- g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
- feature_type *f_ptr;
- f_ptr = &f_info[g_ptr->feat];
- if (player_bold(target_ptr, ny, nx))
- {
- turn_flags_ptr->do_move = TRUE;
- return TRUE;
- }
-
- if (g_ptr->m_idx > 0)
- {
- turn_flags_ptr->do_move = TRUE;
- return TRUE;
- }
-
- if (((r_ptr->flags2 & RF2_KILL_WALL) != 0) &&
- (can_cross ? !have_flag(f_ptr->flags, FF_LOS) : !turn_flags_ptr->is_riding_mon) &&
- have_flag(f_ptr->flags, FF_HURT_DISI) && !have_flag(f_ptr->flags, FF_PERMANENT) &&
- check_hp_for_feat_destruction(f_ptr, m_ptr))
- {
- turn_flags_ptr->do_move = TRUE;
- if (!can_cross) turn_flags_ptr->must_alter_to_move = TRUE;
-
- turn_flags_ptr->did_kill_wall = TRUE;
- return TRUE;
- }
-
- if (!can_cross) return FALSE;
-
- turn_flags_ptr->do_move = TRUE;
- if (((r_ptr->flags2 & RF2_PASS_WALL) != 0) && (!turn_flags_ptr->is_riding_mon || target_ptr->pass_wall) &&
- have_flag(f_ptr->flags, FF_CAN_PASS))
- {
- turn_flags_ptr->did_pass_wall = TRUE;
- }
-
- return TRUE;
+ monster_race *r_ptr = &r_info[m_ptr->r_idx];
+ grid_type *g_ptr;
+ g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
+ feature_type *f_ptr;
+ f_ptr = &f_info[g_ptr->feat];
+ if (player_bold(target_ptr, ny, nx)) {
+ turn_flags_ptr->do_move = TRUE;
+ return TRUE;
+ }
+
+ if (g_ptr->m_idx > 0) {
+ turn_flags_ptr->do_move = TRUE;
+ return TRUE;
+ }
+
+ if (((r_ptr->flags2 & RF2_KILL_WALL) != 0) && (can_cross ? !has_flag(f_ptr->flags, FF_LOS) : !turn_flags_ptr->is_riding_mon)
+ && has_flag(f_ptr->flags, FF_HURT_DISI) && !has_flag(f_ptr->flags, FF_PERMANENT) && check_hp_for_feat_destruction(f_ptr, m_ptr)) {
+ turn_flags_ptr->do_move = TRUE;
+ if (!can_cross)
+ turn_flags_ptr->must_alter_to_move = TRUE;
+
+ turn_flags_ptr->did_kill_wall = TRUE;
+ return TRUE;
+ }
+
+ if (!can_cross)
+ return FALSE;
+
+ turn_flags_ptr->do_move = TRUE;
+ if (((r_ptr->flags2 & RF2_PASS_WALL) != 0) && (!turn_flags_ptr->is_riding_mon || has_pass_wall(target_ptr))
+ && has_flag(f_ptr->flags, FF_CAN_PASS)) {
+ turn_flags_ptr->did_pass_wall = TRUE;
+ }
+
+ return TRUE;
}
-
/*!
* @brief モンスターが普通のドアを開ける処理
* @param target_ptr プレーヤーへの参照ポインタ
*/
static bool bash_normal_door(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx)
{
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
- grid_type *g_ptr;
- g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
- feature_type *f_ptr;
- f_ptr = &f_info[g_ptr->feat];
- turn_flags_ptr->do_move = FALSE;
- if (((r_ptr->flags2 & RF2_OPEN_DOOR) == 0) || !have_flag(f_ptr->flags, FF_OPEN) ||
- (is_pet(m_ptr) && ((target_ptr->pet_extra_flags & PF_OPEN_DOORS) == 0)))
- return TRUE;
-
- if (f_ptr->power == 0)
- {
- turn_flags_ptr->did_open_door = TRUE;
- turn_flags_ptr->do_turn = TRUE;
- return FALSE;
- }
-
- if (randint0(m_ptr->hp / 10) > f_ptr->power)
- {
- cave_alter_feat(target_ptr, ny, nx, FF_DISARM);
- turn_flags_ptr->do_turn = TRUE;
- return FALSE;
- }
-
- return TRUE;
+ monster_race *r_ptr = &r_info[m_ptr->r_idx];
+ grid_type *g_ptr;
+ g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
+ feature_type *f_ptr;
+ f_ptr = &f_info[g_ptr->feat];
+ turn_flags_ptr->do_move = FALSE;
+ if (((r_ptr->flags2 & RF2_OPEN_DOOR) == 0) || !has_flag(f_ptr->flags, FF_OPEN) || (is_pet(m_ptr) && ((target_ptr->pet_extra_flags & PF_OPEN_DOORS) == 0)))
+ return TRUE;
+
+ if (f_ptr->power == 0) {
+ turn_flags_ptr->did_open_door = TRUE;
+ turn_flags_ptr->do_turn = TRUE;
+ return FALSE;
+ }
+
+ if (randint0(m_ptr->hp / 10) > f_ptr->power) {
+ cave_alter_feat(target_ptr, ny, nx, FF_DISARM);
+ turn_flags_ptr->do_turn = TRUE;
+ return FALSE;
+ }
+
+ return TRUE;
}
-
/*!
* @brief モンスターがガラスのドアを開ける処理
* @param target_ptr プレーヤーへの参照ポインタ
*/
static void bash_glass_door(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, feature_type *f_ptr, bool may_bash)
{
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
- if (!may_bash || ((r_ptr->flags2 & RF2_BASH_DOOR) == 0) || !have_flag(f_ptr->flags, FF_BASH) ||
- (is_pet(m_ptr) && ((target_ptr->pet_extra_flags & PF_OPEN_DOORS) == 0)))
- return;
+ monster_race *r_ptr = &r_info[m_ptr->r_idx];
+ if (!may_bash || ((r_ptr->flags2 & RF2_BASH_DOOR) == 0) || !has_flag(f_ptr->flags, FF_BASH)
+ || (is_pet(m_ptr) && ((target_ptr->pet_extra_flags & PF_OPEN_DOORS) == 0)))
+ return;
- if (!check_hp_for_feat_destruction(f_ptr, m_ptr) || (randint0(m_ptr->hp / 10) <= f_ptr->power))
- return;
+ if (!check_hp_for_feat_destruction(f_ptr, m_ptr) || (randint0(m_ptr->hp / 10) <= f_ptr->power))
+ return;
- if (have_flag(f_ptr->flags, FF_GLASS))
- msg_print(_("ガラスが砕ける音がした!", "You hear glass breaking!"));
- else
- msg_print(_("ドアを叩き開ける音がした!", "You hear a door burst open!"));
+ if (has_flag(f_ptr->flags, FF_GLASS))
+ msg_print(_("ガラスが砕ける音がした!", "You hear glass breaking!"));
+ else
+ msg_print(_("ドアを叩き開ける音がした!", "You hear a door burst open!"));
- if (disturb_minor) disturb(target_ptr, FALSE, FALSE);
+ if (disturb_minor)
+ disturb(target_ptr, FALSE, FALSE);
- turn_flags_ptr->did_bash_door = TRUE;
- turn_flags_ptr->do_move = TRUE;
- turn_flags_ptr->must_alter_to_move = TRUE;
+ turn_flags_ptr->did_bash_door = TRUE;
+ turn_flags_ptr->do_move = TRUE;
+ turn_flags_ptr->must_alter_to_move = TRUE;
}
-
/*!
* @brief モンスターによるドアの開放・破壊を行う
* @param target_ptr プレーヤーへの参照ポインタ
*/
static bool process_door(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx)
{
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
- grid_type *g_ptr;
- g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
- if (!is_closed_door(target_ptr, g_ptr->feat)) return TRUE;
-
- feature_type *f_ptr;
- f_ptr = &f_info[g_ptr->feat];
- bool may_bash = bash_normal_door(target_ptr, turn_flags_ptr, m_ptr, ny, nx);
- bash_glass_door(target_ptr, turn_flags_ptr, m_ptr, f_ptr, may_bash);
-
- if (!turn_flags_ptr->did_open_door && !turn_flags_ptr->did_bash_door) return TRUE;
-
- if (turn_flags_ptr->did_bash_door &&
- ((randint0(100) < 50) || (feat_state(target_ptr, g_ptr->feat, FF_OPEN) == g_ptr->feat) || have_flag(f_ptr->flags, FF_GLASS)))
- {
- cave_alter_feat(target_ptr, ny, nx, FF_BASH);
- if (!monster_is_valid(m_ptr))
- {
- target_ptr->update |= (PU_FLOW);
- target_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
- if (is_original_ap_and_seen(target_ptr, m_ptr)) r_ptr->r_flags2 |= (RF2_BASH_DOOR);
-
- return FALSE;
- }
- }
- else
- {
- cave_alter_feat(target_ptr, ny, nx, FF_OPEN);
- }
-
- f_ptr = &f_info[g_ptr->feat];
- turn_flags_ptr->do_view = TRUE;
- return TRUE;
+ monster_race *r_ptr = &r_info[m_ptr->r_idx];
+ grid_type *g_ptr;
+ g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
+ if (!is_closed_door(target_ptr, g_ptr->feat))
+ return TRUE;
+
+ feature_type *f_ptr;
+ f_ptr = &f_info[g_ptr->feat];
+ bool may_bash = bash_normal_door(target_ptr, turn_flags_ptr, m_ptr, ny, nx);
+ bash_glass_door(target_ptr, turn_flags_ptr, m_ptr, f_ptr, may_bash);
+
+ if (!turn_flags_ptr->did_open_door && !turn_flags_ptr->did_bash_door)
+ return TRUE;
+
+ if (turn_flags_ptr->did_bash_door
+ && ((randint0(100) < 50) || (feat_state(target_ptr, g_ptr->feat, FF_OPEN) == g_ptr->feat) || has_flag(f_ptr->flags, FF_GLASS))) {
+ cave_alter_feat(target_ptr, ny, nx, FF_BASH);
+ if (!monster_is_valid(m_ptr)) {
+ target_ptr->update |= (PU_FLOW);
+ target_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
+ if (is_original_ap_and_seen(target_ptr, m_ptr))
+ r_ptr->r_flags2 |= (RF2_BASH_DOOR);
+
+ return FALSE;
+ }
+ } else {
+ cave_alter_feat(target_ptr, ny, nx, FF_OPEN);
+ }
+
+ f_ptr = &f_info[g_ptr->feat];
+ turn_flags_ptr->do_view = TRUE;
+ return TRUE;
}
-
/*!
* @brief 守りのルーンによるモンスターの移動制限を処理する
* @param target_ptr プレーヤーへの参照ポインタ
*/
static bool process_protection_rune(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx)
{
- grid_type *g_ptr;
- g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
- if (!turn_flags_ptr->do_move || !is_glyph_grid(g_ptr) ||
- (((r_ptr->flags1 & RF1_NEVER_BLOW) != 0) && player_bold(target_ptr, ny, nx)))
- return FALSE;
-
- turn_flags_ptr->do_move = FALSE;
- if (is_pet(m_ptr) || (randint1(BREAK_GLYPH) >= r_ptr->level))
- return TRUE;
-
- if (g_ptr->info & CAVE_MARK)
- {
- msg_print(_("守りのルーンが壊れた!", "The rune of protection is broken!"));
- }
-
- g_ptr->info &= ~(CAVE_MARK);
- g_ptr->info &= ~(CAVE_OBJECT);
- g_ptr->mimic = 0;
- turn_flags_ptr->do_move = TRUE;
- note_spot(target_ptr, ny, nx);
- return TRUE;
+ grid_type *g_ptr;
+ g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
+ monster_race *r_ptr = &r_info[m_ptr->r_idx];
+ if (!turn_flags_ptr->do_move || !is_glyph_grid(g_ptr) || (((r_ptr->flags1 & RF1_NEVER_BLOW) != 0) && player_bold(target_ptr, ny, nx)))
+ return FALSE;
+
+ turn_flags_ptr->do_move = FALSE;
+ if (is_pet(m_ptr) || (randint1(BREAK_GLYPH) >= r_ptr->level))
+ return TRUE;
+
+ if (g_ptr->info & CAVE_MARK) {
+ msg_print(_("守りのルーンが壊れた!", "The rune of protection is broken!"));
+ }
+
+ g_ptr->info &= ~(CAVE_MARK);
+ g_ptr->info &= ~(CAVE_OBJECT);
+ g_ptr->mimic = 0;
+ turn_flags_ptr->do_move = TRUE;
+ note_spot(target_ptr, ny, nx);
+ return TRUE;
}
-
/*!
* @brief 爆発のルーンを処理する
* @param target_ptr プレーヤーへの参照ポインタ
*/
static bool process_explosive_rune(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx)
{
- grid_type *g_ptr;
- g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
- if (!turn_flags_ptr->do_move || !is_explosive_rune_grid(g_ptr) ||
- (((r_ptr->flags1 & RF1_NEVER_BLOW) != 0) && player_bold(target_ptr, ny, nx)))
- return TRUE;
-
- turn_flags_ptr->do_move = FALSE;
- if (is_pet(m_ptr)) return TRUE;
-
- if (randint1(BREAK_MINOR_GLYPH) > r_ptr->level)
- {
- if (g_ptr->info & CAVE_MARK)
- {
- msg_print(_("ルーンが爆発した!", "The rune explodes!"));
- BIT_FLAGS project_flags = PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP | PROJECT_NO_HANGEKI;
- project(target_ptr, 0, 2, ny, nx, 2 * (target_ptr->lev + damroll(7, 7)), GF_MANA, project_flags, -1);
- }
- }
- else
- {
- msg_print(_("爆発のルーンは解除された。", "An explosive rune was disarmed."));
- }
-
- g_ptr->info &= ~(CAVE_MARK);
- g_ptr->info &= ~(CAVE_OBJECT);
- g_ptr->mimic = 0;
-
- note_spot(target_ptr, ny, nx);
- lite_spot(target_ptr, ny, nx);
-
- if (!monster_is_valid(m_ptr)) return FALSE;
-
- turn_flags_ptr->do_move = TRUE;
- return TRUE;
+ grid_type *g_ptr;
+ g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
+ monster_race *r_ptr = &r_info[m_ptr->r_idx];
+ if (!turn_flags_ptr->do_move || !is_explosive_rune_grid(g_ptr) || (((r_ptr->flags1 & RF1_NEVER_BLOW) != 0) && player_bold(target_ptr, ny, nx)))
+ return TRUE;
+
+ turn_flags_ptr->do_move = FALSE;
+ if (is_pet(m_ptr))
+ return TRUE;
+
+ if (randint1(BREAK_MINOR_GLYPH) > r_ptr->level) {
+ if (g_ptr->info & CAVE_MARK) {
+ msg_print(_("ルーンが爆発した!", "The rune explodes!"));
+ BIT_FLAGS project_flags = PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP | PROJECT_NO_HANGEKI;
+ project(target_ptr, 0, 2, ny, nx, 2 * (target_ptr->lev + damroll(7, 7)), GF_MANA, project_flags, -1);
+ }
+ } else {
+ msg_print(_("爆発のルーンは解除された。", "An explosive rune was disarmed."));
+ }
+
+ g_ptr->info &= ~(CAVE_MARK);
+ g_ptr->info &= ~(CAVE_OBJECT);
+ g_ptr->mimic = 0;
+
+ note_spot(target_ptr, ny, nx);
+ lite_spot(target_ptr, ny, nx);
+
+ if (!monster_is_valid(m_ptr))
+ return FALSE;
+
+ turn_flags_ptr->do_move = TRUE;
+ return TRUE;
}
-
/*!
* @brief モンスターが壁を掘った後続処理を実行する
* @param target_ptr プレーヤーへの参照ポインタ
*/
static bool process_post_dig_wall(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx)
{
- monster_race *r_ptr = &r_info[m_ptr->r_idx];
- grid_type *g_ptr;
- g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
- feature_type *f_ptr;
- f_ptr = &f_info[g_ptr->feat];
- if (!turn_flags_ptr->did_kill_wall || !turn_flags_ptr->do_move) return TRUE;
-
- if (one_in_(GRINDNOISE))
- {
- if (have_flag(f_ptr->flags, FF_GLASS))
- msg_print(_("何かの砕ける音が聞こえる。", "There is a crashing sound."));
- else
- msg_print(_("ギシギシいう音が聞こえる。", "There is a grinding sound."));
- }
-
- cave_alter_feat(target_ptr, ny, nx, FF_HURT_DISI);
-
- if (!monster_is_valid(m_ptr))
- {
- target_ptr->update |= (PU_FLOW);
- target_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
- if (is_original_ap_and_seen(target_ptr, m_ptr)) r_ptr->r_flags2 |= (RF2_KILL_WALL);
-
- return FALSE;
- }
-
- f_ptr = &f_info[g_ptr->feat];
- turn_flags_ptr->do_view = TRUE;
- turn_flags_ptr->do_turn = TRUE;
- return TRUE;
+ monster_race *r_ptr = &r_info[m_ptr->r_idx];
+ grid_type *g_ptr;
+ g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
+ feature_type *f_ptr;
+ f_ptr = &f_info[g_ptr->feat];
+ if (!turn_flags_ptr->did_kill_wall || !turn_flags_ptr->do_move)
+ return TRUE;
+
+ if (one_in_(GRINDNOISE)) {
+ if (has_flag(f_ptr->flags, FF_GLASS))
+ msg_print(_("何かの砕ける音が聞こえる。", "There is a crashing sound."));
+ else
+ msg_print(_("ギシギシいう音が聞こえる。", "There is a grinding sound."));
+ }
+
+ cave_alter_feat(target_ptr, ny, nx, FF_HURT_DISI);
+
+ if (!monster_is_valid(m_ptr)) {
+ target_ptr->update |= (PU_FLOW);
+ target_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
+ if (is_original_ap_and_seen(target_ptr, m_ptr))
+ r_ptr->r_flags2 |= (RF2_KILL_WALL);
+
+ return FALSE;
+ }
+
+ f_ptr = &f_info[g_ptr->feat];
+ turn_flags_ptr->do_view = TRUE;
+ turn_flags_ptr->do_turn = TRUE;
+ return TRUE;
}
-
/*!
* todo 少し長いが、これといってブロックとしてまとまった部分もないので暫定でこのままとする
* @brief モンスターの移動に関するメインルーチン
*/
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 && !monster_fear_remaining(&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;
+ 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 && !monster_fear_remaining(&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 (has_flag(f_ptr->flags, FF_TREE) && ((r_ptr->flags7 & RF7_CAN_FLY) == 0) && ((r_ptr->flags8 & RF8_WILD_WOOD) == 0))
+ 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 プレーヤーへの参照ポインタ
*/
void process_speak_sound(player_type *target_ptr, MONSTER_IDX m_idx, POSITION oy, POSITION ox, bool aware)
{
- if (target_ptr->phase_out) return;
-
- monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
- monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
- if (m_ptr->ap_r_idx == MON_CYBER &&
- one_in_(CYBERNOISE) &&
- !m_ptr->ml && (m_ptr->cdis <= MAX_SIGHT))
- {
- if (disturb_minor) disturb(target_ptr, FALSE, FALSE);
- msg_print(_("重厚な足音が聞こえた。", "You hear heavy steps."));
- }
-
- if (((ap_r_ptr->flags2 & RF2_CAN_SPEAK) == 0) || !aware ||
- !one_in_(SPEAK_CHANCE) ||
- !player_has_los_bold(target_ptr, oy, ox) ||
- !projectable(target_ptr, oy, ox, target_ptr->y, target_ptr->x))
- return;
-
- GAME_TEXT m_name[MAX_NLEN];
- char monmessage[1024];
- concptr filename;
-
- if (m_ptr->ml)
- monster_desc(target_ptr, m_name, m_ptr, 0);
- else
- strcpy(m_name, _("それ", "It"));
-
- if (monster_fear_remaining(m_ptr))
- filename = _("monfear_j.txt", "monfear.txt");
- else if (is_pet(m_ptr))
- filename = _("monpet_j.txt", "monpet.txt");
- else if (is_friendly(m_ptr))
- filename = _("monfrien_j.txt", "monfrien.txt");
- else
- filename = _("monspeak_j.txt", "monspeak.txt");
-
- if (get_rnd_line(filename, m_ptr->ap_r_idx, monmessage) == 0)
- {
- msg_format(_("%^s%s", "%^s %s"), m_name, monmessage);
- }
+ if (target_ptr->phase_out)
+ return;
+
+ monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
+ monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
+ if (m_ptr->ap_r_idx == MON_CYBER && one_in_(CYBERNOISE) && !m_ptr->ml && (m_ptr->cdis <= MAX_SIGHT)) {
+ if (disturb_minor)
+ disturb(target_ptr, FALSE, FALSE);
+ msg_print(_("重厚な足音が聞こえた。", "You hear heavy steps."));
+ }
+
+ if (((ap_r_ptr->flags2 & RF2_CAN_SPEAK) == 0) || !aware || !one_in_(SPEAK_CHANCE) || !player_has_los_bold(target_ptr, oy, ox)
+ || !projectable(target_ptr, oy, ox, target_ptr->y, target_ptr->x))
+ return;
+
+ GAME_TEXT m_name[MAX_NLEN];
+ char monmessage[1024];
+ concptr filename;
+
+ if (m_ptr->ml)
+ monster_desc(target_ptr, m_name, m_ptr, 0);
+ else
+ strcpy(m_name, _("それ", "It"));
+
+ if (monster_fear_remaining(m_ptr))
+ filename = _("monfear_j.txt", "monfear.txt");
+ else if (is_pet(m_ptr))
+ filename = _("monpet_j.txt", "monpet.txt");
+ else if (is_friendly(m_ptr))
+ filename = _("monfrien_j.txt", "monfrien.txt");
+ else
+ filename = _("monspeak_j.txt", "monspeak.txt");
+
+ if (get_rnd_line(filename, m_ptr->ap_r_idx, monmessage) == 0) {
+ msg_format(_("%^s%s", "%^s %s"), m_name, monmessage);
+ }
}
/*!