OSDN Git Service

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