OSDN Git Service

Merge pull request #3569 from sikabane-works/release/3.0.0.88-alpha
[hengbandforosx/hengbandosx.git] / src / autopick / autopick-entry.cpp
1 #include "autopick/autopick-entry.h"
2 #include "autopick/autopick-flags-table.h"
3 #include "autopick/autopick-key-flag-process.h"
4 #include "autopick/autopick-keys-table.h"
5 #include "autopick/autopick-methods-table.h"
6 #include "autopick/autopick-util.h"
7 #include "core/show-file.h"
8 #include "flavor/flavor-describer.h"
9 #include "flavor/object-flavor-types.h"
10 #include "floor/floor-object.h"
11 #include "monster-race/monster-race.h"
12 #include "monster-race/race-flags1.h"
13 #include "object-enchant/item-feeling.h"
14 #include "object-enchant/object-ego.h"
15 #include "object-enchant/special-object-flags.h"
16 #include "object-hook/hook-quest.h"
17 #include "object-hook/hook-weapon.h"
18 #include "object/item-use-flags.h"
19 #include "object/object-info.h"
20 #include "perception/object-perception.h"
21 #include "player-base/player-class.h"
22 #include "player/player-realm.h"
23 #include "system/baseitem-info.h"
24 #include "system/item-entity.h"
25 #include "system/monster-race-info.h"
26 #include "system/player-type-definition.h"
27 #include "util/string-processor.h"
28 #include <optional>
29 #include <sstream>
30 #include <string>
31
32 #ifdef JP
33 static char kanji_colon[] = ":";
34 #endif
35
36 /*!
37  * @brief A function to create new entry
38  */
39 bool autopick_new_entry(autopick_type *entry, concptr str, bool allow_default)
40 {
41     if (str[0] && str[1] == ':') {
42         switch (str[0]) {
43         case '?':
44         case '%':
45         case 'A':
46         case 'P':
47         case 'C':
48             return false;
49         }
50     }
51
52     entry->flags[0] = entry->flags[1] = 0L;
53     entry->dice = 0;
54     entry->bonus = 0;
55
56     byte act = DO_AUTOPICK | DO_DISPLAY;
57     while (true) {
58         if ((act & DO_AUTOPICK) && *str == '!') {
59             act &= ~DO_AUTOPICK;
60             act |= DO_AUTODESTROY;
61             str++;
62             continue;
63         }
64
65         if ((act & DO_AUTOPICK) && *str == '~') {
66             act &= ~DO_AUTOPICK;
67             act |= DONT_AUTOPICK;
68             str++;
69             continue;
70         }
71
72         if ((act & DO_AUTOPICK) && *str == ';') {
73             act &= ~DO_AUTOPICK;
74             act |= DO_QUERY_AUTOPICK;
75             str++;
76             continue;
77         }
78
79         if ((act & DO_DISPLAY) && *str == '(') {
80             act &= ~DO_DISPLAY;
81             str++;
82             continue;
83         }
84
85         break;
86     }
87
88     concptr insc = nullptr;
89     char buf[MAX_LINELEN];
90     int i;
91     for (i = 0; *str; i++) {
92         char c = *str++;
93 #ifdef JP
94         if (iskanji(c)) {
95             buf[i++] = c;
96             buf[i] = *str++;
97             continue;
98         }
99 #endif
100         if (c == '#') {
101             buf[i] = '\0';
102             insc = str;
103             break;
104         }
105
106         if (isupper(c)) {
107             c = (char)tolower(c);
108         }
109
110         buf[i] = c;
111     }
112
113     buf[i] = '\0';
114     if (!allow_default && *buf == 0) {
115         return false;
116     }
117     if (*buf == 0 && insc) {
118         return false;
119     }
120
121     concptr prev_ptr, ptr;
122     ptr = prev_ptr = buf;
123     concptr old_ptr = nullptr;
124     while (old_ptr != ptr) {
125         old_ptr = ptr;
126         if (MATCH_KEY(KEY_ALL)) {
127             entry->add(FLG_ALL);
128         }
129         if (MATCH_KEY(KEY_COLLECTING)) {
130             entry->add(FLG_COLLECTING);
131         }
132         if (MATCH_KEY(KEY_UNAWARE)) {
133             entry->add(FLG_UNAWARE);
134         }
135         if (MATCH_KEY(KEY_UNIDENTIFIED)) {
136             entry->add(FLG_UNIDENTIFIED);
137         }
138         if (MATCH_KEY(KEY_IDENTIFIED)) {
139             entry->add(FLG_IDENTIFIED);
140         }
141         if (MATCH_KEY(KEY_STAR_IDENTIFIED)) {
142             entry->add(FLG_STAR_IDENTIFIED);
143         }
144         if (MATCH_KEY(KEY_BOOSTED)) {
145             entry->add(FLG_BOOSTED);
146         }
147
148         /*** Weapons whose dd*ds is more than nn ***/
149         if (MATCH_KEY2(KEY_MORE_THAN)) {
150             int k = 0;
151             entry->dice = 0;
152
153             while (' ' == *ptr) {
154                 ptr++;
155             }
156
157             while ('0' <= *ptr && *ptr <= '9') {
158                 entry->dice = 10 * entry->dice + (*ptr - '0');
159                 ptr++;
160                 k++;
161             }
162
163             if (k > 0 && k <= 2) {
164                 (void)MATCH_KEY(KEY_DICE);
165                 entry->add(FLG_MORE_DICE);
166             } else {
167                 ptr = prev_ptr;
168             }
169         }
170
171         /*** Items whose magical bonus is more than n ***/
172         if (MATCH_KEY2(KEY_MORE_BONUS)) {
173             int k = 0;
174             entry->bonus = 0;
175
176             while (' ' == *ptr) {
177                 ptr++;
178             }
179
180             while ('0' <= *ptr && *ptr <= '9') {
181                 entry->bonus = 10 * entry->bonus + (*ptr - '0');
182                 ptr++;
183                 k++;
184             }
185
186             if (k > 0 && k <= 2) {
187 #ifdef JP
188                 (void)MATCH_KEY(KEY_MORE_BONUS2);
189 #else
190                 if (' ' == *ptr) {
191                     ptr++;
192                 }
193 #endif
194                 entry->add(FLG_MORE_BONUS);
195             } else {
196                 ptr = prev_ptr;
197             }
198         }
199
200         if (MATCH_KEY(KEY_WORTHLESS)) {
201             entry->add(FLG_WORTHLESS);
202         }
203         if (MATCH_KEY(KEY_EGO)) {
204             entry->add(FLG_EGO);
205         }
206         if (MATCH_KEY(KEY_GOOD)) {
207             entry->add(FLG_GOOD);
208         }
209         if (MATCH_KEY(KEY_NAMELESS)) {
210             entry->add(FLG_NAMELESS);
211         }
212         if (MATCH_KEY(KEY_AVERAGE)) {
213             entry->add(FLG_AVERAGE);
214         }
215         if (MATCH_KEY(KEY_RARE)) {
216             entry->add(FLG_RARE);
217         }
218         if (MATCH_KEY(KEY_COMMON)) {
219             entry->add(FLG_COMMON);
220         }
221         if (MATCH_KEY(KEY_WANTED)) {
222             entry->add(FLG_WANTED);
223         }
224         if (MATCH_KEY(KEY_UNIQUE)) {
225             entry->add(FLG_UNIQUE);
226         }
227         if (MATCH_KEY(KEY_HUMAN)) {
228             entry->add(FLG_HUMAN);
229         }
230         if (MATCH_KEY(KEY_UNREADABLE)) {
231             entry->add(FLG_UNREADABLE);
232         }
233         if (MATCH_KEY(KEY_REALM1)) {
234             entry->add(FLG_REALM1);
235         }
236         if (MATCH_KEY(KEY_REALM2)) {
237             entry->add(FLG_REALM2);
238         }
239         if (MATCH_KEY(KEY_FIRST)) {
240             entry->add(FLG_FIRST);
241         }
242         if (MATCH_KEY(KEY_SECOND)) {
243             entry->add(FLG_SECOND);
244         }
245         if (MATCH_KEY(KEY_THIRD)) {
246             entry->add(FLG_THIRD);
247         }
248         if (MATCH_KEY(KEY_FOURTH)) {
249             entry->add(FLG_FOURTH);
250         }
251     }
252
253     std::optional<int> previous_flag = std::nullopt;
254     if (MATCH_KEY2(KEY_ARTIFACT)) {
255         entry->add(FLG_ARTIFACT);
256         previous_flag = FLG_ARTIFACT;
257     }
258
259     if (MATCH_KEY2(KEY_ITEMS)) {
260         entry->add(FLG_ITEMS);
261         previous_flag = FLG_ITEMS;
262     } else if (MATCH_KEY2(KEY_WEAPONS)) {
263         entry->add(FLG_WEAPONS);
264         previous_flag = FLG_WEAPONS;
265     } else if (MATCH_KEY2(KEY_FAVORITE_WEAPONS)) {
266         entry->add(FLG_FAVORITE_WEAPONS);
267         previous_flag = FLG_FAVORITE_WEAPONS;
268     } else if (MATCH_KEY2(KEY_ARMORS)) {
269         entry->add(FLG_ARMORS);
270         previous_flag = FLG_ARMORS;
271     } else if (MATCH_KEY2(KEY_MISSILES)) {
272         entry->add(FLG_MISSILES);
273         previous_flag = FLG_MISSILES;
274     } else if (MATCH_KEY2(KEY_DEVICES)) {
275         entry->add(FLG_DEVICES);
276         previous_flag = FLG_DEVICES;
277     } else if (MATCH_KEY2(KEY_LIGHTS)) {
278         entry->add(FLG_LIGHTS);
279         previous_flag = FLG_LIGHTS;
280     } else if (MATCH_KEY2(KEY_JUNKS)) {
281         entry->add(FLG_JUNKS);
282         previous_flag = FLG_JUNKS;
283     } else if (MATCH_KEY2(KEY_CORPSES)) {
284         entry->add(FLG_CORPSES);
285         previous_flag = FLG_CORPSES;
286     } else if (MATCH_KEY2(KEY_SPELLBOOKS)) {
287         entry->add(FLG_SPELLBOOKS);
288         previous_flag = FLG_SPELLBOOKS;
289     } else if (MATCH_KEY2(KEY_HAFTED)) {
290         entry->add(FLG_HAFTED);
291         previous_flag = FLG_HAFTED;
292     } else if (MATCH_KEY2(KEY_SHIELDS)) {
293         entry->add(FLG_SHIELDS);
294         previous_flag = FLG_SHIELDS;
295     } else if (MATCH_KEY2(KEY_BOWS)) {
296         entry->add(FLG_BOWS);
297         previous_flag = FLG_BOWS;
298     } else if (MATCH_KEY2(KEY_RINGS)) {
299         entry->add(FLG_RINGS);
300         previous_flag = FLG_RINGS;
301     } else if (MATCH_KEY2(KEY_AMULETS)) {
302         entry->add(FLG_AMULETS);
303         previous_flag = FLG_AMULETS;
304     } else if (MATCH_KEY2(KEY_SUITS)) {
305         entry->add(FLG_SUITS);
306         previous_flag = FLG_SUITS;
307     } else if (MATCH_KEY2(KEY_CLOAKS)) {
308         entry->add(FLG_CLOAKS);
309         previous_flag = FLG_CLOAKS;
310     } else if (MATCH_KEY2(KEY_HELMS)) {
311         entry->add(FLG_HELMS);
312         previous_flag = FLG_HELMS;
313     } else if (MATCH_KEY2(KEY_GLOVES)) {
314         entry->add(FLG_GLOVES);
315         previous_flag = FLG_GLOVES;
316     } else if (MATCH_KEY2(KEY_BOOTS)) {
317         entry->add(FLG_BOOTS);
318         previous_flag = FLG_BOOTS;
319     }
320
321     if (*ptr == ':') {
322         ptr++;
323     }
324 #ifdef JP
325     else if (ptr[0] == kanji_colon[0] && ptr[1] == kanji_colon[1]) {
326         ptr += 2;
327     }
328 #endif
329     else if (*ptr == '\0') {
330         if (!previous_flag.has_value()) {
331             entry->add(FLG_ITEMS);
332             previous_flag = FLG_ITEMS;
333         }
334     } else {
335         if (previous_flag.has_value()) {
336             entry->remove(previous_flag.value());
337             ptr = prev_ptr;
338         }
339     }
340
341     entry->name = ptr;
342     entry->action = act;
343     entry->insc = insc != nullptr ? insc : "";
344
345     return true;
346 }
347
348 /*!
349  * @brief Get auto-picker entry from o_ptr.
350  */
351 void autopick_entry_from_object(PlayerType *player_ptr, autopick_type *entry, ItemEntity *o_ptr)
352 {
353     /* Assume that object name is to be added */
354     bool name = true;
355     entry->name.clear();
356     entry->insc = o_ptr->inscription.value_or("");
357     entry->action = DO_AUTOPICK | DO_DISPLAY;
358     entry->flags[0] = entry->flags[1] = 0L;
359     entry->dice = 0;
360
361     // エゴ銘が邪魔かもしれないので、デフォルトで「^」は付けない.
362     // We can always use the ^ mark in English.
363     bool is_hat_added = _(false, true);
364     if (!o_ptr->is_aware()) {
365         entry->add(FLG_UNAWARE);
366         is_hat_added = true;
367     } else if (!o_ptr->is_known()) {
368         if (!(o_ptr->ident & IDENT_SENSE)) {
369             entry->add(FLG_UNIDENTIFIED);
370             is_hat_added = true;
371         } else {
372             switch (o_ptr->feeling) {
373             case FEEL_AVERAGE:
374             case FEEL_GOOD:
375                 entry->add(FLG_NAMELESS);
376                 is_hat_added = true;
377                 break;
378
379             case FEEL_BROKEN:
380             case FEEL_CURSED:
381                 entry->add(FLG_NAMELESS);
382                 entry->add(FLG_WORTHLESS);
383                 is_hat_added = true;
384                 break;
385
386             case FEEL_TERRIBLE:
387             case FEEL_WORTHLESS:
388                 entry->add(FLG_WORTHLESS);
389                 break;
390
391             case FEEL_EXCELLENT:
392                 entry->add(FLG_EGO);
393                 break;
394
395             case FEEL_UNCURSED:
396                 break;
397
398             default:
399                 break;
400             }
401         }
402     } else {
403         if (o_ptr->is_ego()) {
404             if (o_ptr->is_weapon_armour_ammo()) {
405                 auto &ego = o_ptr->get_ego();
406 #ifdef JP
407                 /* エゴ銘には「^」マークが使える */
408                 entry->name = "^";
409                 entry->name.append(ego.name);
410 #else
411                 /* We omit the basename and cannot use the ^ mark */
412                 entry->name = ego.name;
413 #endif
414                 name = false;
415                 if (!o_ptr->is_rare()) {
416                     entry->add(FLG_COMMON);
417                 }
418             }
419
420             entry->add(FLG_EGO);
421         } else if (o_ptr->is_fixed_or_random_artifact()) {
422             entry->add(FLG_ARTIFACT);
423         } else {
424             if (o_ptr->is_equipment()) {
425                 entry->add(FLG_NAMELESS);
426             }
427
428             is_hat_added = true;
429         }
430     }
431
432     if (o_ptr->is_melee_weapon()) {
433         const auto &baseitem = o_ptr->get_baseitem();
434         if ((o_ptr->dd != baseitem.dd) || (o_ptr->ds != baseitem.ds)) {
435             entry->add(FLG_BOOSTED);
436         }
437     }
438
439     if (object_is_bounty(player_ptr, o_ptr)) {
440         entry->remove(FLG_WORTHLESS);
441         entry->add(FLG_WANTED);
442     }
443
444     const auto r_idx = i2enum<MonsterRaceId>(o_ptr->pval);
445     const auto &bi_key = o_ptr->bi_key;
446     const auto tval = bi_key.tval();
447     if ((tval == ItemKindType::CORPSE || tval == ItemKindType::STATUE) && monraces_info[r_idx].kind_flags.has(MonsterKindType::UNIQUE)) {
448         entry->add(FLG_UNIQUE);
449     }
450
451     if (tval == ItemKindType::CORPSE && angband_strchr("pht", monraces_info[r_idx].d_char)) {
452         entry->add(FLG_HUMAN);
453     }
454
455     if (o_ptr->is_spell_book() && !check_book_realm(player_ptr, bi_key)) {
456         entry->add(FLG_UNREADABLE);
457         if (tval != ItemKindType::ARCANE_BOOK) {
458             name = false;
459         }
460     }
461
462     PlayerClass pc(player_ptr);
463     auto realm_except_class = pc.equals(PlayerClassType::SORCERER) || pc.equals(PlayerClassType::RED_MAGE);
464
465     if ((get_realm1_book(player_ptr) == tval) && !realm_except_class) {
466         entry->add(FLG_REALM1);
467         name = false;
468     }
469
470     if ((get_realm2_book(player_ptr) == tval) && !realm_except_class) {
471         entry->add(FLG_REALM2);
472         name = false;
473     }
474
475     const auto sval = bi_key.sval();
476     if (o_ptr->is_spell_book() && (sval == 0)) {
477         entry->add(FLG_FIRST);
478     }
479     if (o_ptr->is_spell_book() && (sval == 1)) {
480         entry->add(FLG_SECOND);
481     }
482     if (o_ptr->is_spell_book() && (sval == 2)) {
483         entry->add(FLG_THIRD);
484     }
485     if (o_ptr->is_spell_book() && (sval == 3)) {
486         entry->add(FLG_FOURTH);
487     }
488
489     if (o_ptr->is_ammo()) {
490         entry->add(FLG_MISSILES);
491     } else if (tval == ItemKindType::SCROLL || o_ptr->is_wand_staff() || o_ptr->is_wand_rod()) {
492         entry->add(FLG_DEVICES);
493     } else if (tval == ItemKindType::LITE) {
494         entry->add(FLG_LIGHTS);
495     } else if (o_ptr->is_junk()) {
496         entry->add(FLG_JUNKS);
497     } else if (tval == ItemKindType::CORPSE) {
498         entry->add(FLG_CORPSES);
499     } else if (o_ptr->is_spell_book()) {
500         entry->add(FLG_SPELLBOOKS);
501     } else if (o_ptr->is_melee_weapon()) {
502         entry->add(FLG_WEAPONS);
503     } else if (tval == ItemKindType::SHIELD) {
504         entry->add(FLG_SHIELDS);
505     } else if (tval == ItemKindType::BOW) {
506         entry->add(FLG_BOWS);
507     } else if (tval == ItemKindType::RING) {
508         entry->add(FLG_RINGS);
509     } else if (tval == ItemKindType::AMULET) {
510         entry->add(FLG_AMULETS);
511     } else if (o_ptr->is_armour()) {
512         entry->add(FLG_SUITS);
513     } else if (tval == ItemKindType::CLOAK) {
514         entry->add(FLG_CLOAKS);
515     } else if (tval == ItemKindType::HELM) {
516         entry->add(FLG_HELMS);
517     } else if (tval == ItemKindType::GLOVES) {
518         entry->add(FLG_GLOVES);
519     } else if (tval == ItemKindType::BOOTS) {
520         entry->add(FLG_BOOTS);
521     }
522
523     if (!name) {
524         str_tolower(entry->name.data());
525         return;
526     }
527
528     const auto item_name = describe_flavor(player_ptr, o_ptr, (OD_NO_FLAVOR | OD_OMIT_PREFIX | OD_NO_PLURAL | OD_NAME_ONLY));
529
530     /*
531      * If necessary, add a '^' which indicates the
532      * beginning of line.
533      */
534     entry->name = std::string(is_hat_added ? "^" : "").append(item_name);
535     str_tolower(entry->name.data());
536 }
537
538 std::string shape_autopick_key(const std::string &key)
539 {
540 #ifdef JP
541     return key;
542 #else
543     std::stringstream ss;
544     ss << key << ' ';
545     return ss.str();
546 #endif
547 }
548
549 /*!
550  * @brief Reconstruct preference line from entry
551  */
552 concptr autopick_line_from_entry(const autopick_type &entry)
553 {
554     std::stringstream ss;
555     if (!(entry.action & DO_DISPLAY)) {
556         ss << '(';
557     }
558
559     if (entry.action & DO_QUERY_AUTOPICK) {
560         ss << ';';
561     }
562
563     if (entry.action & DO_AUTODESTROY) {
564         ss << '!';
565     }
566
567     if (entry.action & DONT_AUTOPICK) {
568         ss << '~';
569     }
570
571     if (entry.has(FLG_ALL)) {
572         ss << shape_autopick_key(KEY_ALL);
573     }
574     if (entry.has(FLG_COLLECTING)) {
575         ss << shape_autopick_key(KEY_COLLECTING);
576     }
577     if (entry.has(FLG_UNAWARE)) {
578         ss << shape_autopick_key(KEY_UNAWARE);
579     }
580     if (entry.has(FLG_UNIDENTIFIED)) {
581         ss << shape_autopick_key(KEY_UNIDENTIFIED);
582     }
583     if (entry.has(FLG_IDENTIFIED)) {
584         ss << shape_autopick_key(KEY_IDENTIFIED);
585     }
586     if (entry.has(FLG_STAR_IDENTIFIED)) {
587         ss << shape_autopick_key(KEY_STAR_IDENTIFIED);
588     }
589     if (entry.has(FLG_BOOSTED)) {
590         ss << shape_autopick_key(KEY_BOOSTED);
591     }
592
593     if (entry.has(FLG_MORE_DICE)) {
594         ss << shape_autopick_key(KEY_MORE_THAN);
595         ss << entry.dice;
596         ss << shape_autopick_key(KEY_DICE);
597     }
598
599     if (entry.has(FLG_MORE_BONUS)) {
600         ss << shape_autopick_key(KEY_MORE_BONUS);
601         ss << entry.bonus;
602         ss << shape_autopick_key(KEY_MORE_BONUS2);
603     }
604
605     if (entry.has(FLG_UNREADABLE)) {
606         ss << shape_autopick_key(KEY_UNREADABLE);
607     }
608
609     if (entry.has(FLG_REALM1)) {
610         ss << shape_autopick_key(KEY_REALM1);
611     }
612
613     if (entry.has(FLG_REALM2)) {
614         ss << shape_autopick_key(KEY_REALM2);
615     }
616
617     if (entry.has(FLG_FIRST)) {
618         ss << shape_autopick_key(KEY_FIRST);
619     }
620
621     if (entry.has(FLG_SECOND)) {
622         ss << shape_autopick_key(KEY_SECOND);
623     }
624
625     if (entry.has(FLG_THIRD)) {
626         ss << shape_autopick_key(KEY_THIRD);
627     }
628
629     if (entry.has(FLG_FOURTH)) {
630         ss << shape_autopick_key(KEY_FOURTH);
631     }
632
633     if (entry.has(FLG_WANTED)) {
634         ss << shape_autopick_key(KEY_WANTED);
635     }
636
637     if (entry.has(FLG_UNIQUE)) {
638         ss << shape_autopick_key(KEY_UNIQUE);
639     }
640
641     if (entry.has(FLG_HUMAN)) {
642         ss << shape_autopick_key(KEY_HUMAN);
643     }
644
645     if (entry.has(FLG_WORTHLESS)) {
646         ss << shape_autopick_key(KEY_WORTHLESS);
647     }
648
649     if (entry.has(FLG_GOOD)) {
650         ss << shape_autopick_key(KEY_GOOD);
651     }
652
653     if (entry.has(FLG_NAMELESS)) {
654         ss << shape_autopick_key(KEY_NAMELESS);
655     }
656
657     if (entry.has(FLG_AVERAGE)) {
658         ss << shape_autopick_key(KEY_AVERAGE);
659     }
660
661     if (entry.has(FLG_RARE)) {
662         ss << shape_autopick_key(KEY_RARE);
663     }
664
665     if (entry.has(FLG_COMMON)) {
666         ss << shape_autopick_key(KEY_COMMON);
667     }
668
669     if (entry.has(FLG_EGO)) {
670         ss << shape_autopick_key(KEY_EGO);
671     }
672
673     if (entry.has(FLG_ARTIFACT)) {
674         ss << shape_autopick_key(KEY_ARTIFACT);
675     }
676
677     auto should_separate = true;
678     if (entry.has(FLG_ITEMS)) {
679         ss << KEY_ITEMS;
680     } else if (entry.has(FLG_WEAPONS)) {
681         ss << KEY_WEAPONS;
682     } else if (entry.has(FLG_FAVORITE_WEAPONS)) {
683         ss << KEY_FAVORITE_WEAPONS;
684     } else if (entry.has(FLG_ARMORS)) {
685         ss << KEY_ARMORS;
686     } else if (entry.has(FLG_MISSILES)) {
687         ss << KEY_MISSILES;
688     } else if (entry.has(FLG_DEVICES)) {
689         ss << KEY_DEVICES;
690     } else if (entry.has(FLG_LIGHTS)) {
691         ss << KEY_LIGHTS;
692     } else if (entry.has(FLG_JUNKS)) {
693         ss << KEY_JUNKS;
694     } else if (entry.has(FLG_CORPSES)) {
695         ss << KEY_CORPSES;
696     } else if (entry.has(FLG_SPELLBOOKS)) {
697         ss << KEY_SPELLBOOKS;
698     } else if (entry.has(FLG_HAFTED)) {
699         ss << KEY_HAFTED;
700     } else if (entry.has(FLG_SHIELDS)) {
701         ss << KEY_SHIELDS;
702     } else if (entry.has(FLG_BOWS)) {
703         ss << KEY_BOWS;
704     } else if (entry.has(FLG_RINGS)) {
705         ss << KEY_RINGS;
706     } else if (entry.has(FLG_AMULETS)) {
707         ss << KEY_AMULETS;
708     } else if (entry.has(FLG_SUITS)) {
709         ss << KEY_SUITS;
710     } else if (entry.has(FLG_CLOAKS)) {
711         ss << KEY_CLOAKS;
712     } else if (entry.has(FLG_HELMS)) {
713         ss << KEY_HELMS;
714     } else if (entry.has(FLG_GLOVES)) {
715         ss << KEY_GLOVES;
716     } else if (entry.has(FLG_BOOTS)) {
717         ss << KEY_BOOTS;
718     } else if (!entry.has(FLG_ARTIFACT)) {
719         should_separate = false;
720     }
721
722     if (!entry.name.empty()) {
723         if (should_separate) {
724             ss << ":";
725         }
726
727         ss << entry.name;
728     }
729
730     if (entry.insc.empty()) {
731         auto str = ss.str();
732         return string_make(str.data());
733     }
734
735     ss << '#' << entry.insc;
736     auto str = ss.str();
737     return string_make(str.data());
738 }
739
740 /*!
741  * @brief Choose an item and get auto-picker entry from it.
742  */
743 bool entry_from_choosed_object(PlayerType *player_ptr, autopick_type *entry)
744 {
745     constexpr auto q = _("どのアイテムを登録しますか? ", "Enter which item? ");
746     constexpr auto s = _("アイテムを持っていない。", "You have nothing to enter.");
747     auto *o_ptr = choose_object(player_ptr, nullptr, q, s, USE_INVEN | USE_FLOOR | USE_EQUIP);
748     if (!o_ptr) {
749         return false;
750     }
751
752     autopick_entry_from_object(player_ptr, entry, o_ptr);
753     return true;
754 }