OSDN Git Service

[Refactor] #37353 Separated hook-checker.c/h from object-hook.c/h
[hengband/hengband.git] / src / object-enchant / object-curse.c
1 #include "object-enchant/object-curse.h"
2 #include "object-enchant/item-feeling.h"
3 #include "object-enchant/tr-types.h"
4 #include "object-enchant/trc-types.h"
5 #include "object-hook/hook-armor.h"
6 #include "object-hook/hook-checker.h"
7 #include "object/object-flags.h"
8 #include "object/object-flavor.h"
9 #include "object/object-hook.h"
10 #include "util/bit-flags-calculator.h"
11 #include "view/display-messages.h"
12
13 #define MAX_CURSE 18
14 #define TRC_SPECIAL_MASK (TRC_TY_CURSE | TRC_AGGRAVATE)
15 #define TRC_HEAVY_MASK (TRC_TY_CURSE | TRC_AGGRAVATE | TRC_DRAIN_EXP | TRC_ADD_H_CURSE | TRC_CALL_DEMON | TRC_CALL_DRAGON | TRC_CALL_UNDEAD | TRC_TELEPORT)
16
17 /*!
18  * @brief アイテムに付加される可能性のある呪いを指定する。
19  * @param power 呪いの段階
20  * @param o_ptr 呪いをかけられる装備オブジェクトの構造体参照ポインタ
21  * @return 与える呪いのID
22  */
23 BIT_FLAGS get_curse(player_type *owner_ptr, int power, object_type *o_ptr)
24 {
25         BIT_FLAGS new_curse;
26
27         while (TRUE)
28         {
29                 new_curse = (1 << (randint0(MAX_CURSE)+4));
30                 if (power == 2)
31                 {
32                         if (!(new_curse & TRC_HEAVY_MASK)) continue;
33                 }
34                 else if (power == 1)
35                 {
36                         if (new_curse & TRC_SPECIAL_MASK) continue;
37                 }
38                 else if (power == 0)
39                 {
40                         if (new_curse & TRC_HEAVY_MASK) continue;
41                 }
42
43                 if (new_curse == TRC_LOW_MELEE && !object_is_weapon(owner_ptr, o_ptr)) continue;
44                 if (new_curse == TRC_LOW_AC && !object_is_armour(owner_ptr, o_ptr)) continue;
45                 break;
46         }
47
48         return new_curse;
49 }
50
51
52 /*!
53  * @brief 装備への呪い付加判定と付加処理
54  * @param owner_ptr プレーヤーへの参照ポインタ
55  * @param chance 呪いの基本確率
56  * @param heavy_chance さらに重い呪いとなる確率
57  * @return なし
58  */
59 void curse_equipment(player_type *owner_ptr, PERCENTAGE chance, PERCENTAGE heavy_chance)
60 {
61         if (randint1(100) > chance) return;
62
63         object_type *o_ptr = &owner_ptr->inventory_list[INVEN_RARM + randint0(12)];
64         if (!o_ptr->k_idx) return;
65         BIT_FLAGS oflgs[TR_FLAG_SIZE];
66         object_flags(owner_ptr, o_ptr, oflgs);
67         GAME_TEXT o_name[MAX_NLEN];
68         object_desc(owner_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
69
70         /* Extra, biased saving throw for blessed items */
71         if (have_flag(oflgs, TR_BLESSED))
72         {
73 #ifdef JP
74                 msg_format("祝福された%sは呪いを跳ね返した!", o_name);
75 #else
76                 msg_format("Your blessed %s resist%s cursing!", o_name, ((o_ptr->number > 1) ? "" : "s"));
77 #endif
78                 /* Hmmm -- can we wear multiple items? If not, this is unnecessary */
79                 return;
80         }
81
82         bool changed = FALSE;
83         int curse_power = 0;
84         if ((randint1(100) <= heavy_chance) &&
85             (object_is_artifact(o_ptr) || object_is_ego(o_ptr)))
86         {
87                 if (!(o_ptr->curse_flags & TRC_HEAVY_CURSE))
88                         changed = TRUE;
89                 o_ptr->curse_flags |= TRC_HEAVY_CURSE;
90                 o_ptr->curse_flags |= TRC_CURSED;
91                 curse_power++;
92         }
93         else
94         {
95                 if (!object_is_cursed(o_ptr))
96                         changed = TRUE;
97                 o_ptr->curse_flags |= TRC_CURSED;
98         }
99
100         if (heavy_chance >= 50) curse_power++;
101
102         BIT_FLAGS new_curse = get_curse(owner_ptr, curse_power, o_ptr);
103         if (!(o_ptr->curse_flags & new_curse))
104         {
105                 changed = TRUE;
106                 o_ptr->curse_flags |= new_curse;
107         }
108
109         if (changed)
110         {
111                 msg_format(_("悪意に満ちた黒いオーラが%sをとりまいた...", "There is a malignant black aura surrounding %s..."), o_name);
112                 o_ptr->feeling = FEEL_NONE;
113         }
114
115         owner_ptr->update |= PU_BONUS;
116 }