OSDN Git Service

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