OSDN Git Service

Merge pull request #3532 from sikabane-works/release/3.0.0.87-alpha
[hengbandforosx/hengbandosx.git] / src / mind / mind-priest.cpp
1 #include "mind/mind-priest.h"
2 #include "core/window-redrawer.h"
3 #include "flavor/flavor-describer.h"
4 #include "flavor/object-flavor-types.h"
5 #include "floor/floor-object.h"
6 #include "object-enchant/item-feeling.h"
7 #include "object-enchant/special-object-flags.h"
8 #include "object-enchant/tr-types.h"
9 #include "object-enchant/trc-types.h"
10 #include "object-hook/hook-weapon.h"
11 #include "object/item-tester-hooker.h"
12 #include "object/item-use-flags.h"
13 #include "object/object-flags.h"
14 #include "racial/racial-android.h"
15 #include "system/item-entity.h"
16 #include "system/player-type-definition.h"
17 #include "system/redrawing-flags-updater.h"
18 #include "util/bit-flags-calculator.h"
19 #include "view/display-messages.h"
20
21 /*!
22  * @brief 武器の祝福処理 /
23  * Bless a weapon
24  * @return ターン消費を要する処理を行ったならばTRUEを返す
25  */
26 bool bless_weapon(PlayerType *player_ptr)
27 {
28     concptr q = _("どのアイテムを祝福しますか?", "Bless which weapon? ");
29     concptr s = _("祝福できる武器がありません。", "You have no weapon to bless.");
30
31     OBJECT_IDX item;
32     constexpr BIT_FLAGS options = USE_EQUIP | USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT;
33     auto *o_ptr = choose_object(player_ptr, &item, q, s, options, FuncItemTester(&ItemEntity::is_weapon));
34     if (!o_ptr) {
35         return false;
36     }
37
38     const auto item_name = describe_flavor(player_ptr, o_ptr, OD_OMIT_PREFIX | OD_NAME_ONLY);
39     auto item_flags = object_flags(o_ptr);
40     auto &rfu = RedrawingFlagsUpdater::get_instance();
41     if (o_ptr->is_cursed()) {
42         auto can_disturb_blessing = o_ptr->curse_flags.has(CurseTraitType::HEAVY_CURSE) && (randint1(100) < 33);
43         can_disturb_blessing |= item_flags.has(TR_ADD_L_CURSE);
44         can_disturb_blessing |= item_flags.has(TR_ADD_H_CURSE);
45         can_disturb_blessing |= o_ptr->curse_flags.has(CurseTraitType::PERSISTENT_CURSE);
46         can_disturb_blessing |= o_ptr->curse_flags.has(CurseTraitType::PERMA_CURSE);
47         if (can_disturb_blessing) {
48 #ifdef JP
49             msg_format("%sを覆う黒いオーラは祝福を跳ね返した!", item_name.data());
50 #else
51             msg_format("The black aura on %s %s disrupts the blessing!", ((item >= 0) ? "your" : "the"), item_name.data());
52 #endif
53
54             return true;
55         }
56
57 #ifdef JP
58         msg_format("%s から邪悪なオーラが消えた。", item_name.data());
59 #else
60         msg_format("A malignant aura leaves %s %s.", ((item >= 0) ? "your" : "the"), item_name.data());
61 #endif
62         o_ptr->curse_flags.clear();
63         set_bits(o_ptr->ident, IDENT_SENSE);
64         o_ptr->feeling = FEEL_NONE;
65         rfu.set_flag(StatusRecalculatingFlag::BONUS);
66         static constexpr auto flags = {
67             SubWindowRedrawingFlag::EQUIPMENT,
68             SubWindowRedrawingFlag::FLOOR_ITEMS,
69             SubWindowRedrawingFlag::FOUND_ITEMS,
70         };
71         rfu.set_flags(flags);
72     }
73
74     /*
75      * Next, we try to bless it. Artifacts have a 1/3 chance of
76      * being blessed, otherwise, the operation simply disenchants
77      * them, godly power negating the magic. Ok, the explanation
78      * is silly, but otherwise priests would always bless every
79      * artifact weapon they find. Ego weapons and normal weapons
80      * can be blessed automatically.
81      */
82     if (item_flags.has(TR_BLESSED)) {
83 #ifdef JP
84         msg_format("%s は既に祝福されている。", item_name.data());
85 #else
86         msg_format("%s %s %s blessed already.", ((item >= 0) ? "Your" : "The"), item_name.data(), ((o_ptr->number > 1) ? "were" : "was"));
87 #endif
88         return true;
89     }
90
91     if (!(o_ptr->is_fixed_or_random_artifact() || o_ptr->is_ego()) || one_in_(3)) {
92 #ifdef JP
93         msg_format("%sは輝いた!", item_name.data());
94 #else
95         msg_format("%s %s shine%s!", ((item >= 0) ? "Your" : "The"), item_name.data(), ((o_ptr->number > 1) ? "" : "s"));
96 #endif
97         o_ptr->art_flags.set(TR_BLESSED);
98         o_ptr->discount = 99;
99     } else {
100         bool dis_happened = false;
101         msg_print(_("その武器は祝福を嫌っている!", "The weapon resists your blessing!"));
102
103         /* Disenchant tohit */
104         if (o_ptr->to_h > 0) {
105             o_ptr->to_h--;
106             dis_happened = true;
107         }
108
109         if ((o_ptr->to_h > 5) && (randint0(100) < 33)) {
110             o_ptr->to_h--;
111         }
112
113         /* Disenchant todam */
114         if (o_ptr->to_d > 0) {
115             o_ptr->to_d--;
116             dis_happened = true;
117         }
118
119         if ((o_ptr->to_d > 5) && (randint0(100) < 33)) {
120             o_ptr->to_d--;
121         }
122
123         /* Disenchant toac */
124         if (o_ptr->to_a > 0) {
125             o_ptr->to_a--;
126             dis_happened = true;
127         }
128
129         if ((o_ptr->to_a > 5) && (randint0(100) < 33)) {
130             o_ptr->to_a--;
131         }
132
133         if (dis_happened) {
134             msg_print(_("周囲が凡庸な雰囲気で満ちた...", "There is a static feeling in the air..."));
135
136 #ifdef JP
137             msg_format("%s は劣化した!", item_name.data());
138 #else
139             msg_format("%s %s %s disenchanted!", ((item >= 0) ? "Your" : "The"), item_name.data(), ((o_ptr->number > 1) ? "were" : "was"));
140 #endif
141         }
142     }
143
144     rfu.set_flag(StatusRecalculatingFlag::BONUS);
145     static constexpr auto flags_swrf = {
146         SubWindowRedrawingFlag::EQUIPMENT,
147         SubWindowRedrawingFlag::PLAYER,
148         SubWindowRedrawingFlag::FLOOR_ITEMS,
149         SubWindowRedrawingFlag::FOUND_ITEMS,
150     };
151     rfu.set_flags(flags_swrf);
152     calc_android_exp(player_ptr);
153     return true;
154 }