OSDN Git Service

d0b83ab79af0938cd0688f8630636e0f7c19fe29
[hengbandforosx/hengbandosx.git] / src / object-hook / hook-magic.cpp
1 #include "object-hook/hook-magic.h"
2 #include "inventory/inventory-slot-types.h"
3 #include "object-enchant/tr-types.h"
4 #include "object/object-flags.h"
5 #include "perception/object-perception.h"
6 #include "player-info/class-info.h"
7 #include "player/player-realm.h"
8 #include "realm/realm-names-table.h"
9 #include "system/object-type-definition.h"
10 #include "system/player-type-definition.h"
11 #include "util/bit-flags-calculator.h"
12 #include "util/enum-converter.h"
13
14 /*!
15  * @brief オブジェクトをプレイヤーが簡易使用コマンドで利用できるかを判定する /
16  * Hook to determine if an object is useable
17  * @param o_ptr 判定したいオブジェクトの構造体参照ポインタ
18  * @return 利用可能ならばTRUEを返す
19  */
20 bool item_tester_hook_use(player_type *player_ptr, const object_type *o_ptr)
21 {
22     if (o_ptr->tval == player_ptr->tval_ammo)
23         return true;
24
25     switch (o_ptr->tval) {
26     case ItemKindType::SPIKE:
27     case ItemKindType::STAFF:
28     case ItemKindType::WAND:
29     case ItemKindType::ROD:
30     case ItemKindType::SCROLL:
31     case ItemKindType::POTION:
32     case ItemKindType::FOOD:
33         return true;
34     default:
35         if (!o_ptr->is_known()) {
36             return false;
37         }
38
39         for (int i = INVEN_MAIN_HAND; i < INVEN_TOTAL; i++) {
40             if (&player_ptr->inventory_list[i] == o_ptr) {
41                 auto flags = object_flags(o_ptr);
42                 if (flags.has(TR_ACTIVATE))
43                     return true;
44             }
45         }
46
47         return false;
48     }
49 }
50
51 /*!
52  * @brief オブジェクトがプレイヤーが使用可能な魔道書かどうかを判定する
53  * @param o_ptr 判定したいオブ会ジェクトの構造体参照ポインタ
54  * @return 学習できる魔道書ならばTRUEを返す
55  */
56 bool item_tester_learn_spell(player_type *player_ptr, const object_type *o_ptr)
57 {
58     int32_t choices = realm_choices2[player_ptr->pclass];
59     if (player_ptr->pclass == CLASS_PRIEST) {
60         if (is_good_realm(player_ptr->realm1)) {
61             choices &= ~(CH_DEATH | CH_DAEMON);
62         } else {
63             choices &= ~(CH_LIFE | CH_CRUSADE);
64         }
65     }
66
67     if ((o_ptr->tval < ItemKindType::LIFE_BOOK) || (o_ptr->tval > ItemKindType::HEX_BOOK))
68         return false;
69
70     if ((o_ptr->tval == ItemKindType::MUSIC_BOOK) && (player_ptr->pclass == CLASS_BARD))
71         return true;
72     else if (!is_magic(tval2realm(o_ptr->tval)))
73         return false;
74
75     return (get_realm1_book(player_ptr) == o_ptr->tval) || (get_realm2_book(player_ptr) == o_ptr->tval)
76         || (choices & (0x0001U << (tval2realm(o_ptr->tval) - 1)));
77 }
78
79 /*!
80  * @brief オブジェクトが高位の魔法書かどうかを判定する
81  * @param o_ptr 判定したいオブジェクトの構造体参照ポインタ
82  * @return オブジェクトが高位の魔法書ならばTRUEを返す
83  */
84 bool item_tester_high_level_book(const object_type *o_ptr)
85 {
86     if ((o_ptr->tval == ItemKindType::LIFE_BOOK) || (o_ptr->tval == ItemKindType::SORCERY_BOOK) || (o_ptr->tval == ItemKindType::NATURE_BOOK) || (o_ptr->tval == ItemKindType::CHAOS_BOOK)
87         || (o_ptr->tval == ItemKindType::DEATH_BOOK) || (o_ptr->tval == ItemKindType::TRUMP_BOOK) || (o_ptr->tval == ItemKindType::CRAFT_BOOK) || (o_ptr->tval == ItemKindType::DEMON_BOOK)
88         || (o_ptr->tval == ItemKindType::CRUSADE_BOOK) || (o_ptr->tval == ItemKindType::MUSIC_BOOK) || (o_ptr->tval == ItemKindType::HEX_BOOK)) {
89         if (o_ptr->sval > 1)
90             return true;
91         else
92             return false;
93     }
94
95     return false;
96 }