OSDN Git Service

Merge branch 'develop' into feature/Remove-Dependency-Player-Status
[hengbandforosx/hengbandosx.git] / src / autopick / autopick-matcher.cpp
1 /*!
2  * @brief 床のアイテムが自動拾いに一致するかどうかを調べる関数だけを格納したファイル
3  * @date 2020/04/25
4  * @author Hourier
5  * @todo 300行以上の凶悪関数なので後で分割しておく
6  */
7
8 #include "autopick/autopick-matcher.h"
9 #include "autopick/autopick-flags-table.h"
10 #include "autopick/autopick-key-flag-process.h"
11 #include "autopick/autopick-util.h"
12 #include "inventory/inventory-slot-types.h"
13 #include "monster-race/monster-race.h"
14 #include "monster-race/race-flags1.h"
15 #include "object-enchant/item-feeling.h"
16 #include "object-enchant/special-object-flags.h"
17 #include "object-hook/hook-armor.h"
18 #include "object-hook/hook-bow.h"
19 #include "object-hook/hook-checker.h"
20 #include "object-hook/hook-enchant.h"
21 #include "object-hook/hook-quest.h"
22 #include "object-hook/hook-weapon.h"
23 #include "object/object-info.h"
24 #include "object/object-kind.h"
25 #include "object/object-stack.h"
26 #include "object/object-value.h"
27 #include "perception/object-perception.h"
28 #include "player/player-realm.h"
29 #include "system/floor-type-definition.h"
30 #include "system/monster-race-definition.h"
31 #include "system/object-type-definition.h"
32 #include "system/player-type-definition.h"
33 #include "util/string-processor.h"
34
35 /*
36  * A function for Auto-picker/destroyer
37  * Examine whether the object matches to the entry
38  */
39 bool is_autopick_match(player_type *player_ptr, object_type *o_ptr, autopick_type *entry, concptr o_name)
40 {
41     concptr ptr = entry->name;
42     if (IS_FLG(FLG_UNAWARE) && object_is_aware(o_ptr))
43         return FALSE;
44
45     if (IS_FLG(FLG_UNIDENTIFIED) && (object_is_known(o_ptr) || (o_ptr->ident & IDENT_SENSE)))
46         return FALSE;
47
48     if (IS_FLG(FLG_IDENTIFIED) && !object_is_known(o_ptr))
49         return FALSE;
50
51     if (IS_FLG(FLG_STAR_IDENTIFIED) && (!object_is_known(o_ptr) || !object_is_fully_known(o_ptr)))
52         return FALSE;
53
54     if (IS_FLG(FLG_BOOSTED)) {
55         object_kind *k_ptr = &k_info[o_ptr->k_idx];
56         if (!object_is_melee_weapon(o_ptr))
57             return FALSE;
58
59         if ((o_ptr->dd == k_ptr->dd) && (o_ptr->ds == k_ptr->ds))
60             return FALSE;
61
62         if (!object_is_known(o_ptr) && object_is_quest_target(player_ptr->current_floor_ptr->inside_quest, o_ptr)) {
63             return FALSE;
64         }
65     }
66
67     if (IS_FLG(FLG_MORE_DICE)) {
68         if (o_ptr->dd * o_ptr->ds < entry->dice)
69             return FALSE;
70     }
71
72     if (IS_FLG(FLG_MORE_BONUS)) {
73         if (!object_is_known(o_ptr))
74             return FALSE;
75
76         if (o_ptr->pval) {
77             if (o_ptr->pval < entry->bonus)
78                 return FALSE;
79         } else {
80             if (o_ptr->to_h < entry->bonus && o_ptr->to_d < entry->bonus && o_ptr->to_a < entry->bonus && o_ptr->pval < entry->bonus)
81                 return FALSE;
82         }
83     }
84
85     if (IS_FLG(FLG_WORTHLESS) && object_value(player_ptr, o_ptr) > 0)
86         return FALSE;
87
88     if (IS_FLG(FLG_ARTIFACT)) {
89         if (!object_is_known(o_ptr) || !object_is_artifact(o_ptr))
90             return FALSE;
91     }
92
93     if (IS_FLG(FLG_EGO)) {
94         if (!object_is_ego(o_ptr))
95             return FALSE;
96         if (!object_is_known(o_ptr) && !((o_ptr->ident & IDENT_SENSE) && o_ptr->feeling == FEEL_EXCELLENT))
97             return FALSE;
98     }
99
100     if (IS_FLG(FLG_GOOD)) {
101         if (!object_is_equipment(o_ptr))
102             return FALSE;
103         if (object_is_known(o_ptr)) {
104             if (!object_is_nameless(player_ptr, o_ptr))
105                 return FALSE;
106
107             if (o_ptr->to_a <= 0 && (o_ptr->to_h + o_ptr->to_d) <= 0)
108                 return FALSE;
109         } else if (o_ptr->ident & IDENT_SENSE) {
110             switch (o_ptr->feeling) {
111             case FEEL_GOOD:
112                 break;
113
114             default:
115                 return FALSE;
116             }
117         } else {
118             return FALSE;
119         }
120     }
121
122     if (IS_FLG(FLG_NAMELESS)) {
123         if (!object_is_equipment(o_ptr))
124             return FALSE;
125         if (object_is_known(o_ptr)) {
126             if (!object_is_nameless(player_ptr, o_ptr))
127                 return FALSE;
128         } else if (o_ptr->ident & IDENT_SENSE) {
129             switch (o_ptr->feeling) {
130             case FEEL_AVERAGE:
131             case FEEL_GOOD:
132             case FEEL_BROKEN:
133             case FEEL_CURSED:
134                 break;
135
136             default:
137                 return FALSE;
138             }
139         } else {
140             return FALSE;
141         }
142     }
143
144     if (IS_FLG(FLG_AVERAGE)) {
145         if (!object_is_equipment(o_ptr))
146             return FALSE;
147         if (object_is_known(o_ptr)) {
148             if (!object_is_nameless(player_ptr, o_ptr))
149                 return FALSE;
150
151             if (object_is_cursed(o_ptr) || object_is_broken(o_ptr))
152                 return FALSE;
153
154             if (o_ptr->to_a > 0 || (o_ptr->to_h + o_ptr->to_d) > 0)
155                 return FALSE;
156         } else if (o_ptr->ident & IDENT_SENSE) {
157             switch (o_ptr->feeling) {
158             case FEEL_AVERAGE:
159                 break;
160
161             default:
162                 return FALSE;
163             }
164         } else {
165             return FALSE;
166         }
167     }
168
169     if (IS_FLG(FLG_RARE) && !object_is_rare(o_ptr))
170         return FALSE;
171
172     if (IS_FLG(FLG_COMMON) && object_is_rare(o_ptr))
173         return FALSE;
174
175     if (IS_FLG(FLG_WANTED) && !object_is_bounty(player_ptr, o_ptr))
176         return FALSE;
177
178     if (IS_FLG(FLG_UNIQUE) && ((o_ptr->tval != TV_CORPSE && o_ptr->tval != TV_STATUE) || !(r_info[o_ptr->pval].flags1 & RF1_UNIQUE)))
179         return FALSE;
180
181     if (IS_FLG(FLG_HUMAN) && (o_ptr->tval != TV_CORPSE || !angband_strchr("pht", r_info[o_ptr->pval].d_char)))
182         return FALSE;
183
184     if (IS_FLG(FLG_UNREADABLE) && (o_ptr->tval < TV_LIFE_BOOK || check_book_realm(player_ptr, o_ptr->tval, o_ptr->sval)))
185         return FALSE;
186
187     bool realm_except_class = player_ptr->pclass == CLASS_SORCERER || player_ptr->pclass == CLASS_RED_MAGE;
188
189     if (IS_FLG(FLG_REALM1) && (get_realm1_book(player_ptr) != o_ptr->tval || realm_except_class))
190         return FALSE;
191
192     if (IS_FLG(FLG_REALM2) && (get_realm2_book(player_ptr) != o_ptr->tval || realm_except_class))
193         return FALSE;
194
195     if (IS_FLG(FLG_FIRST) && (o_ptr->tval < TV_LIFE_BOOK || 0 != o_ptr->sval))
196         return FALSE;
197
198     if (IS_FLG(FLG_SECOND) && (o_ptr->tval < TV_LIFE_BOOK || 1 != o_ptr->sval))
199         return FALSE;
200
201     if (IS_FLG(FLG_THIRD) && (o_ptr->tval < TV_LIFE_BOOK || 2 != o_ptr->sval))
202         return FALSE;
203
204     if (IS_FLG(FLG_FOURTH) && (o_ptr->tval < TV_LIFE_BOOK || 3 != o_ptr->sval))
205         return FALSE;
206
207     if (IS_FLG(FLG_WEAPONS)) {
208         if (!object_is_weapon(player_ptr, o_ptr))
209             return FALSE;
210     } else if (IS_FLG(FLG_FAVORITE_WEAPONS)) {
211         if (!object_is_favorite(player_ptr, o_ptr))
212             return FALSE;
213     } else if (IS_FLG(FLG_ARMORS)) {
214         if (!object_is_armour(player_ptr, o_ptr))
215             return FALSE;
216     } else if (IS_FLG(FLG_MISSILES)) {
217         if (!object_is_ammo(o_ptr))
218             return FALSE;
219     } else if (IS_FLG(FLG_DEVICES)) {
220         switch (o_ptr->tval) {
221         case TV_SCROLL:
222         case TV_STAFF:
223         case TV_WAND:
224         case TV_ROD:
225             break;
226         default:
227             return FALSE;
228         }
229     } else if (IS_FLG(FLG_LIGHTS)) {
230         if (!(o_ptr->tval == TV_LITE))
231             return FALSE;
232     } else if (IS_FLG(FLG_JUNKS)) {
233         switch (o_ptr->tval) {
234         case TV_SKELETON:
235         case TV_BOTTLE:
236         case TV_JUNK:
237         case TV_STATUE:
238             break;
239         default:
240             return FALSE;
241         }
242     } else if (IS_FLG(FLG_CORPSES)) {
243         if (o_ptr->tval != TV_CORPSE && o_ptr->tval != TV_SKELETON)
244             return FALSE;
245     } else if (IS_FLG(FLG_SPELLBOOKS)) {
246         if (!(o_ptr->tval >= TV_LIFE_BOOK))
247             return FALSE;
248     } else if (IS_FLG(FLG_HAFTED)) {
249         if (!(o_ptr->tval == TV_HAFTED))
250             return FALSE;
251     } else if (IS_FLG(FLG_SHIELDS)) {
252         if (!(o_ptr->tval == TV_SHIELD))
253             return FALSE;
254     } else if (IS_FLG(FLG_BOWS)) {
255         if (!(o_ptr->tval == TV_BOW))
256             return FALSE;
257     } else if (IS_FLG(FLG_RINGS)) {
258         if (!(o_ptr->tval == TV_RING))
259             return FALSE;
260     } else if (IS_FLG(FLG_AMULETS)) {
261         if (!(o_ptr->tval == TV_AMULET))
262             return FALSE;
263     } else if (IS_FLG(FLG_SUITS)) {
264         if (!(o_ptr->tval == TV_DRAG_ARMOR || o_ptr->tval == TV_HARD_ARMOR || o_ptr->tval == TV_SOFT_ARMOR))
265             return FALSE;
266     } else if (IS_FLG(FLG_CLOAKS)) {
267         if (!(o_ptr->tval == TV_CLOAK))
268             return FALSE;
269     } else if (IS_FLG(FLG_HELMS)) {
270         if (!(o_ptr->tval == TV_CROWN || o_ptr->tval == TV_HELM))
271             return FALSE;
272     } else if (IS_FLG(FLG_GLOVES)) {
273         if (!(o_ptr->tval == TV_GLOVES))
274             return FALSE;
275     } else if (IS_FLG(FLG_BOOTS)) {
276         if (!(o_ptr->tval == TV_BOOTS))
277             return FALSE;
278     }
279
280     if (*ptr == '^') {
281         ptr++;
282         if (strncmp(o_name, ptr, strlen(ptr)))
283             return FALSE;
284     } else {
285         if (!angband_strstr(o_name, ptr))
286             return FALSE;
287     }
288
289     if (!IS_FLG(FLG_COLLECTING))
290         return TRUE;
291
292     for (int j = 0; j < INVEN_PACK; j++) {
293         /*
294          * 'Collecting' means the item must be absorbed
295          * into an inventory slot.
296          * But an item can not be absorbed into itself!
297          */
298         if ((&player_ptr->inventory_list[j] != o_ptr) && object_similar(&player_ptr->inventory_list[j], o_ptr))
299             return TRUE;
300     }
301
302     return FALSE;
303 }