OSDN Git Service

df1e592be56cb01e54dd0b6cf6c9219f28b99c34
[hengbandforosx/hengbandosx.git] / src / artifact / artifact-info.cpp
1 /*!
2  * @file artifact-info.cpp
3  * @brief アーティファクトの発動効果取得関数定義
4  */
5
6 #include "artifact/artifact-info.h"
7 #include "artifact/random-art-effects.h"
8 #include "object-enchant/activation-info-table.h"
9 #include "object-enchant/object-ego.h"
10 #include "object-enchant/tr-types.h"
11 #include "smith/object-smith.h"
12 #include "system/artifact-type-definition.h"
13 #include "system/baseitem-info-definition.h"
14 #include "system/object-type-definition.h"
15 #include "util/bit-flags-calculator.h"
16 #include "util/enum-converter.h"
17
18 /*!
19  * @brief オブジェクトから能力発動IDを取得する。
20  * @details いくつかのケースで定義されている発動効果から、
21  * 鍛冶師による付与>固定アーティファクト>エゴ>ランダムアーティファクト>ベースアイテムの優先順位で走査していく。
22  * @param o_ptr 対象のオブジェクト構造体ポインタ
23  * @return 発動効果のIDを返す
24  */
25 RandomArtActType activation_index(const ItemEntity *o_ptr)
26 {
27     if (auto act_idx = Smith::object_activation(o_ptr); act_idx.has_value()) {
28         return act_idx.value();
29     }
30
31     if (o_ptr->is_fixed_artifact()) {
32         const auto &fixed_artifact = artifacts_info.at(o_ptr->fixed_artifact_idx);
33         if (fixed_artifact.flags.has(TR_ACTIVATE)) {
34             return fixed_artifact.act_idx;
35         }
36     }
37
38     if (o_ptr->is_ego() && egos_info[o_ptr->ego_idx].flags.has(TR_ACTIVATE)) {
39         return egos_info[o_ptr->ego_idx].act_idx;
40     }
41
42     if (!o_ptr->is_random_artifact() && baseitems_info[o_ptr->k_idx].flags.has(TR_ACTIVATE)) {
43         return baseitems_info[o_ptr->k_idx].act_idx;
44     }
45
46     return o_ptr->activation_id;
47 }
48
49 /*!
50  * @brief オブジェクトから発動効果構造体のポインタを取得する。
51  * @details activation_index() 関数の結果から参照する。
52  * @param o_ptr 対象のオブジェクト構造体ポインタ
53  * @return 発動効果構造体のポインタを返す
54  */
55 std::optional<const activation_type *> find_activation_info(const ItemEntity *o_ptr)
56 {
57     const auto index = activation_index(o_ptr);
58     for (const auto &p : activation_info) {
59         if (p.index == index) {
60             return &p;
61         }
62     }
63
64     return std::nullopt;
65 }