2 * @brief モンスターの攻撃に関する処理
7 #include "monster/monster-attack.h"
8 #include "monster-status.h"
10 #include "combat/melee.h" // 暫定。後で引っ越し.
13 * @brief モンスターが移動した結果、そこにプレーヤーがいたら直接攻撃を行う
14 * @param target_ptr プレーヤーへの参照ポインタ
15 * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
16 * @param m_idx モンスターID
17 * @param ny 移動後の、モンスターのY座標
18 * @param nx 移動後の、モンスターのX座標
21 * 反攻撃の洞窟など、直接攻撃ができない場所では処理をスキップする
23 void exe_monster_attack_to_player(player_type *target_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx, POSITION ny, POSITION nx)
25 monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
26 monster_race *r_ptr = &r_info[m_ptr->r_idx];
27 if (!turn_flags_ptr->do_move || !player_bold(target_ptr, ny, nx))
30 if (r_ptr->flags1 & RF1_NEVER_BLOW)
32 if (is_original_ap_and_seen(target_ptr, m_ptr))
33 r_ptr->r_flags1 |= (RF1_NEVER_BLOW);
35 turn_flags_ptr->do_move = FALSE;
38 if (turn_flags_ptr->do_move && ((d_info[target_ptr->dungeon_idx].flags1 & DF1_NO_MELEE) != 0) && !MON_CONFUSED(m_ptr))
40 if (!(r_ptr->flags2 & RF2_STUPID))
41 turn_flags_ptr->do_move = FALSE;
42 else if (is_original_ap_and_seen(target_ptr, m_ptr))
43 r_ptr->r_flags2 |= (RF2_STUPID);
46 if (!turn_flags_ptr->do_move) return;
48 if (!target_ptr->riding || one_in_(2))
50 (void)make_attack_normal(target_ptr, m_idx);
51 turn_flags_ptr->do_move = FALSE;
52 turn_flags_ptr->do_turn = TRUE;
58 * @brief モンスターからモンスターへの直接攻撃を実行する
59 * @param target_ptr プレーヤーへの参照ポインタ
60 * @param m_idx モンスターID
61 * @param g_ptr グリッドへの参照ポインタ
63 static bool exe_monster_attack_to_monster(player_type *target_ptr, MONSTER_IDX m_idx, grid_type *g_ptr)
65 monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
66 monster_race *r_ptr = &r_info[m_ptr->r_idx];
68 y_ptr = &target_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
69 if ((r_ptr->flags1 & RF1_NEVER_BLOW) != 0) return FALSE;
71 if (((r_ptr->flags2 & RF2_KILL_BODY) == 0) && is_original_ap_and_seen(target_ptr, m_ptr))
72 r_ptr->r_flags2 |= (RF2_KILL_BODY);
74 if ((y_ptr->r_idx == 0) || (y_ptr->hp < 0)) return FALSE;
75 if (monst_attack_monst(target_ptr, m_idx, g_ptr->m_idx)) return TRUE;
76 if ((d_info[target_ptr->dungeon_idx].flags1 & DF1_NO_MELEE) == 0) return FALSE;
77 if (MON_CONFUSED(m_ptr)) return TRUE;
78 if ((r_ptr->flags2 & RF2_STUPID) == 0) return FALSE;
80 if (is_original_ap_and_seen(target_ptr, m_ptr))
81 r_ptr->r_flags2 |= (RF2_STUPID);
88 * @brief モンスターからモンスターへの攻撃処理
89 * @param target_ptr プレーヤーへの参照ポインタ
90 * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
91 * @param m_idx モンスターID
92 * @param g_ptr グリッドへの参照ポインタ
93 * @param can_cross モンスターが地形を踏破できるならばTRUE
94 * @return ターン消費が発生したらTRUE
96 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)
98 monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
99 monster_race *r_ptr = &r_info[m_ptr->r_idx];
101 y_ptr = &target_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
102 if (!turn_flags_ptr->do_move || (g_ptr->m_idx == 0)) return FALSE;
104 monster_race *z_ptr = &r_info[y_ptr->r_idx];
105 turn_flags_ptr->do_move = FALSE;
106 if ((((r_ptr->flags2 & RF2_KILL_BODY) != 0) && ((r_ptr->flags1 & RF1_NEVER_BLOW) == 0) &&
107 (r_ptr->mexp * r_ptr->level > z_ptr->mexp * z_ptr->level) &&
108 can_cross && (g_ptr->m_idx != target_ptr->riding)) ||
109 are_enemies(target_ptr, m_ptr, y_ptr) || MON_CONFUSED(m_ptr))
111 return exe_monster_attack_to_monster(target_ptr, m_idx, g_ptr);
114 if (((r_ptr->flags2 & RF2_MOVE_BODY) != 0) && ((r_ptr->flags1 & RF1_NEVER_MOVE) == 0) &&
115 (r_ptr->mexp > z_ptr->mexp) &&
116 can_cross && (g_ptr->m_idx != target_ptr->riding) &&
117 monster_can_cross_terrain(target_ptr, target_ptr->current_floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].feat, z_ptr, 0))
119 turn_flags_ptr->do_move = TRUE;
120 turn_flags_ptr->did_move_body = TRUE;
121 (void)set_monster_csleep(target_ptr, g_ptr->m_idx, 0);