OSDN Git Service

[Refactor] #39962 Renamed files.c/h to files-util.c/h
[hengband/hengband.git] / src / autopick / autopick-destroyer.c
1 /*!
2  * @brief 自動破壊の実行
3  * @date 2020/04/25
4  * @author Hourier
5  */
6 #include "system/angband.h"
7 #include "autopick/autopick-util.h"
8 #include "autopick-methods-table.h"
9 #include "autopick/autopick-destroyer.h"
10 #include "object/object-ego.h"
11 #include "object/object-hook.h"
12 #include "object/object-kind.h"
13 #include "object/object-flavor.h"
14 #include "player/player-move.h"
15 #include "player/player-races-table.h"
16
17 /*!
18  * @brief クラス依存のアイテム破壊を調べる
19  * @param player_ptr プレーヤーへの参照ポインタ
20  * @param o_ptr アイテムへの参照ポインタ
21  * @return 特別なクラス、かつそのクラス特有のアイテムであればFALSE、それ以外はTRUE
22  */
23 static bool is_leave_special_item(player_type *player_ptr, object_type *o_ptr)
24 {
25         if (!leave_special) return TRUE;
26
27         if (player_ptr->prace == RACE_BALROG)
28         {
29                 if (o_ptr->tval == TV_CORPSE &&
30                         o_ptr->sval == SV_CORPSE &&
31                         my_strchr("pht", r_info[o_ptr->pval].d_char))
32                         return FALSE;
33         }
34         else if (player_ptr->pclass == CLASS_ARCHER)
35         {
36                 if (o_ptr->tval == TV_SKELETON ||
37                         (o_ptr->tval == TV_CORPSE && o_ptr->sval == SV_SKELETON))
38                         return FALSE;
39         }
40         else if (player_ptr->pclass == CLASS_NINJA)
41         {
42                 if (o_ptr->tval == TV_LITE &&
43                         o_ptr->name2 == EGO_LITE_DARKNESS && object_is_known(o_ptr))
44                         return FALSE;
45         }
46         else if (player_ptr->pclass == CLASS_BEASTMASTER ||
47                 player_ptr->pclass == CLASS_CAVALRY)
48         {
49                 if (o_ptr->tval == TV_WAND &&
50                         o_ptr->sval == SV_WAND_HEAL_MONSTER && object_is_aware(o_ptr))
51                         return FALSE;
52         }
53
54         return TRUE;
55 }
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) return FALSE;
64
65         if (leave_worth)
66                 if (object_value(o_ptr) > 0) return FALSE;
67
68         if (leave_equip)
69                 if (object_is_weapon_armour_ammo(o_ptr)) return FALSE;
70
71         if (leave_chest)
72                 if ((o_ptr->tval == TV_CHEST) && o_ptr->pval) return FALSE;
73
74         if (leave_wanted)
75                 if (object_is_bounty(o_ptr)) return FALSE;
76
77         if (leave_corpse)
78                 if (o_ptr->tval == TV_CORPSE) return FALSE;
79
80         if (leave_junk)
81                 if ((o_ptr->tval == TV_SKELETON) || (o_ptr->tval == TV_BOTTLE) || (o_ptr->tval == TV_JUNK) || (o_ptr->tval == TV_STATUE)) return FALSE;
82
83         if (!is_leave_special_item(player_ptr, o_ptr)) return FALSE;
84
85         if (o_ptr->tval == TV_GOLD) return FALSE;
86
87         return TRUE;
88 }
89
90
91 void auto_destroy_item(player_type *player_ptr, object_type *o_ptr, int autopick_idx)
92 {
93         bool destroy = FALSE;
94         if (is_opt_confirm_destroy(player_ptr, o_ptr)) destroy = TRUE;
95
96         if (autopick_idx >= 0 &&
97                 !(autopick_list[autopick_idx].action & DO_AUTODESTROY))
98                 destroy = FALSE;
99
100         if (!always_pickup)
101         {
102                 if (autopick_idx >= 0 &&
103                         (autopick_list[autopick_idx].action & DO_AUTODESTROY))
104                         destroy = TRUE;
105         }
106
107         if (!destroy) return;
108
109         disturb(player_ptr, FALSE, FALSE);
110         if (!can_player_destroy_object(o_ptr))
111         {
112                 GAME_TEXT o_name[MAX_NLEN];
113                 object_desc(player_ptr, o_name, o_ptr, 0);
114                 msg_format(_("%sは破壊不能だ。", "You cannot auto-destroy %s."), o_name);
115                 return;
116         }
117
118         (void)COPY(&autopick_last_destroyed_object, o_ptr, object_type);
119         o_ptr->marked |= OM_AUTODESTROY;
120         player_ptr->update |= PU_AUTODESTROY;
121 }