OSDN Git Service

Merge pull request #2290 from habu1010/feature/clang-format-insert-braces
[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-quest.h"
19 #include "object-hook/hook-weapon.h"
20 #include "object/object-info.h"
21 #include "object/object-kind.h"
22 #include "object/object-stack.h"
23 #include "object/object-value.h"
24 #include "perception/object-perception.h"
25 #include "player-base/player-class.h"
26 #include "player/player-realm.h"
27 #include "system/floor-type-definition.h"
28 #include "system/monster-race-definition.h"
29 #include "system/object-type-definition.h"
30 #include "system/player-type-definition.h"
31 #include "util/string-processor.h"
32
33 /*!
34  * @brief A function for Auto-picker/destroyer Examine whether the object matches to the entry
35  */
36 bool is_autopick_match(PlayerType *player_ptr, ObjectType *o_ptr, autopick_type *entry, concptr o_name)
37 {
38     concptr ptr = entry->name.c_str();
39     if (IS_FLG(FLG_UNAWARE) && o_ptr->is_aware()) {
40         return false;
41     }
42
43     if (IS_FLG(FLG_UNIDENTIFIED) && (o_ptr->is_known() || (o_ptr->ident & IDENT_SENSE))) {
44         return false;
45     }
46
47     if (IS_FLG(FLG_IDENTIFIED) && !o_ptr->is_known()) {
48         return false;
49     }
50
51     if (IS_FLG(FLG_STAR_IDENTIFIED) && (!o_ptr->is_known() || !o_ptr->is_fully_known())) {
52         return false;
53     }
54
55     if (IS_FLG(FLG_BOOSTED)) {
56         auto *k_ptr = &k_info[o_ptr->k_idx];
57         if (!o_ptr->is_melee_weapon()) {
58             return false;
59         }
60
61         if ((o_ptr->dd == k_ptr->dd) && (o_ptr->ds == k_ptr->ds)) {
62             return false;
63         }
64
65         if (!o_ptr->is_known() && object_is_quest_target(player_ptr->current_floor_ptr->quest_number, o_ptr)) {
66             return false;
67         }
68     }
69
70     if (IS_FLG(FLG_MORE_DICE)) {
71         if (o_ptr->dd * o_ptr->ds < entry->dice) {
72             return false;
73         }
74     }
75
76     if (IS_FLG(FLG_MORE_BONUS)) {
77         if (!o_ptr->is_known()) {
78             return false;
79         }
80
81         if (o_ptr->pval) {
82             if (o_ptr->pval < entry->bonus) {
83                 return false;
84             }
85         } else {
86             if (o_ptr->to_h < entry->bonus && o_ptr->to_d < entry->bonus && o_ptr->to_a < entry->bonus && o_ptr->pval < entry->bonus) {
87                 return false;
88             }
89         }
90     }
91
92     if (IS_FLG(FLG_WORTHLESS) && object_value(o_ptr) > 0) {
93         return false;
94     }
95
96     if (IS_FLG(FLG_ARTIFACT)) {
97         if (!o_ptr->is_known() || !o_ptr->is_artifact()) {
98             return false;
99         }
100     }
101
102     if (IS_FLG(FLG_EGO)) {
103         if (!o_ptr->is_ego()) {
104             return false;
105         }
106         if (!o_ptr->is_known() && !((o_ptr->ident & IDENT_SENSE) && o_ptr->feeling == FEEL_EXCELLENT)) {
107             return false;
108         }
109     }
110
111     if (IS_FLG(FLG_GOOD)) {
112         if (!o_ptr->is_equipment()) {
113             return false;
114         }
115         if (o_ptr->is_known()) {
116             if (!o_ptr->is_nameless()) {
117                 return false;
118             }
119
120             if (o_ptr->to_a <= 0 && (o_ptr->to_h + o_ptr->to_d) <= 0) {
121                 return false;
122             }
123         } else if (o_ptr->ident & IDENT_SENSE) {
124             switch (o_ptr->feeling) {
125             case FEEL_GOOD:
126                 break;
127
128             default:
129                 return false;
130             }
131         } else {
132             return false;
133         }
134     }
135
136     if (IS_FLG(FLG_NAMELESS)) {
137         if (!o_ptr->is_equipment()) {
138             return false;
139         }
140         if (o_ptr->is_known()) {
141             if (!o_ptr->is_nameless()) {
142                 return false;
143             }
144         } else if (o_ptr->ident & IDENT_SENSE) {
145             switch (o_ptr->feeling) {
146             case FEEL_AVERAGE:
147             case FEEL_GOOD:
148             case FEEL_BROKEN:
149             case FEEL_CURSED:
150                 break;
151
152             default:
153                 return false;
154             }
155         } else {
156             return false;
157         }
158     }
159
160     if (IS_FLG(FLG_AVERAGE)) {
161         if (!o_ptr->is_equipment()) {
162             return false;
163         }
164         if (o_ptr->is_known()) {
165             if (!o_ptr->is_nameless()) {
166                 return false;
167             }
168
169             if (o_ptr->is_cursed() || o_ptr->is_broken()) {
170                 return false;
171             }
172
173             if (o_ptr->to_a > 0 || (o_ptr->to_h + o_ptr->to_d) > 0) {
174                 return false;
175             }
176         } else if (o_ptr->ident & IDENT_SENSE) {
177             switch (o_ptr->feeling) {
178             case FEEL_AVERAGE:
179                 break;
180
181             default:
182                 return false;
183             }
184         } else {
185             return false;
186         }
187     }
188
189     if (IS_FLG(FLG_RARE) && !o_ptr->is_rare()) {
190         return false;
191     }
192
193     if (IS_FLG(FLG_COMMON) && o_ptr->is_rare()) {
194         return false;
195     }
196
197     if (IS_FLG(FLG_WANTED) && !object_is_bounty(player_ptr, o_ptr)) {
198         return false;
199     }
200
201     if (IS_FLG(FLG_UNIQUE) && ((o_ptr->tval != ItemKindType::CORPSE && o_ptr->tval != ItemKindType::STATUE) || r_info[o_ptr->pval].kind_flags.has_not(MonsterKindType::UNIQUE))) {
202         return false;
203     }
204
205     if (IS_FLG(FLG_HUMAN) && (o_ptr->tval != ItemKindType::CORPSE || !angband_strchr("pht", r_info[o_ptr->pval].d_char))) {
206         return false;
207     }
208
209     if (IS_FLG(FLG_UNREADABLE) && (o_ptr->tval < ItemKindType::LIFE_BOOK || check_book_realm(player_ptr, o_ptr->tval, o_ptr->sval))) {
210         return false;
211     }
212
213     PlayerClass pc(player_ptr);
214     auto realm_except_class = pc.equals(PlayerClassType::SORCERER) || pc.equals(PlayerClassType::RED_MAGE);
215
216     if (IS_FLG(FLG_REALM1) && ((get_realm1_book(player_ptr) != o_ptr->tval) || realm_except_class)) {
217         return false;
218     }
219
220     if (IS_FLG(FLG_REALM2) && ((get_realm2_book(player_ptr) != o_ptr->tval) || realm_except_class)) {
221         return false;
222     }
223
224     if (IS_FLG(FLG_FIRST) && ((o_ptr->tval < ItemKindType::LIFE_BOOK) || (o_ptr->sval) != 0)) {
225         return false;
226     }
227
228     if (IS_FLG(FLG_SECOND) && ((o_ptr->tval < ItemKindType::LIFE_BOOK) || (o_ptr->sval) != 1)) {
229         return false;
230     }
231
232     if (IS_FLG(FLG_THIRD) && ((o_ptr->tval < ItemKindType::LIFE_BOOK) || (o_ptr->sval) != 2)) {
233         return false;
234     }
235
236     if (IS_FLG(FLG_FOURTH) && ((o_ptr->tval < ItemKindType::LIFE_BOOK) || (o_ptr->sval) != 3)) {
237         return false;
238     }
239
240     if (IS_FLG(FLG_WEAPONS)) {
241         if (!o_ptr->is_weapon()) {
242             return false;
243         }
244     } else if (IS_FLG(FLG_FAVORITE_WEAPONS)) {
245         if (!object_is_favorite(player_ptr, o_ptr)) {
246             return false;
247         }
248     } else if (IS_FLG(FLG_ARMORS)) {
249         if (!o_ptr->is_armour()) {
250             return false;
251         }
252     } else if (IS_FLG(FLG_MISSILES)) {
253         if (!o_ptr->is_ammo()) {
254             return false;
255         }
256     } else if (IS_FLG(FLG_DEVICES)) {
257         switch (o_ptr->tval) {
258         case ItemKindType::SCROLL:
259         case ItemKindType::STAFF:
260         case ItemKindType::WAND:
261         case ItemKindType::ROD:
262             break;
263         default:
264             return false;
265         }
266     } else if (IS_FLG(FLG_LIGHTS)) {
267         if (!(o_ptr->tval == ItemKindType::LITE)) {
268             return false;
269         }
270     } else if (IS_FLG(FLG_JUNKS)) {
271         switch (o_ptr->tval) {
272         case ItemKindType::SKELETON:
273         case ItemKindType::BOTTLE:
274         case ItemKindType::JUNK:
275         case ItemKindType::STATUE:
276             break;
277         default:
278             return false;
279         }
280     } else if (IS_FLG(FLG_CORPSES)) {
281         if (o_ptr->tval != ItemKindType::CORPSE && o_ptr->tval != ItemKindType::SKELETON) {
282             return false;
283         }
284     } else if (IS_FLG(FLG_SPELLBOOKS)) {
285         if (!(o_ptr->tval >= ItemKindType::LIFE_BOOK)) {
286             return false;
287         }
288     } else if (IS_FLG(FLG_HAFTED)) {
289         if (!(o_ptr->tval == ItemKindType::HAFTED)) {
290             return false;
291         }
292     } else if (IS_FLG(FLG_SHIELDS)) {
293         if (!(o_ptr->tval == ItemKindType::SHIELD)) {
294             return false;
295         }
296     } else if (IS_FLG(FLG_BOWS)) {
297         if (!(o_ptr->tval == ItemKindType::BOW)) {
298             return false;
299         }
300     } else if (IS_FLG(FLG_RINGS)) {
301         if (!(o_ptr->tval == ItemKindType::RING)) {
302             return false;
303         }
304     } else if (IS_FLG(FLG_AMULETS)) {
305         if (!(o_ptr->tval == ItemKindType::AMULET)) {
306             return false;
307         }
308     } else if (IS_FLG(FLG_SUITS)) {
309         if (!(o_ptr->tval == ItemKindType::DRAG_ARMOR || o_ptr->tval == ItemKindType::HARD_ARMOR || o_ptr->tval == ItemKindType::SOFT_ARMOR)) {
310             return false;
311         }
312     } else if (IS_FLG(FLG_CLOAKS)) {
313         if (!(o_ptr->tval == ItemKindType::CLOAK)) {
314             return false;
315         }
316     } else if (IS_FLG(FLG_HELMS)) {
317         if (!(o_ptr->tval == ItemKindType::CROWN || o_ptr->tval == ItemKindType::HELM)) {
318             return false;
319         }
320     } else if (IS_FLG(FLG_GLOVES)) {
321         if (!(o_ptr->tval == ItemKindType::GLOVES)) {
322             return false;
323         }
324     } else if (IS_FLG(FLG_BOOTS)) {
325         if (!(o_ptr->tval == ItemKindType::BOOTS)) {
326             return false;
327         }
328     }
329
330     if (*ptr == '^') {
331         ptr++;
332         if (strncmp(o_name, ptr, strlen(ptr))) {
333             return false;
334         }
335     } else {
336         if (!angband_strstr(o_name, ptr)) {
337             return false;
338         }
339     }
340
341     if (!IS_FLG(FLG_COLLECTING)) {
342         return true;
343     }
344
345     for (int j = 0; j < INVEN_PACK; j++) {
346         /*
347          * 'Collecting' means the item must be absorbed
348          * into an inventory slot.
349          * But an item can not be absorbed into itself!
350          */
351         if ((&player_ptr->inventory_list[j] != o_ptr) && object_similar(&player_ptr->inventory_list[j], o_ptr)) {
352             return true;
353         }
354     }
355
356     return false;
357 }