OSDN Git Service

Merge pull request #3569 from sikabane-works/release/3.0.0.88-alpha
[hengbandforosx/hengbandosx.git] / src / object / object-flags.cpp
1 #include "object/object-flags.h"
2 #include "mind/mind-weaponsmith.h"
3 #include "object-enchant/object-ego.h"
4 #include "object-enchant/tr-types.h"
5 #include "object/tval-types.h"
6 #include "perception/object-perception.h"
7 #include "smith/object-smith.h"
8 #include "system/artifact-type-definition.h"
9 #include "system/baseitem-info.h"
10 #include "system/item-entity.h"
11 #include "system/player-type-definition.h"
12 #include "util/bit-flags-calculator.h"
13
14 /*!
15  * @brief エゴ光源のフラグを修正する
16  *
17  * 寿命のある光源で寿命が0ターンの時、光源エゴアイテムに起因するフラグは
18  * 灼熱エゴの火炎耐性を除き付与されないようにする。
19  *
20  * @param o_ptr フラグ取得元のオブジェクト構造体ポインタ
21  * @param flags フラグ情報を受け取る配列
22  */
23 static void modify_ego_lite_flags(const ItemEntity *o_ptr, TrFlags &flags)
24 {
25     if (o_ptr->bi_key.tval() != ItemKindType::LITE) {
26         return;
27     }
28
29     if (!o_ptr->is_lite_requiring_fuel() || o_ptr->fuel != 0) {
30         return;
31     }
32
33     switch (o_ptr->ego_idx) {
34     case EgoType::LITE_AURA_FIRE:
35         flags.reset(TR_SH_FIRE);
36         return;
37     case EgoType::LITE_INFRA:
38         flags.reset(TR_INFRA);
39         return;
40     case EgoType::LITE_EYE:
41         flags.reset({ TR_RES_BLIND, TR_SEE_INVIS });
42         return;
43     default:
44         return;
45     }
46 }
47
48 /*!
49  * @brief オブジェクトのフラグ類を配列に与える
50  * @param o_ptr フラグ取得元のオブジェクト構造体ポインタ
51  * @param flags フラグ情報を受け取る配列
52  */
53 TrFlags object_flags(const ItemEntity *o_ptr)
54 {
55     const auto &baseitem = o_ptr->get_baseitem();
56     auto flags = baseitem.flags;
57
58     if (o_ptr->is_fixed_artifact()) {
59         flags = o_ptr->get_fixed_artifact().flags;
60     }
61
62     if (o_ptr->is_ego()) {
63         const auto &ego = o_ptr->get_ego();
64         flags.set(ego.flags);
65         modify_ego_lite_flags(o_ptr, flags);
66     }
67
68     flags.set(o_ptr->art_flags);
69     if (auto effect = Smith::object_effect(o_ptr); effect.has_value()) {
70         auto tr_flags = Smith::get_effect_tr_flags(effect.value());
71         flags.set(tr_flags);
72     }
73
74     if (Smith::object_activation(o_ptr).has_value()) {
75         flags.set(TR_ACTIVATE);
76     }
77
78     return flags;
79 }
80
81 /*!
82  * @brief オブジェクトの明示されているフラグ類を取得する
83  * Obtain the "flags" for an item which are known to the player
84  * @param o_ptr フラグ取得元のオブジェクト構造体ポインタ
85  * @param flags フラグ情報を受け取る配列
86  */
87 TrFlags object_flags_known(const ItemEntity *o_ptr)
88 {
89     TrFlags flags{};
90     if (!o_ptr->is_aware()) {
91         return flags;
92     }
93
94     const auto &baseitem = o_ptr->get_baseitem();
95     flags = baseitem.flags;
96     if (!o_ptr->is_known()) {
97         return flags;
98     }
99
100     if (o_ptr->is_ego()) {
101         const auto &ego = o_ptr->get_ego();
102         flags.set(ego.flags);
103         modify_ego_lite_flags(o_ptr, flags);
104     }
105
106     if (o_ptr->is_fully_known()) {
107         if (o_ptr->is_fixed_artifact()) {
108             flags = o_ptr->get_fixed_artifact().flags;
109         }
110
111         flags.set(o_ptr->art_flags);
112     }
113
114     if (auto effect = Smith::object_effect(o_ptr); effect.has_value()) {
115         auto tr_flags = Smith::get_effect_tr_flags(effect.value());
116         flags.set(tr_flags);
117     }
118
119     if (Smith::object_activation(o_ptr).has_value()) {
120         flags.set(TR_ACTIVATE);
121     }
122
123     return flags;
124 }