2 * @brief モンスターの逃走に関する処理
7 #include "monster-floor/monster-runaway.h"
8 #include "core/disturbance.h"
9 #include "dungeon/quest-completion-checker.h"
10 #include "grid/grid.h"
11 #include "monster-floor/monster-remover.h"
12 #include "monster-race/monster-race.h"
13 #include "monster-race/race-flags1.h"
14 #include "monster-race/race-flags2.h"
15 #include "monster-race/race-flags7.h"
16 #include "monster-race/race-indice-types.h"
17 #include "monster/monster-describer.h"
18 #include "monster/monster-info.h"
19 #include "monster/monster-processor-util.h"
20 #include "pet/pet-fall-off.h"
21 #include "system/angband-system.h"
22 #include "system/floor-type-definition.h"
23 #include "system/monster-entity.h"
24 #include "system/monster-race-info.h"
25 #include "system/player-type-definition.h"
26 #include "target/projection-path-calculator.h"
27 #include "view/display-messages.h"
30 * @brief monspeak.txt において、発話ではなく行動のみが描写されているモンスターであるかを調べる
31 * @param r_idx モンスター種族ID
32 * @return 会話内容が行動のみのモンスターか否か
34 static bool is_acting_monster(const MonsterRaceId r_idx)
36 auto is_acting_monster = r_idx == MonsterRaceId::GRIP;
37 is_acting_monster |= r_idx == MonsterRaceId::WOLF;
38 is_acting_monster |= r_idx == MonsterRaceId::FANG;
39 return is_acting_monster;
43 * @brief HPが1/3未満になった友好的なユニークモンスターの逃走処理を行う
44 * @param player_ptr プレイヤーへの参照ポインタ
45 * @param is_riding_mon 騎乗状態ならばTRUE
46 * @param m_ptr モンスターへの参照ポインタ
47 * @param m_name モンスター名称
49 static void escape_monster(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MonsterEntity *m_ptr, concptr m_name)
51 if (turn_flags_ptr->is_riding_mon) {
52 msg_format(_("%sはあなたの束縛から脱出した。", "%s^ succeeded to escape from your restriction!"), m_name);
53 if (process_fall_off_horse(player_ptr, -1, false)) {
54 msg_print(_("地面に落とされた。", "You have fallen from the pet you were riding."));
58 if (turn_flags_ptr->see_m) {
59 static constexpr auto flags = {
60 MonsterSpeakType::SPEAK_ALL,
61 MonsterSpeakType::SPEAK_BATTLE,
62 MonsterSpeakType::SPEAK_FEAR,
65 auto speak = m_ptr->get_monrace().speak_flags.has_any_of(flags);
66 speak &= !is_acting_monster(m_ptr->r_idx);
67 speak &= player_ptr->current_floor_ptr->has_los({ m_ptr->fy, m_ptr->fx });
68 speak &= projectable(player_ptr, m_ptr->fy, m_ptr->fx, player_ptr->y, player_ptr->x);
70 msg_format(_("%s^「ピンチだ!退却させてもらう!」", "%s^ says 'It is the pinch! I will retreat'."), m_name);
73 msg_format(_("%s^がテレポート・レベルの巻物を読んだ。", "%s^ reads a scroll of teleport level."), m_name);
74 msg_format(_("%s^が消え去った。", "%s^ disappears."), m_name);
77 if (turn_flags_ptr->is_riding_mon && process_fall_off_horse(player_ptr, -1, false)) {
78 msg_print(_("地面に落とされた。", "You have fallen from the pet you were riding."));
83 * @brief ペットや友好的なモンスターがフロアから逃げる処理を行う
84 * @param player_ptr プレイヤーへの参照ポインタ
85 * @param m_idx モンスターID
86 * @param is_riding_mon 騎乗状態ならばTRUE
87 * @param see_m モンスターが視界内にいたらTRUE
88 * @return モンスターがフロアから消えたらTRUE
90 bool runaway_monster(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx)
92 auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
93 auto *r_ptr = &m_ptr->get_monrace();
94 bool can_runaway = m_ptr->is_pet() || m_ptr->is_friendly();
95 can_runaway &= (r_ptr->kind_flags.has(MonsterKindType::UNIQUE)) || (r_ptr->population_flags.has(MonsterPopulationType::NAZGUL));
96 can_runaway &= !AngbandSystem::get_instance().is_phase_out();
101 static int riding_pinch = 0;
103 if (m_ptr->hp >= m_ptr->maxhp / 3) {
104 /* Reset the counter */
105 if (turn_flags_ptr->is_riding_mon) {
112 const auto m_name = monster_desc(player_ptr, m_ptr, 0);
113 if (turn_flags_ptr->is_riding_mon && riding_pinch < 2) {
115 _("%sは傷の痛さの余りあなたの束縛から逃れようとしている。", "%s^ seems to be in so much pain and tries to escape from your restriction."), m_name.data());
117 disturb(player_ptr, true, true);
121 escape_monster(player_ptr, turn_flags_ptr, m_ptr, m_name.data());
122 QuestCompletionChecker(player_ptr, m_ptr).complete();
123 delete_monster_idx(player_ptr, m_idx);