OSDN Git Service

[Refactor] object_is_ammo() を object_type のメンバ関数化
[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  * @brief A function for Auto-picker/destroyer Examine whether the object matches to the entry
37  */
38 bool is_autopick_match(player_type *player_ptr, object_type *o_ptr, autopick_type *entry, concptr o_name)
39 {
40     concptr ptr = entry->name;
41     if (IS_FLG(FLG_UNAWARE) && object_is_aware(o_ptr))
42         return false;
43
44     if (IS_FLG(FLG_UNIDENTIFIED) && (object_is_known(o_ptr) || (o_ptr->ident & IDENT_SENSE)))
45         return false;
46
47     if (IS_FLG(FLG_IDENTIFIED) && !object_is_known(o_ptr))
48         return false;
49
50     if (IS_FLG(FLG_STAR_IDENTIFIED) && (!object_is_known(o_ptr) || !object_is_fully_known(o_ptr)))
51         return false;
52
53     if (IS_FLG(FLG_BOOSTED)) {
54         object_kind *k_ptr = &k_info[o_ptr->k_idx];
55         if (!o_ptr->is_melee_weapon())
56             return false;
57
58         if ((o_ptr->dd == k_ptr->dd) && (o_ptr->ds == k_ptr->ds))
59             return false;
60
61         if (!object_is_known(o_ptr) && object_is_quest_target(player_ptr->current_floor_ptr->inside_quest, o_ptr)) {
62             return false;
63         }
64     }
65
66     if (IS_FLG(FLG_MORE_DICE)) {
67         if (o_ptr->dd * o_ptr->ds < entry->dice)
68             return false;
69     }
70
71     if (IS_FLG(FLG_MORE_BONUS)) {
72         if (!object_is_known(o_ptr))
73             return false;
74
75         if (o_ptr->pval) {
76             if (o_ptr->pval < entry->bonus)
77                 return false;
78         } else {
79             if (o_ptr->to_h < entry->bonus && o_ptr->to_d < entry->bonus && o_ptr->to_a < entry->bonus && o_ptr->pval < entry->bonus)
80                 return false;
81         }
82     }
83
84     if (IS_FLG(FLG_WORTHLESS) && object_value(o_ptr) > 0)
85         return false;
86
87     if (IS_FLG(FLG_ARTIFACT)) {
88         if (!object_is_known(o_ptr) || !object_is_artifact(o_ptr))
89             return false;
90     }
91
92     if (IS_FLG(FLG_EGO)) {
93         if (!object_is_ego(o_ptr))
94             return false;
95         if (!object_is_known(o_ptr) && !((o_ptr->ident & IDENT_SENSE) && o_ptr->feeling == FEEL_EXCELLENT))
96             return false;
97     }
98
99     if (IS_FLG(FLG_GOOD)) {
100         if (!o_ptr->is_equipment())
101             return false;
102         if (object_is_known(o_ptr)) {
103             if (!object_is_nameless(o_ptr))
104                 return false;
105
106             if (o_ptr->to_a <= 0 && (o_ptr->to_h + o_ptr->to_d) <= 0)
107                 return false;
108         } else if (o_ptr->ident & IDENT_SENSE) {
109             switch (o_ptr->feeling) {
110             case FEEL_GOOD:
111                 break;
112
113             default:
114                 return false;
115             }
116         } else {
117             return false;
118         }
119     }
120
121     if (IS_FLG(FLG_NAMELESS)) {
122         if (!o_ptr->is_equipment())
123             return false;
124         if (object_is_known(o_ptr)) {
125             if (!object_is_nameless(o_ptr))
126                 return false;
127         } else if (o_ptr->ident & IDENT_SENSE) {
128             switch (o_ptr->feeling) {
129             case FEEL_AVERAGE:
130             case FEEL_GOOD:
131             case FEEL_BROKEN:
132             case FEEL_CURSED:
133                 break;
134
135             default:
136                 return false;
137             }
138         } else {
139             return false;
140         }
141     }
142
143     if (IS_FLG(FLG_AVERAGE)) {
144         if (!o_ptr->is_equipment())
145             return false;
146         if (object_is_known(o_ptr)) {
147             if (!object_is_nameless(o_ptr))
148                 return false;
149
150             if (object_is_cursed(o_ptr) || object_is_broken(o_ptr))
151                 return false;
152
153             if (o_ptr->to_a > 0 || (o_ptr->to_h + o_ptr->to_d) > 0)
154                 return false;
155         } else if (o_ptr->ident & IDENT_SENSE) {
156             switch (o_ptr->feeling) {
157             case FEEL_AVERAGE:
158                 break;
159
160             default:
161                 return false;
162             }
163         } else {
164             return false;
165         }
166     }
167
168     if (IS_FLG(FLG_RARE) && !object_is_rare(o_ptr))
169         return false;
170
171     if (IS_FLG(FLG_COMMON) && object_is_rare(o_ptr))
172         return false;
173
174     if (IS_FLG(FLG_WANTED) && !object_is_bounty(player_ptr, o_ptr))
175         return false;
176
177     if (IS_FLG(FLG_UNIQUE) && ((o_ptr->tval != TV_CORPSE && o_ptr->tval != TV_STATUE) || !(r_info[o_ptr->pval].flags1 & RF1_UNIQUE)))
178         return false;
179
180     if (IS_FLG(FLG_HUMAN) && (o_ptr->tval != TV_CORPSE || !angband_strchr("pht", r_info[o_ptr->pval].d_char)))
181         return false;
182
183     if (IS_FLG(FLG_UNREADABLE) && (o_ptr->tval < TV_LIFE_BOOK || check_book_realm(player_ptr, o_ptr->tval, o_ptr->sval)))
184         return false;
185
186     bool realm_except_class = player_ptr->pclass == CLASS_SORCERER || player_ptr->pclass == CLASS_RED_MAGE;
187
188     if (IS_FLG(FLG_REALM1) && (get_realm1_book(player_ptr) != o_ptr->tval || realm_except_class))
189         return false;
190
191     if (IS_FLG(FLG_REALM2) && (get_realm2_book(player_ptr) != o_ptr->tval || realm_except_class))
192         return false;
193
194     if (IS_FLG(FLG_FIRST) && (o_ptr->tval < TV_LIFE_BOOK || 0 != o_ptr->sval))
195         return false;
196
197     if (IS_FLG(FLG_SECOND) && (o_ptr->tval < TV_LIFE_BOOK || 1 != o_ptr->sval))
198         return false;
199
200     if (IS_FLG(FLG_THIRD) && (o_ptr->tval < TV_LIFE_BOOK || 2 != o_ptr->sval))
201         return false;
202
203     if (IS_FLG(FLG_FOURTH) && (o_ptr->tval < TV_LIFE_BOOK || 3 != o_ptr->sval))
204         return false;
205
206     if (IS_FLG(FLG_WEAPONS)) {
207         if (!o_ptr->is_weapon())
208             return false;
209     } else if (IS_FLG(FLG_FAVORITE_WEAPONS)) {
210         if (!object_is_favorite(player_ptr, o_ptr))
211             return false;
212     } else if (IS_FLG(FLG_ARMORS)) {
213         if (!o_ptr->is_armour())
214             return false;
215     } else if (IS_FLG(FLG_MISSILES)) {
216         if (!o_ptr->is_ammo())
217             return false;
218     } else if (IS_FLG(FLG_DEVICES)) {
219         switch (o_ptr->tval) {
220         case TV_SCROLL:
221         case TV_STAFF:
222         case TV_WAND:
223         case TV_ROD:
224             break;
225         default:
226             return false;
227         }
228     } else if (IS_FLG(FLG_LIGHTS)) {
229         if (!(o_ptr->tval == TV_LITE))
230             return false;
231     } else if (IS_FLG(FLG_JUNKS)) {
232         switch (o_ptr->tval) {
233         case TV_SKELETON:
234         case TV_BOTTLE:
235         case TV_JUNK:
236         case TV_STATUE:
237             break;
238         default:
239             return false;
240         }
241     } else if (IS_FLG(FLG_CORPSES)) {
242         if (o_ptr->tval != TV_CORPSE && o_ptr->tval != TV_SKELETON)
243             return false;
244     } else if (IS_FLG(FLG_SPELLBOOKS)) {
245         if (!(o_ptr->tval >= TV_LIFE_BOOK))
246             return false;
247     } else if (IS_FLG(FLG_HAFTED)) {
248         if (!(o_ptr->tval == TV_HAFTED))
249             return false;
250     } else if (IS_FLG(FLG_SHIELDS)) {
251         if (!(o_ptr->tval == TV_SHIELD))
252             return false;
253     } else if (IS_FLG(FLG_BOWS)) {
254         if (!(o_ptr->tval == TV_BOW))
255             return false;
256     } else if (IS_FLG(FLG_RINGS)) {
257         if (!(o_ptr->tval == TV_RING))
258             return false;
259     } else if (IS_FLG(FLG_AMULETS)) {
260         if (!(o_ptr->tval == TV_AMULET))
261             return false;
262     } else if (IS_FLG(FLG_SUITS)) {
263         if (!(o_ptr->tval == TV_DRAG_ARMOR || o_ptr->tval == TV_HARD_ARMOR || o_ptr->tval == TV_SOFT_ARMOR))
264             return false;
265     } else if (IS_FLG(FLG_CLOAKS)) {
266         if (!(o_ptr->tval == TV_CLOAK))
267             return false;
268     } else if (IS_FLG(FLG_HELMS)) {
269         if (!(o_ptr->tval == TV_CROWN || o_ptr->tval == TV_HELM))
270             return false;
271     } else if (IS_FLG(FLG_GLOVES)) {
272         if (!(o_ptr->tval == TV_GLOVES))
273             return false;
274     } else if (IS_FLG(FLG_BOOTS)) {
275         if (!(o_ptr->tval == TV_BOOTS))
276             return false;
277     }
278
279     if (*ptr == '^') {
280         ptr++;
281         if (strncmp(o_name, ptr, strlen(ptr)))
282             return false;
283     } else {
284         if (!angband_strstr(o_name, ptr))
285             return false;
286     }
287
288     if (!IS_FLG(FLG_COLLECTING))
289         return true;
290
291     for (int j = 0; j < INVEN_PACK; j++) {
292         /*
293          * 'Collecting' means the item must be absorbed
294          * into an inventory slot.
295          * But an item can not be absorbed into itself!
296          */
297         if ((&player_ptr->inventory_list[j] != o_ptr) && object_similar(&player_ptr->inventory_list[j], o_ptr))
298             return true;
299     }
300
301     return false;
302 }