OSDN Git Service

[Refactor] struct player_type を class PlayerType に置換。
[hengbandforosx/hengbandosx.git] / src / autopick / autopick-destroyer.cpp
1 /*!
2  * @brief 自動破壊の実行
3  * @date 2020/04/25
4  * @author Hourier
5  */
6
7 #include "autopick/autopick-destroyer.h"
8 #include "autopick-methods-table.h"
9 #include "autopick/autopick-util.h"
10 #include "core/disturbance.h"
11 #include "core/player-update-types.h"
12 #include "flavor/flavor-describer.h"
13 #include "game-option/auto-destruction-options.h"
14 #include "game-option/input-options.h"
15 #include "monster-race/monster-race.h"
16 #include "object-enchant/object-ego.h"
17 #include "object-enchant/special-object-flags.h"
18 #include "object-hook/hook-expendable.h"
19 #include "object-hook/hook-quest.h"
20 #include "object-hook/hook-weapon.h"
21 #include "object/object-mark-types.h"
22 #include "object/object-value.h"
23 #include "perception/object-perception.h"
24 #include "player-info/race-types.h"
25 #include "sv-definition/sv-other-types.h"
26 #include "sv-definition/sv-wand-types.h"
27 #include "system/monster-race-definition.h"
28 #include "system/object-type-definition.h"
29 #include "system/player-type-definition.h"
30 #include "util/string-processor.h"
31 #include "view/display-messages.h"
32
33 /*!
34  * @brief クラス依存のアイテム破壊を調べる
35  * @param player_ptr プレイヤーへの参照ポインタ
36  * @param o_ptr アイテムへの参照ポインタ
37  * @return 特別なクラス、かつそのクラス特有のアイテムであればFALSE、それ以外はTRUE
38  */
39 static bool is_leave_special_item(PlayerType *player_ptr, object_type *o_ptr)
40 {
41     if (!leave_special)
42         return true;
43
44     if (player_ptr->prace == PlayerRaceType::BALROG) {
45         if (o_ptr->tval == ItemKindType::CORPSE && o_ptr->sval == SV_CORPSE && angband_strchr("pht", r_info[o_ptr->pval].d_char))
46             return false;
47     } else if (player_ptr->pclass == PlayerClassType::ARCHER) {
48         if (o_ptr->tval == ItemKindType::SKELETON || (o_ptr->tval == ItemKindType::CORPSE && o_ptr->sval == SV_SKELETON))
49             return false;
50     } else if (player_ptr->pclass == PlayerClassType::NINJA) {
51         if (o_ptr->tval == ItemKindType::LITE && o_ptr->name2 == EGO_LITE_DARKNESS && o_ptr->is_known())
52             return false;
53     } else if (player_ptr->pclass == PlayerClassType::BEASTMASTER || player_ptr->pclass == PlayerClassType::CAVALRY) {
54         if (o_ptr->tval == ItemKindType::WAND && o_ptr->sval == SV_WAND_HEAL_MONSTER && o_ptr->is_aware())
55              return false;
56     }
57
58     return true;
59 }
60
61 /*!
62  * @brief Automatically destroy items in this grid.
63  */
64 static bool is_opt_confirm_destroy(PlayerType *player_ptr, object_type *o_ptr)
65 {
66     if (!destroy_items)
67         return false;
68
69     if (leave_worth)
70         if (object_value(o_ptr) > 0)
71             return false;
72
73     if (leave_equip)
74         if (o_ptr->is_weapon_armour_ammo())
75             return false;
76
77     if (leave_chest)
78         if ((o_ptr->tval == ItemKindType::CHEST) && o_ptr->pval)
79             return false;
80
81     if (leave_wanted)
82         if (object_is_bounty(player_ptr, o_ptr))
83             return false;
84
85     if (leave_corpse)
86         if (o_ptr->tval == ItemKindType::CORPSE)
87             return false;
88
89     if (leave_junk)
90         if ((o_ptr->tval == ItemKindType::SKELETON) || (o_ptr->tval == ItemKindType::BOTTLE) || (o_ptr->tval == ItemKindType::JUNK) || (o_ptr->tval == ItemKindType::STATUE))
91             return false;
92
93     if (!is_leave_special_item(player_ptr, o_ptr))
94         return false;
95
96     if (o_ptr->tval == ItemKindType::GOLD)
97         return false;
98
99     return true;
100 }
101
102 void auto_destroy_item(PlayerType *player_ptr, object_type *o_ptr, int autopick_idx)
103 {
104     bool destroy = false;
105     if (is_opt_confirm_destroy(player_ptr, o_ptr))
106         destroy = true;
107
108     if (autopick_idx >= 0 && !(autopick_list[autopick_idx].action & DO_AUTODESTROY))
109         destroy = false;
110
111     if (!always_pickup) {
112         if (autopick_idx >= 0 && (autopick_list[autopick_idx].action & DO_AUTODESTROY))
113             destroy = true;
114     }
115
116     if (!destroy)
117         return;
118
119     disturb(player_ptr, false, false);
120     if (!can_player_destroy_object(player_ptr, o_ptr)) {
121         GAME_TEXT o_name[MAX_NLEN];
122         describe_flavor(player_ptr, o_name, o_ptr, 0);
123         msg_format(_("%sは破壊不能だ。", "You cannot auto-destroy %s."), o_name);
124         return;
125     }
126
127     autopick_last_destroyed_object = *o_ptr;
128     o_ptr->marked |= OM_AUTODESTROY;
129     player_ptr->update |= PU_AUTODESTROY;
130 }