OSDN Git Service

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