OSDN Git Service

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