OSDN Git Service

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