OSDN Git Service

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