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-indice-types.h"
14 #include "monster/monster-describer.h"
15 #include "monster/monster-info.h"
16 #include "monster/monster-processor-util.h"
17 #include "pet/pet-fall-off.h"
18 #include "system/angband-system.h"
19 #include "system/floor-type-definition.h"
20 #include "system/monster-entity.h"
21 #include "system/monster-race-info.h"
22 #include "system/player-type-definition.h"
23 #include "target/projection-path-calculator.h"
24 #include "view/display-messages.h"
27 * @brief monspeak.txt において、発話ではなく行動のみが描写されているモンスターであるかを調べる
28 * @param r_idx モンスター種族ID
29 * @return 会話内容が行動のみのモンスターか否か
31 static bool is_acting_monster(const MonsterRaceId r_idx)
33 auto is_acting_monster = r_idx == MonsterRaceId::GRIP;
34 is_acting_monster |= r_idx == MonsterRaceId::WOLF;
35 is_acting_monster |= r_idx == MonsterRaceId::FANG;
36 return is_acting_monster;
40 * @brief HPが1/3未満になった友好的なユニークモンスターの逃走処理を行う
41 * @param player_ptr プレイヤーへの参照ポインタ
42 * @param is_riding_mon 騎乗状態ならばTRUE
43 * @param m_ptr モンスターへの参照ポインタ
44 * @param m_name モンスター名称
46 static void escape_monster(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MonsterEntity *m_ptr, concptr m_name)
48 if (turn_flags_ptr->is_riding_mon) {
49 msg_format(_("%sはあなたの束縛から脱出した。", "%s^ succeeded to escape from your restriction!"), m_name);
50 if (process_fall_off_horse(player_ptr, -1, false)) {
51 msg_print(_("地面に落とされた。", "You have fallen from the pet you were riding."));
55 if (turn_flags_ptr->see_m) {
56 static constexpr auto flags = {
57 MonsterSpeakType::SPEAK_ALL,
58 MonsterSpeakType::SPEAK_BATTLE,
59 MonsterSpeakType::SPEAK_FEAR,
62 auto speak = m_ptr->get_monrace().speak_flags.has_any_of(flags);
63 speak &= !is_acting_monster(m_ptr->r_idx);
64 speak &= player_ptr->current_floor_ptr->has_los({ m_ptr->fy, m_ptr->fx });
65 speak &= projectable(player_ptr, m_ptr->fy, m_ptr->fx, player_ptr->y, player_ptr->x);
67 msg_format(_("%s^「ピンチだ!退却させてもらう!」", "%s^ says 'It is the pinch! I will retreat'."), m_name);
70 msg_format(_("%s^がテレポート・レベルの巻物を読んだ。", "%s^ reads a scroll of teleport level."), m_name);
71 msg_format(_("%s^が消え去った。", "%s^ disappears."), m_name);
74 if (turn_flags_ptr->is_riding_mon && process_fall_off_horse(player_ptr, -1, false)) {
75 msg_print(_("地面に落とされた。", "You have fallen from the pet you were riding."));
80 * @brief ペットや友好的なモンスターがフロアから逃げる処理を行う
81 * @param player_ptr プレイヤーへの参照ポインタ
82 * @param m_idx モンスターID
83 * @param is_riding_mon 騎乗状態ならばTRUE
84 * @param see_m モンスターが視界内にいたらTRUE
85 * @return モンスターがフロアから消えたらTRUE
87 bool runaway_monster(PlayerType *player_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx)
89 auto *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
90 auto *r_ptr = &m_ptr->get_monrace();
91 bool can_runaway = m_ptr->is_pet() || m_ptr->is_friendly();
92 can_runaway &= (r_ptr->kind_flags.has(MonsterKindType::UNIQUE)) || (r_ptr->population_flags.has(MonsterPopulationType::NAZGUL));
93 can_runaway &= !AngbandSystem::get_instance().is_phase_out();
98 static int riding_pinch = 0;
100 if (m_ptr->hp >= m_ptr->maxhp / 3) {
101 /* Reset the counter */
102 if (turn_flags_ptr->is_riding_mon) {
109 const auto m_name = monster_desc(player_ptr, m_ptr, 0);
110 if (turn_flags_ptr->is_riding_mon && riding_pinch < 2) {
112 _("%sは傷の痛さの余りあなたの束縛から逃れようとしている。", "%s^ seems to be in so much pain and tries to escape from your restriction."), m_name.data());
114 disturb(player_ptr, true, true);
118 escape_monster(player_ptr, turn_flags_ptr, m_ptr, m_name.data());
119 QuestCompletionChecker(player_ptr, m_ptr).complete();
120 delete_monster_idx(player_ptr, m_idx);