OSDN Git Service

Merge branch 'master' of https://github.com/hengband/hengband
[hengbandforosx/hengbandosx.git] / src / object-hook / hook-expendable.cpp
1 #include "object-hook/hook-expendable.h"
2 #include "artifact/fixed-art-types.h"
3 #include "core/window-redrawer.h"
4 #include "monster-race/monster-race.h"
5 #include "object-enchant/item-feeling.h"
6 #include "object-enchant/special-object-flags.h"
7 #include "object/tval-types.h"
8 #include "perception/object-perception.h"
9 #include "player-base/player-race.h"
10 #include "player-info/mimic-info-table.h"
11 #include "sv-definition/sv-lite-types.h"
12 #include "sv-definition/sv-other-types.h"
13 #include "system/baseitem-info.h"
14 #include "system/item-entity.h"
15 #include "system/monster-race-info.h"
16 #include "system/player-type-definition.h"
17 #include "system/redrawing-flags-updater.h"
18 #include "util/string-processor.h"
19
20 /*!
21  * @brief オブジェクトをプレイヤーが食べることができるかを判定する /
22  * Hook to determine if an object is eatable
23  * @param o_ptr 判定したいオブジェクトの構造体参照ポインタ
24  * @return 食べることが可能ならばTRUEを返す
25  */
26 bool item_tester_hook_eatable(PlayerType *player_ptr, const ItemEntity *o_ptr)
27 {
28     const auto tval = o_ptr->bi_key.tval();
29     if (tval == ItemKindType::FOOD) {
30         return true;
31     }
32
33     auto food_type = PlayerRace(player_ptr).food();
34     if (food_type == PlayerRaceFoodType::MANA) {
35         if (o_ptr->is_wand_staff()) {
36             return true;
37         }
38     } else if (food_type == PlayerRaceFoodType::CORPSE) {
39         auto corpse_r_idx = i2enum<MonsterRaceId>(o_ptr->pval);
40         if ((o_ptr->bi_key == BaseitemKey(ItemKindType::CORPSE, SV_CORPSE)) && angband_strchr("pht", monraces_info[corpse_r_idx].d_char)) {
41             return true;
42         }
43     }
44
45     return false;
46 }
47
48 /*!
49  * @brief オブジェクトをプレイヤーが飲むことができるかを判定する /
50  * Hook to determine if an object can be quaffed
51  * @param o_ptr 判定したいオブジェクトの構造体参照ポインタ
52  * @return 飲むことが可能ならばTRUEを返す
53  */
54 bool item_tester_hook_quaff(PlayerType *player_ptr, const ItemEntity *o_ptr)
55 {
56     const auto &bi_key = o_ptr->bi_key;
57     if (bi_key.tval() == ItemKindType::POTION) {
58         return true;
59     }
60
61     return (PlayerRace(player_ptr).food() == PlayerRaceFoodType::OIL) && (bi_key == BaseitemKey(ItemKindType::FLASK, SV_FLASK_OIL));
62 }
63
64 /*!
65  * @brief 破壊可能なアイテムかを返す /
66  * Determines whether an object can be destroyed, and makes fake inscription.
67  * @param o_ptr 破壊可能かを確認したいオブジェクトの構造体参照ポインタ
68  * @return オブジェクトが破壊可能ならばTRUEを返す
69  */
70 bool can_player_destroy_object(PlayerType *player_ptr, ItemEntity *o_ptr)
71 {
72     /* Artifacts cannot be destroyed */
73     if (!o_ptr->is_fixed_or_random_artifact()) {
74         return true;
75     }
76
77     if (!o_ptr->is_known()) {
78         byte feel = FEEL_SPECIAL;
79         if (o_ptr->is_cursed() || o_ptr->is_broken()) {
80             feel = FEEL_TERRIBLE;
81         }
82
83         o_ptr->feeling = feel;
84         o_ptr->ident |= IDENT_SENSE;
85         auto &rfu = RedrawingFlagsUpdater::get_instance();
86         rfu.set_flag(StatusRedrawingFlag::COMBINATION);
87         player_ptr->window_flags |= (PW_INVENTORY | PW_EQUIPMENT);
88         return false;
89     }
90
91     return false;
92 }