OSDN Git Service

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