OSDN Git Service

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