OSDN Git Service

238595e60425a6d2105ca4f67731c458f44211a2
[hengbandforosx/hengbandosx.git] / src / object-activation / activation-breath.cpp
1 #include "object-activation/activation-breath.h"
2 #include "object-enchant/dragon-breaths-table.h"
3 #include "object/object-flags.h"
4 #include "player/player-status.h"
5 #include "spell-kind/spells-launcher.h"
6 #include "spell-realm/spells-hex.h"
7 #include "spell-realm/spells-song.h"
8 #include "spell/spell-types.h"
9 #include "status/element-resistance.h"
10 #include "sv-definition/sv-ring-types.h"
11 #include "system/object-type-definition.h"
12 #include "system/player-type-definition.h"
13 #include "target/target-getter.h"
14 #include "util/bit-flags-calculator.h"
15 #include "view/display-messages.h"
16
17 /*!
18  * @brief 発動によるブレスの属性をアイテムの耐性から選択し、実行を処理する。/ Dragon breath activation
19  * @details 対象となる耐性は dragonbreath_info テーブルを参照のこと。
20  * @param player_ptr プレイヤーへの参照ポインタ
21  * @param o_ptr 対象のオブジェクト構造体ポインタ
22  * @return 発動実行の是非を返す。
23  */
24 bool activate_dragon_breath(player_type *player_ptr, object_type *o_ptr)
25 {
26     DIRECTION dir;
27     if (!get_aim_dir(player_ptr, &dir))
28         return false;
29
30     auto resistance_flags = object_flags(o_ptr);
31
32     int type[20];
33     int n = 0;
34     concptr name[20];
35     for (int i = 0; dragonbreath_info[i].flag != 0; i++) {
36         if (resistance_flags.has(dragonbreath_info[i].flag)) {
37             type[n] = dragonbreath_info[i].type;
38             name[n] = dragonbreath_info[i].name;
39             n++;
40         }
41     }
42
43     if (n == 0)
44         return false;
45
46     if (music_singing_any(player_ptr))
47         stop_singing(player_ptr);
48
49     if (SpellHex(player_ptr).is_spelling_any()) {
50         (void)SpellHex(player_ptr).stop_all_spells();
51     }
52
53     int t = randint0(n);
54     msg_format(_("あなたは%sのブレスを吐いた。", "You breathe %s."), name[t]);
55     fire_breath(player_ptr, type[t], dir, 250, 4);
56     return true;
57 }
58
59 bool activate_breath_fire(player_type *player_ptr, object_type *o_ptr)
60 {
61     DIRECTION dir;
62     if (!get_aim_dir(player_ptr, &dir))
63         return false;
64
65     fire_breath(player_ptr, GF_FIRE, dir, 200, 2);
66     if ((o_ptr->tval == ItemKindType::RING) && (o_ptr->sval == SV_RING_FLAMES))
67         (void)set_oppose_fire(player_ptr, randint1(20) + 20, false);
68
69     return true;
70 }
71
72 bool activate_breath_cold(player_type *player_ptr, object_type *o_ptr)
73 {
74     DIRECTION dir;
75     if (!get_aim_dir(player_ptr, &dir))
76         return false;
77
78     fire_breath(player_ptr, GF_COLD, dir, 200, 2);
79     if ((o_ptr->tval == ItemKindType::RING) && (o_ptr->sval == SV_RING_ICE))
80         (void)set_oppose_cold(player_ptr, randint1(20) + 20, false);
81
82     return true;
83 }