OSDN Git Service

[Refactor] #40483 Removed the inclusion of grid.h from grid.h
[hengband/hengband.git] / src / monster-floor / quantum-effect.c
1 #include "monster-floor/quantum-effect.h"
2 #include "floor/floor.h"
3 #include "monster-floor/monster-death.h"
4 #include "monster-floor/monster-remover.h"
5 #include "monster-race/monster-race.h"
6 #include "monster-race/race-flags1.h"
7 #include "monster-race/race-flags2.h"
8 #include "monster/monster-describer.h"
9 #include "monster/monster-info.h"
10 #include "monster/smart-learn-types.h"
11 #include "mspell/assign-monster-spell.h"
12 #include "spell-kind/spells-teleport.h"
13 #include "view/display-messages.h"
14
15 /*!
16  * @brief ユニークでない量子生物を消滅させる
17  * @param target_ptr プレーヤーへの参照ポインタ
18  * @param m_idx モンスターID
19  * @param see_m モンスターが視界内にいたらTRUE
20  * @return なし
21  */
22 static void vanish_nonunique(player_type *target_ptr, MONSTER_IDX m_idx, bool see_m)
23 {
24         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
25         if (see_m)
26         {
27                 GAME_TEXT m_name[MAX_NLEN];
28                 monster_desc(target_ptr, m_name, m_ptr, 0);
29                 msg_format(_("%sは消え去った!", "%^s disappears!"), m_name);
30         }
31
32         monster_death(target_ptr, m_idx, FALSE);
33         delete_monster_idx(target_ptr, m_idx);
34         if (is_pet(m_ptr) && !(m_ptr->ml))
35         {
36                 msg_print(_("少しの間悲しい気分になった。", "You feel sad for a moment."));
37         }
38 }
39
40
41 /*!
42  * todo ユニークとプレーヤーとの間でしか効果が発生しない。ユニークとその他のモンスター間では何もしなくてよい?
43  * @brief 量子生物ユニークの量子的効果 (ショート・テレポートまたは距離10のテレポート・アウェイ)を実行する
44  * @param target_ptr プレーヤーへの参照ポインタ
45  * @param m_idx モンスターID
46  * @param see_m モンスターが視界内にいたらTRUE
47  * @return なし
48  * @details
49  * プレーヤーが量子生物を観測しているか、量子生物がプレーヤーを観測している場合、互いの相対的な位置を確定させる
50  * 波動関数の収縮はテレポートではないので反テレポート無効
51  * @notes
52  * パターンは収縮どころか拡散しているが、この際気にしてはいけない
53  */
54 static void produce_quantum_effect(player_type *target_ptr, MONSTER_IDX m_idx, bool see_m)
55 {
56         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
57         bool coherent = los(target_ptr, m_ptr->fy, m_ptr->fx, target_ptr->y, target_ptr->x);
58         if (!see_m && !coherent) return;
59
60         if (see_m)
61         {
62                 GAME_TEXT m_name[MAX_NLEN];
63                 monster_desc(target_ptr, m_name, m_ptr, 0);
64                 msg_format(_("%sは量子的効果を起こした!", "%^s produced a decoherence!"), m_name);
65         }
66         else
67         {
68                 msg_print(_("量子的効果が起こった!", "A decoherence was produced!"));
69         }
70
71         bool target = one_in_(2);
72         const int blink = 32 * 5 + 4;
73         if (target)
74         {
75                 (void)monspell_to_monster(target_ptr, blink, m_ptr->fy, m_ptr->fx, m_idx, m_idx, TRUE);
76         }
77         else
78         {
79                 teleport_player_away(m_idx, target_ptr, 10, TRUE);
80         }
81 }
82
83
84 /*!
85  * @brief 量子生物の量子的効果を実行する
86  * @param target_ptr プレーヤーへの参照ポインタ
87  * @param m_idx モンスターID
88  * @param see_m モンスターが視界内にいたらTRUE
89  * @return モンスターが量子的効果により消滅したらTRUE
90  */
91 bool process_quantum_effect(player_type *target_ptr, MONSTER_IDX m_idx, bool see_m)
92 {
93         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
94         monster_race *r_ptr = &r_info[m_ptr->r_idx];
95         if ((r_ptr->flags2 & RF2_QUANTUM) == 0) return FALSE;
96         if (!randint0(2)) return FALSE;
97         if (randint0((m_idx % 100) + 10)) return FALSE;
98
99         bool can_disappear = (r_ptr->flags1 & RF1_UNIQUE) == 0;
100         can_disappear &= (r_ptr->flags1 & RF1_QUESTOR) == 0;
101         if (can_disappear)
102         {
103                 vanish_nonunique(target_ptr, m_idx, see_m);
104                 return TRUE;
105         }
106
107         produce_quantum_effect(target_ptr, m_idx, see_m);
108         return FALSE;
109 }