OSDN Git Service

Merge branch 'master' of git.osdn.net:/gitroot/hengband/hengband
[hengband/hengband.git] / src / autopick / autopick-destroyer.c
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/player-race-types.h"
25 #include "sv-definition/sv-other-types.h"
26 #include "sv-definition/sv-wand-types.h"
27 #include "util/string-processor.h"
28 #include "view/display-messages.h"
29
30 /*!
31  * @brief クラス依存のアイテム破壊を調べる
32  * @param player_ptr プレーヤーへの参照ポインタ
33  * @param o_ptr アイテムへの参照ポインタ
34  * @return 特別なクラス、かつそのクラス特有のアイテムであればFALSE、それ以外はTRUE
35  */
36 static bool is_leave_special_item(player_type *player_ptr, object_type *o_ptr)
37 {
38     if (!leave_special)
39         return TRUE;
40
41     if (player_ptr->prace == RACE_BALROG) {
42         if (o_ptr->tval == TV_CORPSE && o_ptr->sval == SV_CORPSE && angband_strchr("pht", r_info[o_ptr->pval].d_char))
43             return FALSE;
44     } else if (player_ptr->pclass == CLASS_ARCHER) {
45         if (o_ptr->tval == TV_SKELETON || (o_ptr->tval == TV_CORPSE && o_ptr->sval == SV_SKELETON))
46             return FALSE;
47     } else if (player_ptr->pclass == CLASS_NINJA) {
48         if (o_ptr->tval == TV_LITE && o_ptr->name2 == EGO_LITE_DARKNESS && object_is_known(o_ptr))
49             return FALSE;
50     } else if (player_ptr->pclass == CLASS_BEASTMASTER || player_ptr->pclass == CLASS_CAVALRY) {
51         if (o_ptr->tval == TV_WAND && o_ptr->sval == SV_WAND_HEAL_MONSTER && object_is_aware(o_ptr))
52             return FALSE;
53     }
54
55     return TRUE;
56 }
57
58 /*
59  * Automatically destroy items in this grid.
60  */
61 static bool is_opt_confirm_destroy(player_type *player_ptr, object_type *o_ptr)
62 {
63     if (!destroy_items)
64         return FALSE;
65
66     if (leave_worth)
67         if (object_value(player_ptr, o_ptr) > 0)
68             return FALSE;
69
70     if (leave_equip)
71         if (object_is_weapon_armour_ammo(player_ptr, o_ptr))
72             return FALSE;
73
74     if (leave_chest)
75         if ((o_ptr->tval == TV_CHEST) && o_ptr->pval)
76             return FALSE;
77
78     if (leave_wanted)
79         if (object_is_bounty(player_ptr, o_ptr))
80             return FALSE;
81
82     if (leave_corpse)
83         if (o_ptr->tval == TV_CORPSE)
84             return FALSE;
85
86     if (leave_junk)
87         if ((o_ptr->tval == TV_SKELETON) || (o_ptr->tval == TV_BOTTLE) || (o_ptr->tval == TV_JUNK) || (o_ptr->tval == TV_STATUE))
88             return FALSE;
89
90     if (!is_leave_special_item(player_ptr, o_ptr))
91         return FALSE;
92
93     if (o_ptr->tval == TV_GOLD)
94         return FALSE;
95
96     return TRUE;
97 }
98
99 void auto_destroy_item(player_type *player_ptr, object_type *o_ptr, int autopick_idx)
100 {
101     bool destroy = FALSE;
102     if (is_opt_confirm_destroy(player_ptr, o_ptr))
103         destroy = TRUE;
104
105     if (autopick_idx >= 0 && !(autopick_list[autopick_idx].action & DO_AUTODESTROY))
106         destroy = FALSE;
107
108     if (!always_pickup) {
109         if (autopick_idx >= 0 && (autopick_list[autopick_idx].action & DO_AUTODESTROY))
110             destroy = TRUE;
111     }
112
113     if (!destroy)
114         return;
115
116     disturb(player_ptr, FALSE, FALSE);
117     if (!can_player_destroy_object(player_ptr, o_ptr)) {
118         GAME_TEXT o_name[MAX_NLEN];
119         describe_flavor(player_ptr, o_name, o_ptr, 0);
120         msg_format(_("%sは破壊不能だ。", "You cannot auto-destroy %s."), o_name);
121         return;
122     }
123
124     (void)COPY(&autopick_last_destroyed_object, o_ptr, object_type);
125     o_ptr->marked |= OM_AUTODESTROY;
126     player_ptr->update |= PU_AUTODESTROY;
127 }