3 /* Purpose: Object Auto-picker/Destroyer */
6 * Copyright (c) 2002 Mogami
8 * This software may be copied and distributed for educational, research, and
9 * not for profit purposes provided that this copyright and statement are
10 * included in all such copies.
16 #define MAX_LINELEN 1024
22 #define FLG_COLLECTING 1
24 #define FLG_UNIDENTIFIED 3
25 #define FLG_IDENTIFIED 4
26 #define FLG_STAR_IDENTIFIED 5
28 #define FLG_MORE_THAN 7
30 #define FLG_MORE_BONUS 9
31 #define FLG_MORE_BONUS2 10
32 #define FLG_WORTHLESS 11
33 #define FLG_ARTIFACT 12
35 #define FLG_NAMELESS 14
39 #define FLG_UNREADABLE 18
48 #define FLG_WEAPONS 31
50 #define FLG_MISSILES 33
51 #define FLG_DEVICES 34
54 #define FLG_SPELLBOOKS 37
56 #define FLG_SHIELDS 39
59 #define FLG_AMULETS 42
65 #define FLG_FAVORITE 48
67 #define FLG_NOUN_BEGIN FLG_ITEMS
68 #define FLG_NOUN_END FLG_FAVORITE
72 #define KEY_ALL "¤¹¤Ù¤Æ¤Î"
76 * MEGA HACK -- MPW¤Î¥Ð¥°½ü¤±¡£
77 * pre-processÃæ¤Ë¡Ö¼ý¡×¤Î»ú¤Î2¥Ð¥¤¥ÈÌܤ¬¾¡¼ê¤Ë¾Ã¤¨¤Æ¤·¤Þ¤¦¡£
79 #define KEY_COLLECTING "\x8e\xfb½¸Ãæ¤Î"
81 #define KEY_COLLECTING "¼ý½¸Ãæ¤Î"
84 #define KEY_UNIDENTIFIED "̤´ÕÄê¤Î"
85 #define KEY_IDENTIFIED "´ÕÄêºÑ¤ß¤Î"
86 #define KEY_STAR_IDENTIFIED "*´ÕÄê*ºÑ¤ß¤Î"
87 #define KEY_BOOSTED "¥À¥¤¥¹Ìܤΰ㤦"
88 #define KEY_MORE_THAN "¥À¥¤¥¹ÌÜ"
89 #define KEY_DICE "°Ê¾å¤Î"
90 #define KEY_MORE_BONUS "½¤ÀµÃÍ"
91 #define KEY_MORE_BONUS2 "°Ê¾å¤Î"
92 #define KEY_WORTHLESS "̵²ÁÃͤÎ"
93 #define KEY_ARTIFACT "¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È"
94 #define KEY_EGO "¥¨¥´"
95 #define KEY_NAMELESS "̵ÌäÎ"
96 #define KEY_UNAWARE "̤ȽÌÀ¤Î"
97 #define KEY_WANTED "¾Þ¶â¼ó¤Î"
98 #define KEY_UNIQUE "¥æ¥Ë¡¼¥¯¡¦¥â¥ó¥¹¥¿¡¼¤Î"
99 #define KEY_HUMAN "¿Í´Ö¤Î"
100 #define KEY_UNREADABLE "Æɤá¤Ê¤¤"
101 #define KEY_REALM1 "Âè°ìÎΰè¤Î"
102 #define KEY_REALM2 "ÂèÆóÎΰè¤Î"
103 #define KEY_FIRST "1ºýÌܤÎ"
104 #define KEY_SECOND "2ºýÌܤÎ"
105 #define KEY_THIRD "3ºýÌܤÎ"
106 #define KEY_FOURTH "4ºýÌܤÎ"
107 #define KEY_ITEMS "¥¢¥¤¥Æ¥à"
108 #define KEY_WEAPONS "Éð´ï"
109 #define KEY_ARMORS "Ëɶñ"
110 #define KEY_MISSILES "Ìð"
111 #define KEY_DEVICES "ËâË¡¥¢¥¤¥Æ¥à"
112 #define KEY_LIGHTS "¸÷¸»"
113 #define KEY_JUNKS "¤¬¤é¤¯¤¿"
114 #define KEY_SPELLBOOKS "ËâË¡½ñ"
115 #define KEY_HAFTED "Æß´ï"
116 #define KEY_SHIELDS "½â"
117 #define KEY_BOWS "µÝ"
118 #define KEY_RINGS "»ØÎØ"
119 #define KEY_AMULETS "¥¢¥ß¥å¥ì¥Ã¥È"
120 #define KEY_SUITS "³»"
121 #define KEY_CLOAKS "¥¯¥í¡¼¥¯"
122 #define KEY_HELMS "³õ"
123 #define KEY_GLOVES "äƼê"
124 #define KEY_BOOTS "·¤"
125 #define KEY_FAVORITE "ÆÀ°ÕÉð´ï"
129 #define KEY_ALL "all"
130 #define KEY_COLLECTING "collecting"
131 #define KEY_UNIDENTIFIED "unidentified"
132 #define KEY_IDENTIFIED "identified"
133 #define KEY_STAR_IDENTIFIED "*identified*"
134 #define KEY_BOOSTED "dice boosted"
135 #define KEY_MORE_THAN "more than"
136 #define KEY_DICE " dice"
137 #define KEY_MORE_BONUS "more bonus than"
138 #define KEY_MORE_BONUS2 ""
139 #define KEY_WORTHLESS "worthless"
140 #define KEY_ARTIFACT "artifact"
141 #define KEY_EGO "ego"
142 #define KEY_NAMELESS "nameless"
143 #define KEY_UNAWARE "unaware"
144 #define KEY_WANTED "wanted"
145 #define KEY_UNIQUE "unique monster's"
146 #define KEY_HUMAN "human"
147 #define KEY_UNREADABLE "unreadable"
148 #define KEY_REALM1 "first realm's"
149 #define KEY_REALM2 "second realm's"
150 #define KEY_FIRST "first"
151 #define KEY_SECOND "second"
152 #define KEY_THIRD "third"
153 #define KEY_FOURTH "fourth"
154 #define KEY_ITEMS "items"
155 #define KEY_WEAPONS "weapons"
156 #define KEY_ARMORS "armors"
157 #define KEY_MISSILES "missiles"
158 #define KEY_DEVICES "magical devices"
159 #define KEY_LIGHTS "lights"
160 #define KEY_JUNKS "junks"
161 #define KEY_SPELLBOOKS "spellbooks"
162 #define KEY_HAFTED "hafted weapons"
163 #define KEY_SHIELDS "shields"
164 #define KEY_BOWS "bows"
165 #define KEY_RINGS "rings"
166 #define KEY_AMULETS "amulets"
167 #define KEY_SUITS "suits"
168 #define KEY_CLOAKS "cloaks"
169 #define KEY_HELMS "helms"
170 #define KEY_GLOVES "gloves"
171 #define KEY_BOOTS "boots"
172 #define KEY_FAVORITE "favorite weapons"
176 #define MATCH_KEY(KEY) (!strncmp(ptr, KEY, sizeof(KEY)-1)\
177 ? (ptr += sizeof(KEY)-1, (' '==*ptr) ? ptr++ : 0, TRUE) : FALSE)
178 #define MATCH_KEY2(KEY) (!strncmp(ptr, KEY, sizeof(KEY)-1)\
179 ? (prev_ptr = ptr, ptr += sizeof(KEY)-1, (' '==*ptr) ? ptr++ : 0, TRUE) : FALSE)
182 #define ADD_KEY(KEY) strcat(ptr, KEY)
184 #define ADD_KEY(KEY) (strcat(ptr, KEY), strcat(ptr, " "))
186 #define ADD_KEY2(KEY) strcat(ptr, KEY)
188 #define ADD_FLG(FLG) (entry->flag[FLG / 32] |= (1L << (FLG % 32)))
189 #define REM_FLG(FLG) (entry->flag[FLG / 32] &= ~(1L << (FLG % 32)))
190 #define ADD_FLG_NOUN(FLG) (ADD_FLG(FLG), prev_flg = FLG)
191 #define IS_FLG(FLG) (entry->flag[FLG / 32] & (1L << (FLG % 32)))
194 static char kanji_colon[] = "¡§";
199 * A function to create new entry
201 bool autopick_new_entry(autopick_type *entry, cptr str)
206 char buf[MAX_LINELEN];
207 cptr prev_ptr, ptr, old_ptr;
210 if (str[1] == ':') switch (str[0])
213 case 'A': case 'P': case 'C':
217 entry->flag[0] = entry->flag[1] = 0L;
220 act = DO_AUTOPICK | DO_DISPLAY;
223 if ((act & DO_AUTOPICK) && *str == '!')
226 act |= DO_AUTODESTROY;
229 else if ((act & DO_AUTOPICK) && *str == '~')
232 act |= DONT_AUTOPICK;
235 else if ((act & DO_AUTOPICK) && *str == ';')
238 act |= DO_QUERY_AUTOPICK;
241 else if ((act & DO_DISPLAY) && *str == '(')
250 /* don't mind upper or lower case */
252 for (i = 0; *str; i++)
263 /* Auto-inscription? */
271 if (isupper(c)) c = tolower(c);
277 /* Skip comment line */
278 if (*buf == 0 && insc) return FALSE;
280 ptr = prev_ptr = buf;
283 while (old_ptr != ptr)
285 /* Save current location */
288 if (MATCH_KEY(KEY_ALL)) ADD_FLG(FLG_ALL);
289 if (MATCH_KEY(KEY_COLLECTING)) ADD_FLG(FLG_COLLECTING);
290 if (MATCH_KEY(KEY_UNIDENTIFIED)) ADD_FLG(FLG_UNIDENTIFIED);
291 if (MATCH_KEY(KEY_IDENTIFIED)) ADD_FLG(FLG_IDENTIFIED);
292 if (MATCH_KEY(KEY_STAR_IDENTIFIED)) ADD_FLG(FLG_STAR_IDENTIFIED);
293 if (MATCH_KEY(KEY_BOOSTED)) ADD_FLG(FLG_BOOSTED);
295 /*** Weapons whose dd*ds is more than nn ***/
296 if (MATCH_KEY2(KEY_MORE_THAN))
301 /* Drop leading spaces */
302 while (' ' == *ptr) ptr++;
305 while ('0' <= *ptr && *ptr <= '9')
307 entry->dice = 10 * entry->dice + (*ptr - '0');
314 (void)MATCH_KEY(KEY_DICE);
315 ADD_FLG(FLG_MORE_THAN);
321 /*** Items whose magical bonus is more than n ***/
322 if (MATCH_KEY2(KEY_MORE_BONUS))
327 /* Drop leading spaces */
328 while (' ' == *ptr) ptr++;
331 while ('0' <= *ptr && *ptr <= '9')
333 entry->bonus = 10 * entry->bonus + (*ptr - '0');
340 (void)MATCH_KEY(KEY_MORE_BONUS2);
341 ADD_FLG(FLG_MORE_BONUS);
347 if (MATCH_KEY(KEY_WORTHLESS)) ADD_FLG(FLG_WORTHLESS);
348 if (MATCH_KEY(KEY_EGO)) ADD_FLG(FLG_EGO);
349 if (MATCH_KEY(KEY_NAMELESS)) ADD_FLG(FLG_NAMELESS);
350 if (MATCH_KEY(KEY_UNAWARE)) ADD_FLG(FLG_UNAWARE);
351 if (MATCH_KEY(KEY_WANTED)) ADD_FLG(FLG_WANTED);
352 if (MATCH_KEY(KEY_UNIQUE)) ADD_FLG(FLG_UNIQUE);
353 if (MATCH_KEY(KEY_HUMAN)) ADD_FLG(FLG_HUMAN);
354 if (MATCH_KEY(KEY_UNREADABLE)) ADD_FLG(FLG_UNREADABLE);
355 if (MATCH_KEY(KEY_REALM1)) ADD_FLG(FLG_REALM1);
356 if (MATCH_KEY(KEY_REALM2)) ADD_FLG(FLG_REALM2);
357 if (MATCH_KEY(KEY_FIRST)) ADD_FLG(FLG_FIRST);
358 if (MATCH_KEY(KEY_SECOND)) ADD_FLG(FLG_SECOND);
359 if (MATCH_KEY(KEY_THIRD)) ADD_FLG(FLG_THIRD);
360 if (MATCH_KEY(KEY_FOURTH)) ADD_FLG(FLG_FOURTH);
363 /* Not yet found any noun */
366 if (MATCH_KEY2(KEY_ARTIFACT)) ADD_FLG_NOUN(FLG_ARTIFACT);
368 if (MATCH_KEY2(KEY_ITEMS)) ADD_FLG_NOUN(FLG_ITEMS);
369 else if (MATCH_KEY2(KEY_WEAPONS)) ADD_FLG_NOUN(FLG_WEAPONS);
370 else if (MATCH_KEY2(KEY_ARMORS)) ADD_FLG_NOUN(FLG_ARMORS);
371 else if (MATCH_KEY2(KEY_MISSILES)) ADD_FLG_NOUN(FLG_MISSILES);
372 else if (MATCH_KEY2(KEY_DEVICES)) ADD_FLG_NOUN(FLG_DEVICES);
373 else if (MATCH_KEY2(KEY_LIGHTS)) ADD_FLG_NOUN(FLG_LIGHTS);
374 else if (MATCH_KEY2(KEY_JUNKS)) ADD_FLG_NOUN(FLG_JUNKS);
375 else if (MATCH_KEY2(KEY_SPELLBOOKS)) ADD_FLG_NOUN(FLG_SPELLBOOKS);
376 else if (MATCH_KEY2(KEY_HAFTED)) ADD_FLG_NOUN(FLG_HAFTED);
377 else if (MATCH_KEY2(KEY_SHIELDS)) ADD_FLG_NOUN(FLG_SHIELDS);
378 else if (MATCH_KEY2(KEY_BOWS)) ADD_FLG_NOUN(FLG_BOWS);
379 else if (MATCH_KEY2(KEY_RINGS)) ADD_FLG_NOUN(FLG_RINGS);
380 else if (MATCH_KEY2(KEY_AMULETS)) ADD_FLG_NOUN(FLG_AMULETS);
381 else if (MATCH_KEY2(KEY_SUITS)) ADD_FLG_NOUN(FLG_SUITS);
382 else if (MATCH_KEY2(KEY_CLOAKS)) ADD_FLG_NOUN(FLG_CLOAKS);
383 else if (MATCH_KEY2(KEY_HELMS)) ADD_FLG_NOUN(FLG_HELMS);
384 else if (MATCH_KEY2(KEY_GLOVES)) ADD_FLG_NOUN(FLG_GLOVES);
385 else if (MATCH_KEY2(KEY_BOOTS)) ADD_FLG_NOUN(FLG_BOOTS);
386 else if (MATCH_KEY2(KEY_FAVORITE)) ADD_FLG_NOUN(FLG_FAVORITE);
388 /* Last 'keyword' must be at the correct location */
392 else if (ptr[0] == kanji_colon[0] && ptr[1] == kanji_colon[1])
395 else if (*ptr == '\0')
397 /* There was no noun */
400 /* Add extra word "items" */
401 ADD_FLG_NOUN(FLG_ITEMS);
408 /* A noun type keyword didn't end correctly */
409 entry->flag[prev_flg/32] &= ~(1L<< (prev_flg%32));
414 /* Save this auto-picker entry line */
415 entry->name = string_make(ptr);
417 entry->insc = string_make(insc);
424 * A function to delete entry
426 void autopick_free_entry(autopick_type *entry)
428 string_free(entry->name);
429 string_free(entry->insc);
434 * Initialize auto-picker preference
436 void init_autopicker(void)
438 static const char easy_autopick_inscription[] = "(:=g";
442 /* Clear old entries */
443 for( i = 0; i < max_autopick; i++)
444 autopick_free_entry(&autopick_list[i]);
448 /* There is always one entry "=g" */
449 autopick_new_entry(&entry, easy_autopick_inscription);
450 autopick_list[max_autopick++] = entry;
456 * Process line for auto picker/destroyer.
458 errr process_pickpref_file_line(char *buf)
463 if (max_autopick == MAX_AUTOPICK)
466 /* Nuke illegal char */
467 for(i = 0; buf[i]; i++)
476 if (isspace(buf[i]) && buf[i] != ' ')
481 if (!autopick_new_entry(&entry, buf)) return 0;
483 /* Already has the same entry? */
484 for(i = 0; i < max_autopick; i++)
485 if(!strcmp(entry.name, autopick_list[i].name)
486 && entry.flag[0] == autopick_list[i].flag[0]
487 && entry.flag[1] == autopick_list[i].flag[1]
488 && entry.dice == autopick_list[i].dice
489 && entry.bonus == autopick_list[i].bonus) return 0;
491 autopick_list[max_autopick++] = entry;
497 * Reconstruct preference line from entry
499 cptr autopick_line_from_entry(autopick_type *entry)
501 char buf[MAX_LINELEN];
503 bool sepa_flag = TRUE;
506 if (!(entry->action & DO_DISPLAY)) strcat(buf, "(");
507 if (entry->action & DO_QUERY_AUTOPICK) strcat(buf, ";");
508 if (entry->action & DO_AUTODESTROY) strcat(buf, "!");
509 if (entry->action & DONT_AUTOPICK) strcat(buf, "~");
513 if (IS_FLG(FLG_ALL)) ADD_KEY(KEY_ALL);
514 if (IS_FLG(FLG_COLLECTING)) ADD_KEY(KEY_COLLECTING);
515 if (IS_FLG(FLG_UNIDENTIFIED)) ADD_KEY(KEY_UNIDENTIFIED);
516 if (IS_FLG(FLG_IDENTIFIED)) ADD_KEY(KEY_IDENTIFIED);
517 if (IS_FLG(FLG_STAR_IDENTIFIED)) ADD_KEY(KEY_STAR_IDENTIFIED);
518 if (IS_FLG(FLG_UNAWARE)) ADD_KEY(KEY_UNAWARE);
519 if (IS_FLG(FLG_BOOSTED)) ADD_KEY(KEY_BOOSTED);
521 if (IS_FLG(FLG_MORE_THAN))
523 ADD_KEY(KEY_MORE_THAN);
524 strcat(ptr, format("%d", entry->dice));
528 if (IS_FLG(FLG_MORE_BONUS))
530 ADD_KEY(KEY_MORE_BONUS);
531 strcat(ptr, format("%d", entry->bonus));
532 ADD_KEY(KEY_MORE_BONUS2);
535 if (IS_FLG(FLG_UNREADABLE)) ADD_KEY(KEY_UNREADABLE);
536 if (IS_FLG(FLG_REALM1)) ADD_KEY(KEY_REALM1);
537 if (IS_FLG(FLG_REALM2)) ADD_KEY(KEY_REALM2);
538 if (IS_FLG(FLG_FIRST)) ADD_KEY(KEY_FIRST);
539 if (IS_FLG(FLG_SECOND)) ADD_KEY(KEY_SECOND);
540 if (IS_FLG(FLG_THIRD)) ADD_KEY(KEY_THIRD);
541 if (IS_FLG(FLG_FOURTH)) ADD_KEY(KEY_FOURTH);
542 if (IS_FLG(FLG_WANTED)) ADD_KEY(KEY_WANTED);
543 if (IS_FLG(FLG_UNIQUE)) ADD_KEY(KEY_UNIQUE);
544 if (IS_FLG(FLG_HUMAN)) ADD_KEY(KEY_HUMAN);
545 if (IS_FLG(FLG_WORTHLESS)) ADD_KEY(KEY_WORTHLESS);
546 if (IS_FLG(FLG_NAMELESS)) ADD_KEY(KEY_NAMELESS);
547 if (IS_FLG(FLG_EGO)) ADD_KEY(KEY_EGO);
549 if (IS_FLG(FLG_ARTIFACT)) ADD_KEY(KEY_ARTIFACT);
551 if (IS_FLG(FLG_ITEMS)) ADD_KEY2(KEY_ITEMS);
552 else if (IS_FLG(FLG_WEAPONS)) ADD_KEY2(KEY_WEAPONS);
553 else if (IS_FLG(FLG_ARMORS)) ADD_KEY2(KEY_ARMORS);
554 else if (IS_FLG(FLG_MISSILES)) ADD_KEY2(KEY_MISSILES);
555 else if (IS_FLG(FLG_DEVICES)) ADD_KEY2(KEY_DEVICES);
556 else if (IS_FLG(FLG_LIGHTS)) ADD_KEY2(KEY_LIGHTS);
557 else if (IS_FLG(FLG_JUNKS)) ADD_KEY2(KEY_JUNKS);
558 else if (IS_FLG(FLG_SPELLBOOKS)) ADD_KEY2(KEY_SPELLBOOKS);
559 else if (IS_FLG(FLG_HAFTED)) ADD_KEY2(KEY_HAFTED);
560 else if (IS_FLG(FLG_SHIELDS)) ADD_KEY2(KEY_SHIELDS);
561 else if (IS_FLG(FLG_BOWS)) ADD_KEY2(KEY_BOWS);
562 else if (IS_FLG(FLG_RINGS)) ADD_KEY2(KEY_RINGS);
563 else if (IS_FLG(FLG_AMULETS)) ADD_KEY2(KEY_AMULETS);
564 else if (IS_FLG(FLG_SUITS)) ADD_KEY2(KEY_SUITS);
565 else if (IS_FLG(FLG_CLOAKS)) ADD_KEY2(KEY_CLOAKS);
566 else if (IS_FLG(FLG_HELMS)) ADD_KEY2(KEY_HELMS);
567 else if (IS_FLG(FLG_GLOVES)) ADD_KEY2(KEY_GLOVES);
568 else if (IS_FLG(FLG_BOOTS)) ADD_KEY2(KEY_BOOTS);
569 else if (IS_FLG(FLG_FAVORITE)) ADD_KEY2(KEY_FAVORITE);
571 /* You don't need sepalator after adjective */
572 /* 'artifact' is not true adjective */
573 else if (!IS_FLG(FLG_ARTIFACT))
576 if (entry->name && entry->name[0])
580 if (sepa_flag) strcat(buf, ":");
583 while (entry->name[j] && i < MAX_LINELEN - 2 - 1)
586 if (iskanji(entry->name[j]))
587 buf[i++] = entry->name[j++];
589 buf[i++] = entry->name[j++];
600 while (entry->insc[j] && i < MAX_LINELEN - 2)
603 if (iskanji(entry->insc[j]))
604 buf[i++] = entry->insc[j++];
606 buf[i++] = entry->insc[j++];
611 return string_make(buf);
616 * Reconstruct preference line from entry and kill entry
618 static cptr autopick_line_from_entry_kill(autopick_type *entry)
620 cptr ptr = autopick_line_from_entry(entry);
622 /* Free memory for original entry */
623 autopick_free_entry(entry);
632 static bool is_favorite(object_type *o_ptr, bool others_ok)
634 /* Only weapons match */
637 case TV_BOW: case TV_HAFTED: case TV_POLEARM:
638 case TV_SWORD: case TV_DIGGING:
640 default: return FALSE;
643 /* Favorite weapons are varied depend on the class */
644 switch (p_ptr->pclass)
648 u32b flgs[TR_FLAG_SIZE];
649 object_flags_known(o_ptr, flgs);
651 if (!have_flag(flgs, TR_BLESSED) &&
652 !(o_ptr->tval == TV_HAFTED))
658 case CLASS_FORCETRAINER:
660 if (!(s_info[p_ptr->pclass].w_max[o_ptr->tval-TV_BOW][o_ptr->sval]))
664 case CLASS_BEASTMASTER:
667 u32b flgs[TR_FLAG_SIZE];
668 object_flags_known(o_ptr, flgs);
670 /* Is it known to be suitable to using while riding? */
671 if (!(have_flag(flgs, TR_RIDING)))
679 if (s_info[p_ptr->pclass].w_max[o_ptr->tval-TV_BOW][o_ptr->sval] <= WEAPON_EXP_BEGINNER)
684 /* Non-special class */
685 if (others_ok) return TRUE;
693 * A function for Auto-picker/destroyer
694 * Examine whether the object matches to the entry
696 static bool is_autopick_aux(object_type *o_ptr, autopick_type *entry, cptr o_name)
699 cptr ptr = entry->name;
701 /*** Unidentified ***/
702 if (IS_FLG(FLG_UNIDENTIFIED)
703 && (object_known_p(o_ptr) || (o_ptr->ident & IDENT_SENSE)))
707 if (IS_FLG(FLG_IDENTIFIED) && !object_known_p(o_ptr))
710 /*** *Identified* ***/
711 if (IS_FLG(FLG_STAR_IDENTIFIED) &&
712 (!object_known_p(o_ptr) || !(o_ptr->ident & IDENT_MENTAL)))
715 /*** Dice boosted (weapon of slaying) ***/
716 if (IS_FLG(FLG_BOOSTED))
718 object_kind *k_ptr = &k_info[o_ptr->k_idx];
720 switch( o_ptr->tval )
726 if ((o_ptr->dd != k_ptr->dd) || (o_ptr->ds != k_ptr->ds))
735 /*** Weapons which dd*ds is more than nn ***/
736 if (IS_FLG(FLG_MORE_THAN))
738 if (o_ptr->dd * o_ptr->ds < entry->dice)
742 /*** Weapons whic dd*ds is more than nn ***/
743 if (IS_FLG(FLG_MORE_BONUS))
745 if (!object_known_p(o_ptr)) return FALSE;
749 if (o_ptr->pval < entry->bonus) return FALSE;
753 if (o_ptr->to_h < entry->bonus &&
754 o_ptr->to_d < entry->bonus &&
755 o_ptr->to_a < entry->bonus &&
756 o_ptr->pval < entry->bonus)
761 /*** Worthless items ***/
762 if (IS_FLG(FLG_WORTHLESS) && object_value(o_ptr) > 0)
765 /*** Artifact object ***/
766 if (IS_FLG(FLG_ARTIFACT))
768 if (!object_known_p(o_ptr) || (!o_ptr->name1 && !o_ptr->art_name))
775 if (!object_known_p(o_ptr) || !o_ptr->name2)
780 if (IS_FLG(FLG_NAMELESS))
785 case TV_SHOT: case TV_ARROW: case TV_BOLT: case TV_BOW:
786 case TV_DIGGING: case TV_HAFTED: case TV_POLEARM: case TV_SWORD:
787 case TV_BOOTS: case TV_GLOVES: case TV_HELM: case TV_CROWN:
788 case TV_SHIELD: case TV_CLOAK:
789 case TV_SOFT_ARMOR: case TV_HARD_ARMOR: case TV_DRAG_ARMOR:
790 case TV_LITE: case TV_AMULET: case TV_RING: case TV_CARD:
791 if ((!object_known_p(o_ptr) || o_ptr->inscription
792 || o_ptr->name1 || o_ptr->name2 || o_ptr->art_name))
801 /*** Unaware items ***/
802 if (IS_FLG(FLG_UNAWARE) && object_aware_p(o_ptr))
805 /*** Wanted monster's corpse/skeletons ***/
806 if (IS_FLG(FLG_WANTED) &&
807 (o_ptr->tval != TV_CORPSE || !object_is_shoukinkubi(o_ptr)))
810 /*** Unique monster's corpse/skeletons/statues ***/
811 if (IS_FLG(FLG_UNIQUE) &&
812 ((o_ptr->tval != TV_CORPSE && o_ptr->tval != TV_STATUE) ||
813 !(r_info[o_ptr->pval].flags1 & RF1_UNIQUE)))
816 /*** Human corpse/skeletons (for Daemon magic) ***/
817 if (IS_FLG(FLG_HUMAN) &&
818 (o_ptr->tval != TV_CORPSE ||
819 !strchr("pht", r_info[o_ptr->pval].d_char)))
822 /*** Unreadable spellbooks ***/
823 if (IS_FLG(FLG_UNREADABLE) &&
824 (o_ptr->tval < TV_LIFE_BOOK ||
825 check_book_realm(o_ptr->tval, o_ptr->sval)))
828 /*** First realm spellbooks ***/
829 if (IS_FLG(FLG_REALM1) &&
830 (REALM1_BOOK != o_ptr->tval ||
831 p_ptr->pclass == CLASS_SORCERER ||
832 p_ptr->pclass == CLASS_RED_MAGE))
835 /*** Second realm spellbooks ***/
836 if (IS_FLG(FLG_REALM2) &&
837 (REALM2_BOOK != o_ptr->tval ||
838 p_ptr->pclass == CLASS_SORCERER ||
839 p_ptr->pclass == CLASS_RED_MAGE))
842 /*** First rank spellbooks ***/
843 if (IS_FLG(FLG_FIRST) &&
844 (o_ptr->tval < TV_LIFE_BOOK || 0 != o_ptr->sval))
847 /*** Second rank spellbooks ***/
848 if (IS_FLG(FLG_SECOND) &&
849 (o_ptr->tval < TV_LIFE_BOOK || 1 != o_ptr->sval))
852 /*** Third rank spellbooks ***/
853 if (IS_FLG(FLG_THIRD) &&
854 (o_ptr->tval < TV_LIFE_BOOK || 2 != o_ptr->sval))
857 /*** Fourth rank spellbooks ***/
858 if (IS_FLG(FLG_FOURTH) &&
859 (o_ptr->tval < TV_LIFE_BOOK || 3 != o_ptr->sval))
863 if (IS_FLG(FLG_WEAPONS))
867 case TV_BOW: case TV_HAFTED: case TV_POLEARM:
868 case TV_SWORD: case TV_DIGGING:
870 default: return FALSE;
873 else if (IS_FLG(FLG_ARMORS))
877 case TV_BOOTS: case TV_GLOVES: case TV_CLOAK: case TV_CROWN:
878 case TV_HELM: case TV_SHIELD: case TV_SOFT_ARMOR:
879 case TV_HARD_ARMOR: case TV_DRAG_ARMOR:
881 default: return FALSE;
884 else if (IS_FLG(FLG_MISSILES))
888 case TV_SHOT: case TV_BOLT: case TV_ARROW:
890 default: return FALSE;
893 else if (IS_FLG(FLG_DEVICES))
897 case TV_SCROLL: case TV_STAFF: case TV_WAND: case TV_ROD:
899 default: return FALSE;
902 else if (IS_FLG(FLG_LIGHTS))
904 if (!(o_ptr->tval == TV_LITE))
907 else if (IS_FLG(FLG_JUNKS))
911 case TV_SKELETON: case TV_BOTTLE:
912 case TV_JUNK: case TV_STATUE:
914 default: return FALSE;
917 else if (IS_FLG(FLG_SPELLBOOKS))
919 if (!(o_ptr->tval >= TV_LIFE_BOOK))
922 else if (IS_FLG(FLG_HAFTED))
924 if (!(o_ptr->tval == TV_HAFTED))
927 else if (IS_FLG(FLG_SHIELDS))
929 if (!(o_ptr->tval == TV_SHIELD))
932 else if (IS_FLG(FLG_BOWS))
934 if (!(o_ptr->tval == TV_BOW))
937 else if (IS_FLG(FLG_RINGS))
939 if (!(o_ptr->tval == TV_RING))
942 else if (IS_FLG(FLG_AMULETS))
944 if (!(o_ptr->tval == TV_AMULET))
947 else if (IS_FLG(FLG_SUITS))
949 if (!(o_ptr->tval == TV_DRAG_ARMOR ||
950 o_ptr->tval == TV_HARD_ARMOR ||
951 o_ptr->tval == TV_SOFT_ARMOR))
954 else if (IS_FLG(FLG_CLOAKS))
956 if (!(o_ptr->tval == TV_CLOAK))
959 else if (IS_FLG(FLG_HELMS))
961 if (!(o_ptr->tval == TV_CROWN || o_ptr->tval == TV_HELM))
964 else if (IS_FLG(FLG_GLOVES))
966 if (!(o_ptr->tval == TV_GLOVES))
969 else if (IS_FLG(FLG_BOOTS))
971 if (!(o_ptr->tval == TV_BOOTS))
974 else if (IS_FLG(FLG_FAVORITE))
976 if (!is_favorite(o_ptr, TRUE))
980 /* Keyword don't match */
984 if (strncmp(o_name, ptr, strlen(ptr))) return FALSE;
989 if (!strstr_j(o_name, ptr)) return FALSE;
991 if (!strstr(o_name, ptr)) return FALSE;
995 /* TRUE when it need not to be 'collecting' */
996 if (!IS_FLG(FLG_COLLECTING)) return TRUE;
998 /* Check if there is a same item */
999 for (j = 0; j < INVEN_PACK; j++)
1002 * 'Collecting' means the item must be absorbed
1003 * into an inventory slot.
1004 * But an item can not be absorbed into itself!
1006 if ((&inventory[j] != o_ptr) &&
1007 object_similar(&inventory[j], o_ptr))
1011 /* Not collecting */
1017 * A function for Auto-picker/destroyer
1018 * Examine whether the object matches to the list of keywords or not.
1020 int is_autopick(object_type *o_ptr)
1023 char o_name[MAX_NLEN];
1025 if (o_ptr->tval == TV_GOLD) return -1;
1027 object_desc(o_name, o_ptr, FALSE, 3);
1029 /* Force to be lower case string */
1030 for (i = 0; o_name[i]; i++)
1033 if (iskanji(o_name[i]))
1037 if (isupper(o_name[i]))
1038 o_name[i] = tolower(o_name[i]);
1041 for (i=0; i < max_autopick; i++)
1043 autopick_type *entry = &autopick_list[i];
1045 if (is_autopick_aux(o_ptr, entry, o_name)) return i;
1048 /* No matching entry */
1056 void auto_inscribe_item(int item, int idx)
1060 /* Get the item (in the pack) */
1061 if (item >= 0) o_ptr = &inventory[item];
1063 /* Get the item (on the floor) */
1064 else o_ptr = &o_list[0 - item];
1066 /* Auto-inscription or Re-inscribe for resistances {%} */
1067 if ((idx < 0 || !autopick_list[idx].insc) && !o_ptr->inscription)
1070 if (!o_ptr->inscription)
1071 o_ptr->inscription = quark_add(autopick_list[idx].insc);
1073 if (item > INVEN_PACK)
1075 /* Redraw inscription */
1076 p_ptr->window |= (PW_EQUIP);
1078 /* {.} and {$} effect p_ptr->warning and TRC_TELEPORT_SELF */
1079 p_ptr->update |= (PU_BONUS);
1083 /* Redraw inscription */
1084 p_ptr->window |= (PW_INVEN);
1090 * Automatically destroy items in this grid.
1092 static bool is_opt_confirm_destroy(object_type *o_ptr)
1094 if (!destroy_items) return FALSE;
1096 /* Known to be worthless? */
1098 if (object_value(o_ptr) > 0) return FALSE;
1101 if ((o_ptr->tval >= TV_SHOT) && (o_ptr->tval <= TV_DRAG_ARMOR)) return FALSE;
1104 if ((o_ptr->tval == TV_CHEST) && o_ptr->pval) return FALSE;
1108 if (o_ptr->tval == TV_CORPSE
1109 && object_is_shoukinkubi(o_ptr)) return FALSE;
1113 if (o_ptr->tval == TV_CORPSE) return FALSE;
1116 if ((o_ptr->tval == TV_SKELETON) || (o_ptr->tval == TV_BOTTLE) || (o_ptr->tval == TV_JUNK) || (o_ptr->tval == TV_STATUE)) return FALSE;
1120 if (p_ptr->prace == RACE_DEMON)
1122 if (o_ptr->tval == TV_CORPSE &&
1123 o_ptr->sval == SV_CORPSE &&
1124 strchr("pht", r_info[o_ptr->pval].d_char))
1128 if (p_ptr->pclass == CLASS_ARCHER)
1130 if (o_ptr->tval == TV_SKELETON ||
1131 (o_ptr->tval == TV_CORPSE && o_ptr->sval == SV_SKELETON))
1134 else if (p_ptr->pclass == CLASS_NINJA)
1136 if (o_ptr->tval == TV_LITE &&
1137 o_ptr->name2 == EGO_LITE_DARKNESS)
1140 else if (p_ptr->pclass == CLASS_BEASTMASTER ||
1141 p_ptr->pclass == CLASS_CAVALRY)
1143 if (o_ptr->tval == TV_WAND &&
1144 o_ptr->sval == SV_WAND_HEAL_MONSTER)
1149 if (o_ptr->tval == TV_GOLD) return FALSE;
1156 * Automatically destroy an item if it is to be destroyed
1158 static object_type autopick_last_destroyed_object;
1160 bool auto_destroy_item(int item, int autopick_idx)
1162 bool destroy = FALSE;
1165 /* Don't destroy equipped items */
1166 if (item > INVEN_PACK) return FALSE;
1168 /* Get the item (in the pack) */
1169 if (item >= 0) o_ptr = &inventory[item];
1171 /* Get the item (on the floor) */
1172 else o_ptr = &o_list[0 - item];
1174 /* Easy-Auto-Destroyer */
1175 if (is_opt_confirm_destroy(o_ptr)) destroy = TRUE;
1177 /* Protected by auto-picker */
1178 if (autopick_idx >= 0 &&
1179 !(autopick_list[autopick_idx].action & DO_AUTODESTROY))
1184 /* Auto-picker/destroyer */
1185 if (autopick_idx >= 0 &&
1186 (autopick_list[autopick_idx].action & DO_AUTODESTROY))
1190 /* Not to be destroyed */
1191 if (!destroy) return FALSE;
1193 /* Now decided to destroy */
1198 if (!can_player_destroy_object(o_ptr))
1200 char o_name[MAX_NLEN];
1202 /* Describe the object (with {terrible/special}) */
1203 object_desc(o_name, o_ptr, TRUE, 3);
1207 msg_format("%s¤ÏÇ˲õÉÔǽ¤À¡£", o_name);
1209 msg_format("You cannot auto-destroy %s.", o_name);
1216 /* Record name of destroyed item */
1217 COPY(&autopick_last_destroyed_object, o_ptr, object_type);
1220 o_ptr->marked |= OM_AUTODESTROY;
1221 p_ptr->notice |= PN_AUTODESTROY;
1228 * Auto-destroy marked item
1230 static void delayed_auto_destroy_aux(int item)
1234 /* Get the item (in the pack) */
1235 if (item >= 0) o_ptr = &inventory[item];
1237 /* Get the item (on the floor) */
1238 else o_ptr = &o_list[0 - item];
1240 if (o_ptr->k_idx && o_ptr->marked & OM_AUTODESTROY)
1242 char o_name[MAX_NLEN];
1244 /* Describe the object (with {terrible/special}) */
1245 object_desc(o_name, o_ptr, TRUE, 3);
1247 /* Eliminate the item (from the pack) */
1250 inven_item_increase(item, -(o_ptr->number));
1251 inven_item_optimize(item);
1254 /* Eliminate the item (from the floor) */
1257 delete_object_idx(0 - item);
1260 /* Print a message */
1262 msg_format("%s¤ò¼«Æ°Ç˲õ¤·¤Þ¤¹¡£", o_name);
1264 msg_format("Auto-destroying %s.", o_name);
1271 * Auto-destroy marked item in inventry and on floor
1273 void delayed_auto_destroy(void)
1278 * Scan inventry in reverse order to prevent
1279 * skipping after inven_item_optimize()
1281 for (item = INVEN_TOTAL - 1; item >= 0 ; item--)
1282 delayed_auto_destroy_aux(item);
1284 /* Scan the pile of objects */
1285 item = cave[py][px].o_idx;
1288 int next = o_list[item].next_o_idx;
1289 delayed_auto_destroy_aux(-item);
1296 * Automatically pickup/destroy items in this grid.
1298 void auto_pickup_items(cave_type *c_ptr)
1300 s16b this_o_idx, next_o_idx = 0;
1302 /* Scan the pile of objects */
1303 for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
1307 /* Acquire object */
1308 object_type *o_ptr = &o_list[this_o_idx];
1310 /* Acquire next object */
1311 next_o_idx = o_ptr->next_o_idx;
1313 idx = is_autopick(o_ptr);
1315 /* Item index for floor -1,-2,-3,... */
1316 auto_inscribe_item((-this_o_idx), idx);
1319 (autopick_list[idx].action & (DO_AUTOPICK | DO_QUERY_AUTOPICK)))
1323 if (!inven_carry_okay(o_ptr))
1325 char o_name[MAX_NLEN];
1327 /* Describe the object */
1328 object_desc(o_name, o_ptr, TRUE, 3);
1332 msg_format("¥¶¥Ã¥¯¤Ë¤Ï%s¤òÆþ¤ì¤ë·ä´Ö¤¬¤Ê¤¤¡£", o_name);
1334 msg_format("You have no room for %s.", o_name);
1336 /* Hack - remember that the item has given a message here. */
1337 o_ptr->marked |= OM_NOMSG;
1341 else if (autopick_list[idx].action & DO_QUERY_AUTOPICK)
1343 char out_val[MAX_NLEN+20];
1344 char o_name[MAX_NLEN];
1346 if (o_ptr->marked & OM_NO_QUERY)
1348 /* Already answered as 'No' */
1352 /* Describe the object */
1353 object_desc(o_name, o_ptr, TRUE, 3);
1356 sprintf(out_val, "%s¤ò½¦¤¤¤Þ¤¹¤«? ", o_name);
1358 sprintf(out_val, "Pick up %s? ", o_name);
1361 if (!get_check(out_val))
1363 /* Hack - remember that the item has given a message here. */
1364 o_ptr->marked |= (OM_NOMSG | OM_NO_QUERY);
1369 py_pickup_aux(this_o_idx);
1376 * When always_pickup is 'yes', we disable
1377 * auto-destroyer from autopick function, and do only
1378 * easy-auto-destroyer.
1382 if (auto_destroy_item((-this_o_idx), idx))
1389 /******** Auto-picker/destroyer editor **********/
1391 #define MAX_YANK MAX_LINELEN
1393 #define MARK_MARK 0x01
1394 #define MARK_BY_SHIFT 0x02
1397 * Struct for yank buffer
1399 typedef struct chain_str {
1400 struct chain_str *next;
1406 * Data struct for text editor
1412 int old_wid, old_hgt;
1414 int old_upper, old_left;
1418 object_type *search_o_ptr;
1420 cptr last_destroyed;
1422 chain_str_type *yank;
1435 * Dirty flag for text editor
1437 #define DIRTY_ALL 0x01
1438 #define DIRTY_MODE 0x04
1439 #define DIRTY_SCREEN 0x08
1440 #define DIRTY_NOT_FOUND 0x10
1441 #define DIRTY_NO_SEARCH 0x20
1445 * Describe which kind of object is Auto-picked/destroyed
1447 static void describe_autopick(char *buff, autopick_type *entry)
1449 cptr str = entry->name;
1450 byte act = entry->action;
1451 cptr insc = entry->insc;
1457 cptr before_str[100], body_str;
1460 body_str = "¥¢¥¤¥Æ¥à";
1462 /*** Collecting items ***/
1463 /*** Which can be absorbed into a slot as a bundle ***/
1464 if (IS_FLG(FLG_COLLECTING))
1465 before_str[before_n++] = "¼ý½¸Ãæ¤Ç´û¤Ë»ý¤Ã¤Æ¤¤¤ë¥¹¥í¥Ã¥È¤Ë¤Þ¤È¤á¤é¤ì¤ë";
1467 /*** Unidentified ***/
1468 if (IS_FLG(FLG_UNIDENTIFIED))
1469 before_str[before_n++] = "̤´ÕÄê¤Î";
1471 /*** Identified ***/
1472 if (IS_FLG(FLG_IDENTIFIED))
1473 before_str[before_n++] = "´ÕÄêºÑ¤ß¤Î";
1475 /*** *Identified* ***/
1476 if (IS_FLG(FLG_STAR_IDENTIFIED))
1477 before_str[before_n++] = "´°Á´¤Ë´ÕÄêºÑ¤ß¤Î";
1479 /*** Dice boosted (weapon of slaying) ***/
1480 if (IS_FLG(FLG_BOOSTED))
1482 before_str[before_n++] = "¥À¥á¡¼¥¸¥À¥¤¥¹¤¬Ä̾ï¤è¤êÂ礤¤";
1486 /*** Weapons whose dd*ds is more than nn ***/
1487 if (IS_FLG(FLG_MORE_THAN))
1489 static char more_than_desc_str[] = "___";
1490 before_str[before_n++] = "¥À¥á¡¼¥¸¥À¥¤¥¹¤ÎºÇÂçÃͤ¬";
1493 sprintf(more_than_desc_str,"%d", entry->dice);
1494 before_str[before_n++] = more_than_desc_str;
1495 before_str[before_n++] = "°Ê¾å¤Î";
1498 /*** Items whose magical bonus is more than nn ***/
1499 if (IS_FLG(FLG_MORE_BONUS))
1501 static char more_bonus_desc_str[] = "___";
1502 before_str[before_n++] = "½¤ÀµÃͤ¬(+";
1504 sprintf(more_bonus_desc_str,"%d", entry->bonus);
1505 before_str[before_n++] = more_bonus_desc_str;
1506 before_str[before_n++] = ")°Ê¾å¤Î";
1509 /*** Worthless items ***/
1510 if (IS_FLG(FLG_WORTHLESS))
1511 before_str[before_n++] = "Ź¤Ç̵²ÁÃͤÈȽÄꤵ¤ì¤ë";
1514 if (IS_FLG(FLG_ARTIFACT))
1516 before_str[before_n++] = "¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È¤Î";
1521 if (IS_FLG(FLG_EGO))
1523 before_str[before_n++] = "¥¨¥´¥¢¥¤¥Æ¥à¤Î";
1528 if (IS_FLG(FLG_NAMELESS))
1530 before_str[before_n++] = "¥¨¥´¤Ç¤â¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È¤Ç¤â¤Ê¤¤";
1534 /*** Unaware items ***/
1535 if (IS_FLG(FLG_UNAWARE))
1536 before_str[before_n++] = "̤´ÕÄê¤Ç¤½¤Î¸ú²Ì¤âȽÌÀ¤·¤Æ¤¤¤Ê¤¤";
1538 /*** Wanted monster's corpse/skeletons ***/
1539 if (IS_FLG(FLG_WANTED))
1541 before_str[before_n++] = "¥Ï¥ó¥¿¡¼»ö̳½ê¤Ç¾Þ¶â¼ó¤È¤µ¤ì¤Æ¤¤¤ë";
1542 body_str = "»àÂΤä¹ü";
1545 /*** Human corpse/skeletons (for Daemon magic) ***/
1546 if (IS_FLG(FLG_HUMAN))
1548 before_str[before_n++] = "°ËâËâË¡¤Ç»È¤¦¤¿¤á¤Î¿Í´Ö¤ä¥Ò¥å¡¼¥Þ¥Î¥¤¥É¤Î";
1549 body_str = "»àÂΤä¹ü";
1552 /*** Unique monster's corpse/skeletons/statues ***/
1553 if (IS_FLG(FLG_UNIQUE))
1555 before_str[before_n++] = "¥æ¥Ë¡¼¥¯¥â¥ó¥¹¥¿¡¼¤Î";
1556 body_str = "»àÂΤä¹ü";
1559 /*** Unreadable spellbooks ***/
1560 if (IS_FLG(FLG_UNREADABLE))
1562 before_str[before_n++] = "¤¢¤Ê¤¿¤¬Æɤá¤Ê¤¤Îΰè¤Î";
1563 body_str = "ËâË¡½ñ";
1566 /*** First realm spellbooks ***/
1567 if (IS_FLG(FLG_REALM1))
1569 before_str[before_n++] = "Âè°ìÎΰè¤Î";
1570 body_str = "ËâË¡½ñ";
1573 /*** Second realm spellbooks ***/
1574 if (IS_FLG(FLG_REALM2))
1576 before_str[before_n++] = "ÂèÆóÎΰè¤Î";
1577 body_str = "ËâË¡½ñ";
1580 /*** First rank spellbooks ***/
1581 if (IS_FLG(FLG_FIRST))
1583 before_str[before_n++] = "Á´4ºý¤ÎÆâ¤Î1ºýÌܤÎ";
1584 body_str = "ËâË¡½ñ";
1587 /*** Second rank spellbooks ***/
1588 if (IS_FLG(FLG_SECOND))
1590 before_str[before_n++] = "Á´4ºý¤ÎÆâ¤Î2ºýÌܤÎ";
1591 body_str = "ËâË¡½ñ";
1594 /*** Third rank spellbooks ***/
1595 if (IS_FLG(FLG_THIRD))
1597 before_str[before_n++] = "Á´4ºý¤ÎÆâ¤Î3ºýÌܤÎ";
1598 body_str = "ËâË¡½ñ";
1601 /*** Fourth rank spellbooks ***/
1602 if (IS_FLG(FLG_FOURTH))
1604 before_str[before_n++] = "Á´4ºý¤ÎÆâ¤Î4ºýÌܤÎ";
1605 body_str = "ËâË¡½ñ";
1609 if (IS_FLG(FLG_ITEMS))
1610 ; /* Nothing to do */
1611 else if (IS_FLG(FLG_WEAPONS))
1613 else if (IS_FLG(FLG_ARMORS))
1615 else if (IS_FLG(FLG_MISSILES))
1616 body_str = "ÃƤäÌð¤ä¥¯¥í¥¹¥Ü¥¦¤ÎÌð";
1617 else if (IS_FLG(FLG_DEVICES))
1618 body_str = "´¬Êª¤äËâË¡ËÀ¤ä¾ó¤ä¥í¥Ã¥É";
1619 else if (IS_FLG(FLG_LIGHTS))
1620 body_str = "¸÷¸»ÍѤΥ¢¥¤¥Æ¥à";
1621 else if (IS_FLG(FLG_JUNKS))
1622 body_str = "Àޤ줿ËÀÅù¤Î¥¬¥é¥¯¥¿";
1623 else if (IS_FLG(FLG_SPELLBOOKS))
1624 body_str = "ËâË¡½ñ";
1625 else if (IS_FLG(FLG_HAFTED))
1627 else if (IS_FLG(FLG_SHIELDS))
1629 else if (IS_FLG(FLG_BOWS))
1630 body_str = "¥¹¥ê¥ó¥°¤äµÝ¤ä¥¯¥í¥¹¥Ü¥¦";
1631 else if (IS_FLG(FLG_RINGS))
1633 else if (IS_FLG(FLG_AMULETS))
1634 body_str = "¥¢¥ß¥å¥ì¥Ã¥È";
1635 else if (IS_FLG(FLG_SUITS))
1637 else if (IS_FLG(FLG_CLOAKS))
1638 body_str = "¥¯¥í¡¼¥¯";
1639 else if (IS_FLG(FLG_HELMS))
1640 body_str = "¥Ø¥ë¥á¥Ã¥È¤ä´§";
1641 else if (IS_FLG(FLG_GLOVES))
1643 else if (IS_FLG(FLG_BOOTS))
1644 body_str = "¥Ö¡¼¥Ä";
1645 else if (IS_FLG(FLG_FAVORITE))
1646 body_str = "ÆÀ°ÕÉð´ï";
1650 strcat(buff, "Á´¤Æ¤Î");
1651 else for (i = 0; i < before_n && before_str[i]; i++)
1652 strcat(buff, before_str[i]);
1654 strcat(buff, body_str);
1664 strcat(buff, "¤Ç¡¢Ì¾Á°¤¬¡Ö");
1665 strncat(buff, str, 80);
1667 strcat(buff, "¡×¤Ç»Ï¤Þ¤ë¤â¤Î");
1669 strcat(buff, "¡×¤ò´Þ¤à¤â¤Î");
1674 strncat(buff, format("¤Ë¡Ö%s¡×", insc), 80);
1676 if (strstr(insc, "%%all"))
1677 strcat(buff, "(%%all¤ÏÁ´Ç½ÎϤòɽ¤¹±Ñ»ú¤Îµ¹æ¤ÇÃÖ´¹)");
1678 else if (strstr(insc, "%all"))
1679 strcat(buff, "(%all¤ÏÁ´Ç½ÎϤòɽ¤¹µ¹æ¤ÇÃÖ´¹)");
1680 else if (strstr(insc, "%%"))
1681 strcat(buff, "(%%¤ÏÄɲÃǽÎϤòɽ¤¹±Ñ»ú¤Îµ¹æ¤ÇÃÖ´¹)");
1682 else if (strstr(insc, "%"))
1683 strcat(buff, "(%¤ÏÄɲÃǽÎϤòɽ¤¹µ¹æ¤ÇÃÖ´¹)");
1685 strcat(buff, "¤È¹ï¤ó¤Ç");
1690 if (act & DONT_AUTOPICK)
1691 strcat(buff, "ÊüÃÖ¤¹¤ë¡£");
1692 else if (act & DO_AUTODESTROY)
1693 strcat(buff, "Ç˲õ¤¹¤ë¡£");
1694 else if (act & DO_QUERY_AUTOPICK)
1695 strcat(buff, "³Îǧ¤Î¸å¤Ë½¦¤¦¡£");
1697 strcat(buff, "½¦¤¦¡£");
1699 if (act & DO_DISPLAY)
1701 if (act & DONT_AUTOPICK)
1702 strcat(buff, "Á´ÂΥޥå×('M')¤Ç'N'¤ò²¡¤·¤¿¤È¤¤Ëɽ¼¨¤¹¤ë¡£");
1703 else if (act & DO_AUTODESTROY)
1704 strcat(buff, "Á´ÂΥޥå×('M')¤Ç'K'¤ò²¡¤·¤¿¤È¤¤Ëɽ¼¨¤¹¤ë¡£");
1706 strcat(buff, "Á´ÂΥޥå×('M')¤Ç'M'¤ò²¡¤·¤¿¤È¤¤Ëɽ¼¨¤¹¤ë¡£");
1709 strcat(buff, "Á´ÂΥޥåפˤÏɽ¼¨¤·¤Ê¤¤");
1713 cptr before_str[20], after_str[20], which_str[20], whose_str[20], body_str;
1714 int before_n = 0, after_n = 0, which_n = 0, whose_n = 0;
1718 /*** Collecting items ***/
1719 /*** Which can be absorbed into a slot as a bundle ***/
1720 if (IS_FLG(FLG_COLLECTING))
1721 which_str[which_n++] = "can be absorbed into an existing inventory slot";
1723 /*** Unidentified ***/
1724 if (IS_FLG(FLG_UNIDENTIFIED))
1725 before_str[before_n++] = "unidentified";
1727 /*** Identified ***/
1728 if (IS_FLG(FLG_IDENTIFIED))
1729 before_str[before_n++] = "identified";
1731 /*** *Identified* ***/
1732 if (IS_FLG(FLG_STAR_IDENTIFIED))
1733 before_str[before_n++] = "fully identified";
1735 /*** Worthless items ***/
1736 if (IS_FLG(FLG_WORTHLESS))
1738 before_str[before_n++] = "worthless";
1739 which_str[which_n++] = "can not be sold at stores";
1743 if (IS_FLG(FLG_ARTIFACT))
1745 before_str[before_n++] = "artifact";
1749 if (IS_FLG(FLG_EGO))
1751 before_str[before_n++] = "ego";
1755 if (IS_FLG(FLG_NAMELESS))
1757 body_str = "equipment";
1758 which_str[which_n++] = "is neither ego-item nor artifact";
1761 /*** Unaware items ***/
1762 if (IS_FLG(FLG_UNAWARE))
1764 before_str[before_n++] = "unidentified";
1765 whose_str[whose_n++] = "basic abilities are not known";
1768 /*** Dice boosted (weapon of slaying) ***/
1769 if (IS_FLG(FLG_BOOSTED))
1771 body_str = "weapons";
1772 whose_str[whose_n++] = "damage dice is bigger than normal";
1775 /*** Weapons whose dd*ds is more than nn ***/
1776 if (IS_FLG(FLG_MORE_THAN))
1778 static char more_than_desc_str[] =
1779 "maximum damage from dice is bigger than __";
1780 body_str = "weapons";
1782 sprintf(more_than_desc_str + sizeof(more_than_desc_str) - 3,
1784 whose_str[whose_n++] = more_than_desc_str;
1787 /*** Items whose magical bonus is more than nn ***/
1788 if (IS_FLG(FLG_MORE_BONUS))
1790 static char more_bonus_desc_str[] =
1791 "magical bonus is bigger than (+__)";
1793 sprintf(more_bonus_desc_str + sizeof(more_bonus_desc_str) - 4,
1794 "%d)", entry->bonus);
1795 whose_str[whose_n++] = more_bonus_desc_str;
1798 /*** Wanted monster's corpse/skeletons ***/
1799 if (IS_FLG(FLG_WANTED))
1801 body_str = "corpse or skeletons";
1802 which_str[which_n++] = "is wanted at the Hunter's Office";
1805 /*** Human corpse/skeletons (for Daemon magic) ***/
1806 if (IS_FLG(FLG_HUMAN))
1808 before_str[before_n++] = "humanoid";
1809 body_str = "corpse or skeletons";
1810 which_str[which_n++] = "can be used for Daemon magic";
1813 /*** Unique monster's corpse/skeletons/statues ***/
1814 if (IS_FLG(FLG_UNIQUE))
1816 before_str[before_n++] = "unique monster's";
1817 body_str = "corpse or skeletons";
1820 /*** Unreadable spellbooks ***/
1821 if (IS_FLG(FLG_UNREADABLE))
1823 body_str = "spellbooks";
1824 after_str[after_n++] = "of different realms from yours";
1827 /*** First realm spellbooks ***/
1828 if (IS_FLG(FLG_REALM1))
1830 body_str = "spellbooks";
1831 after_str[after_n++] = "of your first realm";
1834 /*** Second realm spellbooks ***/
1835 if (IS_FLG(FLG_REALM2))
1837 body_str = "spellbooks";
1838 after_str[after_n++] = "of your second realm";
1841 /*** First rank spellbooks ***/
1842 if (IS_FLG(FLG_FIRST))
1844 before_str[before_n++] = "first one of four";
1845 body_str = "spellbooks";
1848 /*** Second rank spellbooks ***/
1849 if (IS_FLG(FLG_SECOND))
1851 before_str[before_n++] = "second one of four";
1852 body_str = "spellbooks";
1855 /*** Third rank spellbooks ***/
1856 if (IS_FLG(FLG_THIRD))
1858 before_str[before_n++] = "third one of four";
1859 body_str = "spellbooks";
1862 /*** Fourth rank spellbooks ***/
1863 if (IS_FLG(FLG_FOURTH))
1865 before_str[before_n++] = "fourth one of four";
1866 body_str = "spellbooks";
1870 if (IS_FLG(FLG_ITEMS))
1871 ; /* Nothing to do */
1872 else if (IS_FLG(FLG_WEAPONS))
1873 body_str = "weapons";
1874 else if (IS_FLG(FLG_ARMORS))
1875 body_str = "armors";
1876 else if (IS_FLG(FLG_MISSILES))
1877 body_str = "shots, arrows or crossbow bolts";
1878 else if (IS_FLG(FLG_DEVICES))
1879 body_str = "scrolls, wands, staves or rods";
1880 else if (IS_FLG(FLG_LIGHTS))
1881 body_str = "light sources";
1882 else if (IS_FLG(FLG_JUNKS))
1883 body_str = "junk such as broken sticks";
1884 else if (IS_FLG(FLG_SPELLBOOKS))
1885 body_str = "spellbooks";
1886 else if (IS_FLG(FLG_HAFTED))
1887 body_str = "hafted weapons";
1888 else if (IS_FLG(FLG_SHIELDS))
1889 body_str = "shields";
1890 else if (IS_FLG(FLG_BOWS))
1891 body_str = "slings, bows or crossbows";
1892 else if (IS_FLG(FLG_RINGS))
1894 else if (IS_FLG(FLG_AMULETS))
1895 body_str = "amulets";
1896 else if (IS_FLG(FLG_SUITS))
1897 body_str = "body armors";
1898 else if (IS_FLG(FLG_CLOAKS))
1899 body_str = "cloaks";
1900 else if (IS_FLG(FLG_HELMS))
1901 body_str = "helms or crowns";
1902 else if (IS_FLG(FLG_GLOVES))
1903 body_str = "gloves";
1904 else if (IS_FLG(FLG_BOOTS))
1906 else if (IS_FLG(FLG_FAVORITE))
1907 body_str = "favorite weapons";
1909 /* Prepare a string for item name */
1916 whose_str[whose_n++] = "name is beginning with \"";
1919 which_str[which_n++] = "have \"";
1923 /* Describe action flag */
1924 if (act & DONT_AUTOPICK)
1925 strcpy(buff, "Leave on floor ");
1926 else if (act & DO_AUTODESTROY)
1927 strcpy(buff, "Destroy ");
1928 else if (act & DO_QUERY_AUTOPICK)
1929 strcpy(buff, "Ask to pick up ");
1931 strcpy(buff, "Pickup ");
1933 /* Auto-insctiption */
1936 strncat(buff, format("and inscribe \"%s\"", insc), 80);
1938 if (strstr(insc, "%all"))
1939 strcat(buff, ", replacing %all with code string representing all abilities,");
1940 else if (strstr(insc, "%"))
1941 strcat(buff, ", replacing % with code string representing extra random abilities,");
1943 strcat(buff, " on ");
1948 strcat(buff, "all ");
1949 else for (i = 0; i < before_n && before_str[i]; i++)
1951 strcat(buff, before_str[i]);
1956 strcat(buff, body_str);
1959 for (i = 0; i < after_n && after_str[i]; i++)
1962 strcat(buff, after_str[i]);
1966 for (i = 0; i < whose_n && whose_str[i]; i++)
1969 strcat(buff, " whose ");
1971 strcat(buff, ", and ");
1973 strcat(buff, whose_str[i]);
1976 /* Item name ; whose name is beginning with "str" */
1983 /* whose ..., and which .... */
1984 if (whose_n && which_n)
1985 strcat(buff, ", and ");
1988 for (i = 0; i < which_n && which_str[i]; i++)
1991 strcat(buff, " which ");
1993 strcat(buff, ", and ");
1995 strcat(buff, which_str[i]);
1998 /* Item name ; which have "str" as part of its name */
2001 strncat(buff, str, 80);
2002 strcat(buff, "\" as part of its name");
2006 /* Describe whether it will be displayed on the full map or not */
2007 if (act & DO_DISPLAY)
2009 if (act & DONT_AUTOPICK)
2010 strcat(buff, " Display these items when you press the N key in the full 'M'ap.");
2011 else if (act & DO_AUTODESTROY)
2012 strcat(buff, " Display these items when you press the K key in the full 'M'ap.");
2014 strcat(buff, " Display these items when you press the M key in the full 'M'ap.");
2017 strcat(buff, " Not displayed in the full map.");
2023 #define MAX_LINES 3000
2026 * Read whole lines of a file to memory
2028 static cptr *read_text_lines(cptr filename, bool user)
2030 cptr *lines_list = NULL;
2038 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, filename);
2042 path_build(buf, sizeof(buf), ANGBAND_DIR_PREF, filename);
2046 fff = my_fopen(buf, "r");
2050 /* Allocate list of pointers */
2051 C_MAKE(lines_list, MAX_LINES, cptr);
2054 while (0 == my_fgets(fff, buf, sizeof(buf)))
2056 lines_list[lines++] = string_make(buf);
2057 if (lines >= MAX_LINES - 1) break;
2060 lines_list[0] = string_make("");
2065 if (!fff) return NULL;
2070 #define PT_DEFAULT 0
2071 #define PT_WITH_PNAME 1
2073 static cptr *read_pickpref_text_lines(int *filename_mode_p)
2079 sprintf(buf, "picktype-%s.prf", player_name);
2081 sprintf(buf, "pickpref-%s.prf", player_name);
2083 lines_list = read_text_lines(buf, TRUE);
2088 lines_list = read_text_lines("picktype.prf", TRUE);
2090 lines_list = read_text_lines("pickpref.prf", TRUE);
2092 *filename_mode_p = PT_DEFAULT;
2098 lines_list = read_text_lines("picktype.prf", FALSE);
2100 lines_list = read_text_lines("pickpref.prf", FALSE);
2102 *filename_mode_p = PT_WITH_PNAME;
2107 /* Allocate list of pointers */
2108 C_MAKE(lines_list, MAX_LINES, cptr);
2109 lines_list[0] = string_make("");
2110 *filename_mode_p = PT_WITH_PNAME;
2117 * Write whole lines of memory to a file.
2119 static bool write_text_lines(cptr filename, cptr *lines_list)
2126 /* Build the filename */
2127 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, filename);
2130 fff = my_fopen(buf, "w");
2133 for (lines = 0; lines_list[lines]; lines++)
2134 my_fputs(fff, lines_list[lines], 1024);
2139 if (!fff) return FALSE;
2145 * Free memory of lines_list.
2147 static void free_text_lines(cptr *lines_list)
2151 for (lines = 0; lines_list[lines]; lines++)
2152 string_free(lines_list[lines]);
2154 /* free list of pointers */
2155 C_FREE((char **)lines_list, MAX_LINES, char *);
2160 * Delete or insert string
2162 static void toggle_keyword(text_body_type *tb, int flg)
2164 int by1, by2, bx1, bx2, y;
2168 /* Select this line */
2169 if (!tb->mark) tb->my = tb->cy;
2171 if (tb->my < tb->cy)
2186 /* String on these lines are not really selected */
2187 if (tb->lines_list[by1][bx1] == '\0' && by1 < tb->cy) by1++;
2188 if (bx2 == 0 && tb->cy < by2) by2--;
2191 /* Set/Reset flag of each line */
2192 for (y = by1; y <= by2; y++)
2194 autopick_type an_entry, *entry = &an_entry;
2196 if (!autopick_new_entry(entry, tb->lines_list[y]))
2199 string_free(tb->lines_list[y]);
2203 /* Add? or Remove? */
2204 if (!IS_FLG(flg)) add = TRUE;
2207 /* No more change */
2211 /* You can use only one noun flag */
2212 if (FLG_NOUN_BEGIN <= flg && flg <= FLG_NOUN_END)
2215 for (i = FLG_NOUN_BEGIN; i <= FLG_NOUN_END; i++)
2219 /* You can use only one identify state flag */
2220 else if (FLG_UNAWARE <= flg && flg <= FLG_STAR_IDENTIFIED)
2223 for (i = FLG_UNAWARE; i <= FLG_STAR_IDENTIFIED; i++)
2227 /* You can use only one flag in artifact/ego/nameless */
2228 else if (FLG_ARTIFACT <= flg && flg <= FLG_NAMELESS)
2231 for (i = FLG_ARTIFACT; i <= FLG_NAMELESS; i++)
2235 if (add) ADD_FLG(flg);
2238 tb->lines_list[y] = autopick_line_from_entry_kill(entry);
2241 tb->dirty_flags |= DIRTY_ALL;
2247 * Change command letter
2249 static void toggle_command_letter(text_body_type *tb, byte flg)
2251 autopick_type an_entry, *entry = &an_entry;
2252 int by1, by2, bx1, bx2, y;
2256 /* Select this line */
2257 if (!tb->mark) tb->my = tb->cy;
2259 if (tb->my < tb->cy)
2274 /* String on these lines are not really selected */
2275 if (tb->lines_list[by1][bx1] == '\0' && by1 < tb->cy) by1++;
2276 if (bx2 == 0 && tb->cy < by2) by2--;
2279 /* Set/Reset flag of each line */
2280 for (y = by1; y <= by2; y++)
2284 if (!autopick_new_entry(entry, tb->lines_list[y])) continue;
2286 string_free(tb->lines_list[y]);
2290 /* Add? or Remove? */
2291 if (!(entry->action & flg)) add = TRUE;
2294 /* No more change */
2298 /* Count number of letter (by negative number) */
2299 if (entry->action & DONT_AUTOPICK) wid--;
2300 else if (entry->action & DO_AUTODESTROY) wid--;
2301 else if (entry->action & DO_QUERY_AUTOPICK) wid--;
2302 if (!(entry->action & DO_DISPLAY)) wid--;
2304 /* Set/Reset the flag */
2305 if (flg != DO_DISPLAY)
2307 entry->action &= ~(DO_AUTOPICK | DONT_AUTOPICK | DO_AUTODESTROY | DO_QUERY_AUTOPICK);
2308 if (add) entry->action |= flg;
2309 else entry->action |= DO_AUTOPICK;
2313 entry->action &= ~(DO_DISPLAY);
2314 if (add) entry->action |= flg;
2317 /* Correct cursor location */
2320 if (entry->action & DONT_AUTOPICK) wid++;
2321 else if (entry->action & DO_AUTODESTROY) wid++;
2322 else if (entry->action & DO_QUERY_AUTOPICK) wid++;
2323 if (!(entry->action & DO_DISPLAY)) wid++;
2325 if (wid > 0) tb->cx++;
2326 if (wid < 0 && tb->cx > 0) tb->cx--;
2329 tb->lines_list[y] = autopick_line_from_entry_kill(entry);
2332 tb->dirty_flags |= DIRTY_ALL;
2337 * Delete or insert string
2339 static void add_keyword(text_body_type *tb, int flg)
2341 autopick_type an_entry, *entry = &an_entry;
2343 if (!autopick_new_entry(entry, tb->lines_list[tb->cy]))
2346 /* There is the flag already */
2349 /* Free memory for the entry */
2350 autopick_free_entry(entry);
2355 string_free(tb->lines_list[tb->cy]);
2357 /* Remove all noun flag */
2358 if (FLG_NOUN_BEGIN <= flg && flg <= FLG_NOUN_END)
2361 for (i = FLG_NOUN_BEGIN; i <= FLG_NOUN_END; i++)
2367 tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
2370 tb->dirty_line = tb->cy;
2375 * Insert return code and split the line
2377 static bool insert_return_code(cptr *lines_list, int cx, int cy)
2379 char buf[MAX_LINELEN];
2382 for (k = 0; lines_list[k]; k++)
2383 /* count number of lines */ ;
2385 if (k >= MAX_LINES - 2) return FALSE;
2388 /* Move down lines */
2390 lines_list[k+1] = lines_list[k];
2392 /* Split current line */
2393 for (i = j = 0; lines_list[cy][i] && i < cx; i++)
2396 if (iskanji(lines_list[cy][i]))
2397 buf[j++] = lines_list[cy][i++];
2399 buf[j++] = lines_list[cy][i];
2402 lines_list[cy+1] = string_make(&lines_list[cy][i]);
2403 string_free(lines_list[cy]);
2404 lines_list[cy] = string_make(buf);
2410 * Get auto-picker entry from o_ptr.
2412 void autopick_entry_from_object(autopick_type *entry, object_type *o_ptr)
2414 char o_name[MAX_NLEN];
2415 object_desc(o_name, o_ptr, FALSE, 0);
2417 entry->name = string_make(o_name);
2418 entry->insc = string_make(quark_str(o_ptr->inscription));
2419 entry->action = DO_AUTOPICK | DO_DISPLAY;
2420 entry->flag[0] = entry->flag[1] = 0L;
2423 if (!object_aware_p(o_ptr))
2424 ADD_FLG(FLG_UNAWARE);
2425 if (object_value(o_ptr) <= 0)
2426 ADD_FLG(FLG_WORTHLESS);
2428 if (object_known_p(o_ptr))
2432 else if (o_ptr->name1 || o_ptr->art_name)
2433 ADD_FLG(FLG_ARTIFACT);
2439 case TV_HAFTED: case TV_POLEARM: case TV_SWORD: case TV_DIGGING:
2440 k_ptr = &k_info[o_ptr->k_idx];
2441 if ((o_ptr->dd != k_ptr->dd) || (o_ptr->ds != k_ptr->ds))
2442 ADD_FLG(FLG_BOOSTED);
2445 if (o_ptr->tval == TV_CORPSE && object_is_shoukinkubi(o_ptr))
2447 REM_FLG(FLG_WORTHLESS);
2448 ADD_FLG(FLG_WANTED);
2451 if ((o_ptr->tval == TV_CORPSE || o_ptr->tval == TV_STATUE)
2452 && (r_info[o_ptr->pval].flags1 & RF1_UNIQUE))
2454 REM_FLG(FLG_WORTHLESS);
2455 ADD_FLG(FLG_UNIQUE);
2458 if (o_ptr->tval == TV_CORPSE && strchr("pht", r_info[o_ptr->pval].d_char))
2460 REM_FLG(FLG_WORTHLESS);
2464 if (o_ptr->tval >= TV_LIFE_BOOK &&
2465 !check_book_realm(o_ptr->tval, o_ptr->sval))
2466 ADD_FLG(FLG_UNREADABLE);
2468 if (REALM1_BOOK == o_ptr->tval &&
2469 p_ptr->pclass != CLASS_SORCERER &&
2470 p_ptr->pclass != CLASS_RED_MAGE)
2471 ADD_FLG(FLG_REALM1);
2473 if (REALM2_BOOK == o_ptr->tval &&
2474 p_ptr->pclass != CLASS_SORCERER &&
2475 p_ptr->pclass != CLASS_RED_MAGE)
2476 ADD_FLG(FLG_REALM2);
2478 if (o_ptr->tval >= TV_LIFE_BOOK && 0 == o_ptr->sval)
2480 if (o_ptr->tval >= TV_LIFE_BOOK && 1 == o_ptr->sval)
2481 ADD_FLG(FLG_SECOND);
2482 if (o_ptr->tval >= TV_LIFE_BOOK && 2 == o_ptr->sval)
2484 if (o_ptr->tval >= TV_LIFE_BOOK && 3 == o_ptr->sval)
2485 ADD_FLG(FLG_FOURTH);
2487 if (o_ptr->tval == TV_SHOT || o_ptr->tval == TV_BOLT
2488 || o_ptr->tval == TV_ARROW)
2489 ADD_FLG(FLG_MISSILES);
2490 else if (o_ptr->tval == TV_SCROLL || o_ptr->tval == TV_STAFF
2491 || o_ptr->tval == TV_WAND || o_ptr->tval == TV_ROD)
2492 ADD_FLG(FLG_DEVICES);
2493 else if (o_ptr->tval == TV_LITE)
2494 ADD_FLG(FLG_LIGHTS);
2495 else if (o_ptr->tval == TV_SKELETON || o_ptr->tval == TV_BOTTLE
2496 || o_ptr->tval == TV_JUNK || o_ptr->tval == TV_STATUE)
2498 else if (o_ptr->tval >= TV_LIFE_BOOK)
2499 ADD_FLG(FLG_SPELLBOOKS);
2500 else if (is_favorite(o_ptr, FALSE))
2501 ADD_FLG(FLG_FAVORITE);
2502 else if (o_ptr->tval == TV_POLEARM || o_ptr->tval == TV_SWORD
2503 || o_ptr->tval == TV_DIGGING || o_ptr->tval == TV_HAFTED)
2504 ADD_FLG(FLG_WEAPONS);
2505 else if (o_ptr->tval == TV_SHIELD)
2506 ADD_FLG(FLG_SHIELDS);
2507 else if (o_ptr->tval == TV_BOW)
2509 else if (o_ptr->tval == TV_RING)
2511 else if (o_ptr->tval == TV_AMULET)
2512 ADD_FLG(FLG_AMULETS);
2513 else if (o_ptr->tval == TV_DRAG_ARMOR || o_ptr->tval == TV_HARD_ARMOR ||
2514 o_ptr->tval == TV_SOFT_ARMOR)
2516 else if (o_ptr->tval == TV_CLOAK)
2517 ADD_FLG(FLG_CLOAKS);
2518 else if (o_ptr->tval == TV_HELM)
2520 else if (o_ptr->tval == TV_GLOVES)
2521 ADD_FLG(FLG_GLOVES);
2522 else if (o_ptr->tval == TV_BOOTS)
2530 * Choose an item and get auto-picker entry from it.
2532 static object_type *choose_object(cptr q, cptr s)
2536 if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EQUIP))) return NULL;
2538 /* Get the item (in the pack) */
2539 if (item >= 0) return &inventory[item];
2541 /* Get the item (on the floor) */
2542 else return &o_list[0 - item];
2547 * Choose an item and get auto-picker entry from it.
2549 static bool entry_from_choosed_object(autopick_type *entry)
2556 q = "¤É¤Î¥¢¥¤¥Æ¥à¤òÅÐÏ¿¤·¤Þ¤¹¤«? ";
2557 s = "¥¢¥¤¥Æ¥à¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¡£";
2559 q = "Enter which item? ";
2560 s = "You have nothing to enter.";
2562 o_ptr = choose_object(q, s);
2563 if (!o_ptr) return FALSE;
2565 autopick_entry_from_object(entry, o_ptr);
2571 * Choose an item for search
2573 static byte get_object_for_search(object_type **o_handle, cptr *search_strp)
2575 char buf[MAX_NLEN+20];
2581 q = "¤É¤Î¥¢¥¤¥Æ¥à¤ò¸¡º÷¤·¤Þ¤¹¤«? ";
2582 s = "¥¢¥¤¥Æ¥à¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¡£";
2584 q = "Enter which item? ";
2585 s = "You have nothing to enter.";
2587 o_ptr = choose_object(q, s);
2588 if (!o_ptr) return 0;
2592 string_free(*search_strp);
2593 object_desc(buf, *o_handle, FALSE, 3);
2594 *search_strp = string_make(format("<%s>", buf));
2600 * Prepare for search by destroyed object
2602 static byte get_destroyed_object_for_search(object_type **o_handle, cptr *search_strp)
2604 char buf[MAX_NLEN+20];
2606 if (!autopick_last_destroyed_object.k_idx) return 0;
2608 *o_handle = &autopick_last_destroyed_object;
2610 string_free(*search_strp);
2611 object_desc(buf, *o_handle, FALSE, 3);
2612 *search_strp = string_make(format("<%s>", buf));
2618 * Choose an item or string for search
2620 static byte get_string_for_search(object_type **o_handle, cptr *search_strp)
2623 char buf[MAX_NLEN+20];
2626 int k_flag[MAX_NLEN+20];
2627 char prompt[] = "¸¡º÷(^I:»ý¤Áʪ ^L:Ç˲õ¤µ¤ì¤¿Êª): ";
2629 char prompt[] = "Search key(^I:inven ^L:destroyed): ";
2631 int col = sizeof(prompt) - 1;
2633 if (*search_strp) strcpy(buf, *search_strp);
2636 /* Display prompt */
2639 /* Display the default answer */
2640 Term_erase(col, 0, 255);
2641 Term_putstr(col, 0, -1, TERM_YELLOW, buf);
2650 Term_gotoxy(col + pos, 0);
2655 /* HACK -- ignore macro defined on ASCII keys */
2656 if (strlen(inkey_macro_trigger_string) == 1)
2657 i = inkey_macro_trigger_string[0];
2660 /* Analyze the key */
2673 if (!pos && *o_handle) return (back ? -1 : 1);
2674 string_free(*search_strp);
2675 *search_strp = string_make(buf);
2677 return (back ? -1 : 1);
2681 return get_object_for_search(o_handle, search_strp);
2684 /* Prepare string for destroyed object if there is one. */
2685 if (get_destroyed_object_for_search(o_handle, search_strp))
2695 if (k_flag[pos]) pos--;
2710 if (pos + 1 < MAX_NLEN)
2718 else if (pos < MAX_NLEN && isprint(i))
2725 if (pos < MAX_NLEN && isprint(i)) buf[pos++] = i;
2734 /* Update the entry */
2735 Term_erase(col, 0, 255);
2736 Term_putstr(col, 0, -1, TERM_WHITE, buf);
2744 * Search next line matches for o_ptr
2746 static bool search_for_object(cptr *lines_list, object_type *o_ptr, int *cxp, int *cyp, bool forward)
2749 autopick_type an_entry, *entry = &an_entry;
2750 char o_name[MAX_NLEN];
2752 object_desc(o_name, o_ptr, FALSE, 3);
2754 /* Force to be lower case string */
2755 for (i = 0; o_name[i]; i++)
2758 if (iskanji(o_name[i]))
2762 if (isupper(o_name[i]))
2763 o_name[i] = tolower(o_name[i]);
2772 if (!lines_list[++i]) break;
2779 if (!autopick_new_entry(entry, lines_list[i])) continue;
2781 if (is_autopick_aux(o_ptr, entry, o_name))
2794 * Search next line matches to the string
2796 static bool search_for_string(cptr *lines_list, cptr search_str, int *cxp, int *cyp, bool forward)
2806 if (!lines_list[++i]) break;
2813 pos = strstr_j(lines_list[i], search_str);
2815 pos = strstr(lines_list[i], search_str);
2819 *cxp = (int)(pos - lines_list[i]);
2832 * Editor command id's
2845 #define EC_PGDOWN 12
2847 #define EC_BOTTOM 14
2852 #define EC_KILL_LINE 19
2853 #define EC_DELETE_CHAR 20
2854 #define EC_BACKSPACE 21
2855 #define EC_SEARCH_STR 22
2856 #define EC_SEARCH_FORW 23
2857 #define EC_SEARCH_BACK 24
2858 #define EC_SEARCH_OBJ 25
2859 #define EC_SEARCH_DESTROYED 26
2860 #define EC_INSERT_OBJECT 27
2861 #define EC_INSERT_DESTROYED 28
2862 #define EC_INSERT_BLOCK 29
2863 #define EC_INSERT_MACRO 30
2864 #define EC_INSERT_KEYMAP 31
2865 #define EC_CL_AUTOPICK 32
2866 #define EC_CL_DESTROY 33
2867 #define EC_CL_LEAVE 34
2868 #define EC_CL_QUERY 35
2869 #define EC_CL_NO_DISP 36
2870 #define EC_OK_COLLECTING 37
2871 #define EC_IK_UNAWARE 38
2872 #define EC_IK_UNIDENTIFIED 39
2873 #define EC_IK_IDENTIFIED 40
2874 #define EC_IK_STAR_IDENTIFIED 41
2875 #define EC_OK_BOOSTED 42
2876 #define EC_OK_MORE_THAN 43
2877 #define EC_OK_MORE_BONUS 44
2878 #define EC_OK_WORTHLESS 45
2879 #define EC_OK_ARTIFACT 46
2880 #define EC_OK_EGO 47
2881 #define EC_OK_NAMELESS 48
2882 #define EC_OK_WANTED 49
2883 #define EC_OK_UNIQUE 50
2884 #define EC_OK_HUMAN 51
2885 #define EC_OK_UNREADABLE 52
2886 #define EC_OK_REALM1 53
2887 #define EC_OK_REALM2 54
2888 #define EC_OK_FIRST 55
2889 #define EC_OK_SECOND 56
2890 #define EC_OK_THIRD 57
2891 #define EC_OK_FOURTH 58
2892 #define EC_KK_WEAPONS 59
2893 #define EC_KK_FAVORITE 60
2894 #define EC_KK_ARMORS 61
2895 #define EC_KK_MISSILES 62
2896 #define EC_KK_DEVICES 63
2897 #define EC_KK_LIGHTS 64
2898 #define EC_KK_JUNKS 65
2899 #define EC_KK_SPELLBOOKS 66
2900 #define EC_KK_SHIELDS 67
2901 #define EC_KK_BOWS 68
2902 #define EC_KK_RINGS 69
2903 #define EC_KK_AMULETS 70
2904 #define EC_KK_SUITS 71
2905 #define EC_KK_CLOAKS 72
2906 #define EC_KK_HELMS 73
2907 #define EC_KK_GLOVES 74
2908 #define EC_KK_BOOTS 75
2914 #define MN_QUIT "¥»¡¼¥Ö¤·¤Æ½ªÎ»"
2915 #define MN_REVERT "Á´¤Æ¤ÎÊѹ¹¤òÇË´þ"
2916 #define MN_HELP "¥Ø¥ë¥×"
2918 #define MN_MOVE "¥«¡¼¥½¥ë°ÜÆ°"
2919 #define MN_LEFT "º¸"
2920 #define MN_DOWN "²¼"
2922 #define MN_RIGHT "±¦"
2923 #define MN_BOL "¹Ô¤ÎÀèƬ"
2924 #define MN_EOL "¹Ô¤Î½ªÃ¼"
2925 #define MN_PGUP "¾å¤Î¥Ú¡¼¥¸"
2926 #define MN_PGDOWN "²¼¤Î¥Ú¡¼¥¸"
2927 #define MN_TOP "1¹ÔÌܤذÜÆ°"
2928 #define MN_BOTTOM "ºÇ²¼¹Ô¤Ø°ÜÆ°"
2930 #define MN_EDIT "ÊÔ½¸"
2931 #define MN_CUT "ÁªÂòÈϰϤò¥«¥Ã¥È"
2932 #define MN_COPY "ÁªÂòÈϰϤò¥³¥Ô¡¼"
2933 #define MN_PASTE "¥Ú¡¼¥¹¥È"
2934 #define MN_BLOCK "ÁªÂòÈϰϤλØÄê"
2935 #define MN_KILL_LINE "¹Ô¤Î»Ä¤ê¤òºï½ü"
2936 #define MN_DELETE_CHAR "1ʸ»úºï½ü"
2937 #define MN_BACKSPACE "¥Ð¥Ã¥¯¥¹¥Ú¡¼¥¹"
2938 #define MN_RETURN "²þ¹Ô"
2939 #define MN_RETURN "²þ¹Ô"
2941 #define MN_SEARCH "¸¡º÷"
2942 #define MN_SEARCH_STR "ʸ»úÎó¤Ç¸¡º÷"
2943 #define MN_SEARCH_FORW "Á°Êý¤ØºÆ¸¡º÷"
2944 #define MN_SEARCH_BACK "¸åÊý¤ØºÆ¸¡º÷"
2945 #define MN_SEARCH_OBJ "¥¢¥¤¥Æ¥à¤òÁªÂò¤·¤Æ¸¡º÷"
2946 #define MN_SEARCH_DESTROYED "¼«Æ°Ç˲õ¤µ¤ì¤¿¥¢¥¤¥Æ¥à¤Ç¸¡º÷"
2948 #define MN_INSERT "¿§¡¹ÁÞÆþ"
2949 #define MN_INSERT_OBJECT "ÁªÂò¤·¤¿¥¢¥¤¥Æ¥à¤Î̾Á°¤òÁÞÆþ"
2950 #define MN_INSERT_DESTROYED "¼«Æ°Ç˲õ¤µ¤ì¤¿¥¢¥¤¥Æ¥à¤Î̾Á°¤òÁÞÆþ"
2951 #define MN_INSERT_BLOCK "¾ò·ïʬ´ô¥Ö¥í¥Ã¥¯¤ÎÎã¤òÁÞÆþ"
2952 #define MN_INSERT_MACRO "¥Þ¥¯¥íÄêµÁ¤òÁÞÆþ"
2953 #define MN_INSERT_KEYMAP "¥¡¼¥Þ¥Ã¥×ÄêµÁ¤òÁÞÆþ"
2955 #define MN_COMMAND_LETTER "½¦¤¤/Ç˲õ/ÊüÃÖ¤ÎÁªÂò"
2956 #define MN_CL_AUTOPICK "¡Ö ¡× (¼«Æ°½¦¤¤)"
2957 #define MN_CL_DESTROY "¡Ö!¡× (¼«Æ°Ç˲õ)"
2958 #define MN_CL_LEAVE "¡Ö~¡× (ÊüÃÖ)"
2959 #define MN_CL_QUERY "¡Ö;¡× (³Îǧ¤·¤Æ½¦¤¦)"
2960 #define MN_CL_NO_DISP "¡Ö(¡× (¥Þ¥Ã¥×¥³¥Þ¥ó¥É¤Çɽ¼¨¤·¤Ê¤¤)"
2962 #define MN_ADJECTIVE_GEN "·ÁÍÆ»ì(°ìÈÌ)¤ÎÁªÂò"
2964 #define MN_ADJECTIVE_SPECIAL "·ÁÍÆ»ì(Æüì)¤ÎÁªÂò"
2965 #define MN_BOOSTED "¥À¥¤¥¹Ìܤΰ㤦 (Éð´ï)"
2966 #define MN_MORE_THAN "¥À¥¤¥¹ÌÜ # °Ê¾å¤Î (Éð´ï)"
2967 #define MN_MORE_BONUS "½¤ÀµÃÍ # °Ê¾å¤Î (»ØÎØÅù)"
2968 #define MN_ARTIFACT "¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È (ÁõÈ÷)"
2969 #define MN_EGO "¥¨¥´ (ÁõÈ÷)"
2970 #define MN_NAMELESS "̵ÌäΠ(ÁõÈ÷)"
2971 #define MN_WANTED "¾Þ¶â¼ó¤Î (»àÂÎ)"
2972 #define MN_UNIQUE "¥æ¥Ë¡¼¥¯¡¦¥â¥ó¥¹¥¿¡¼¤Î (»àÂÎ)"
2973 #define MN_HUMAN "¿Í´Ö¤Î (»àÂÎ)"
2974 #define MN_UNREADABLE "Æɤá¤Ê¤¤ (ËâË¡½ñ)"
2975 #define MN_REALM1 "Âè°ìÎΰè¤Î (ËâË¡½ñ)"
2976 #define MN_REALM2 "ÂèÆóÎΰè¤Î (ËâË¡½ñ)"
2977 #define MN_FIRST "1ºýÌܤΠ(ËâË¡½ñ)"
2978 #define MN_SECOND "2ºýÌܤΠ(ËâË¡½ñ)"
2979 #define MN_THIRD "3ºýÌܤΠ(ËâË¡½ñ)"
2980 #define MN_FOURTH "4ºýÌܤΠ(ËâË¡½ñ)"
2982 #define MN_NOUN "̾»ì¤ÎÁªÂò"
2986 #define MN_QUIT "Save & Quit"
2987 #define MN_REVERT "Revert all changes"
2988 #define MN_HELP "Help"
2990 #define MN_MOVE "Move cursor"
2991 #define MN_LEFT "Left"
2992 #define MN_DOWN "Down"
2994 #define MN_RIGHT "Right"
2995 #define MN_BOL "Beggining of line"
2996 #define MN_EOL "End of line"
2997 #define MN_PGUP "Page up"
2998 #define MN_PGDOWN "Page down"
2999 #define MN_TOP "Top"
3000 #define MN_BOTTOM "Bottom"
3002 #define MN_EDIT "Edit"
3003 #define MN_CUT "Cut"
3004 #define MN_COPY "Copy"
3005 #define MN_PASTE "Paste"
3006 #define MN_BLOCK "Select block"
3007 #define MN_KILL_LINE "Kill rest of line"
3008 #define MN_DELETE_CHAR "Delete character"
3009 #define MN_BACKSPACE "Backspace"
3010 #define MN_RETURN "Return"
3011 #define MN_RETURN "Return"
3013 #define MN_SEARCH "Search"
3014 #define MN_SEARCH_STR "Search by string"
3015 #define MN_SEARCH_FORW "Search forward"
3016 #define MN_SEARCH_BACK "Search backward"
3017 #define MN_SEARCH_OBJ "Search by inventory object"
3018 #define MN_SEARCH_DESTROYED "Search by destroyed object"
3020 #define MN_INSERT "Insert..."
3021 #define MN_INSERT_OBJECT "Insert name of choosen object"
3022 #define MN_INSERT_DESTROYED "Insert name of destroyed object"
3023 #define MN_INSERT_BLOCK "Insert conditional block"
3024 #define MN_INSERT_MACRO "Insert a macro definition"
3025 #define MN_INSERT_KEYMAP "Insert a keymap definition"
3027 #define MN_COMMAND_LETTER "Command letter"
3028 #define MN_CL_AUTOPICK "' ' (Auto pick)"
3029 #define MN_CL_DESTROY "'!' (Auto destroy)"
3030 #define MN_CL_LEAVE "'~' (Leave it on the floor)"
3031 #define MN_CL_QUERY "';' (Query to pick up)"
3032 #define MN_CL_NO_DISP "'(' (No display on the large map)"
3034 #define MN_ADJECTIVE_GEN "Adjective (general)"
3036 #define MN_ADJECTIVE_SPECIAL "Adjective (special)"
3037 #define MN_BOOSTED "dice boosted (weapons)"
3038 #define MN_MORE_THAN "more than # dice (weapons)"
3039 #define MN_MORE_BONUS "more bonus than # (rings etc.)"
3040 #define MN_ARTIFACT "artifact (equipments)"
3041 #define MN_EGO "ego (equipments)"
3042 #define MN_NAMELESS "nameless (equipments)"
3043 #define MN_WANTED "wanted (corpse)"
3044 #define MN_UNIQUE "unique (corpse)"
3045 #define MN_HUMAN "human (corpse)"
3046 #define MN_UNREADABLE "unreadable (spellbooks)"
3047 #define MN_REALM1 "realm1 (spellbooks)"
3048 #define MN_REALM2 "realm2 (spellbooks)"
3049 #define MN_FIRST "first (spellbooks)"
3050 #define MN_SECOND "second (spellbooks)"
3051 #define MN_THIRD "third (spellbooks)"
3052 #define MN_FOURTH "fourth (spellbooks)"
3054 #define MN_NOUN "Keywords (noun)"
3064 } command_menu_type;
3067 command_menu_type menu_data[] =
3069 {MN_QUIT, 0, KTRL('q'), EC_QUIT},
3070 {MN_REVERT, 0, KTRL('z'), EC_REVERT},
3071 {MN_HELP, 0, -1, EC_HELP},
3073 {MN_MOVE, 0, -1, -1},
3074 {MN_LEFT, 1, KTRL('b'), EC_LEFT},
3075 {MN_DOWN, 1, KTRL('n'), EC_DOWN},
3076 {MN_UP, 1, KTRL('p'), EC_UP},
3077 {MN_RIGHT, 1, KTRL('f'), EC_RIGHT},
3078 {MN_BOL, 1, KTRL('a'), EC_BOL},
3079 {MN_EOL, 1, KTRL('e'), EC_EOL},
3080 {MN_PGUP, 1, KTRL('o'), EC_PGUP},
3081 {MN_PGDOWN, 1, KTRL('l'), EC_PGDOWN},
3082 {MN_TOP, 1, KTRL('y'), EC_TOP},
3083 {MN_BOTTOM, 1, KTRL('u'), EC_BOTTOM},
3085 {MN_EDIT, 0, -1, -1},
3086 {MN_CUT, 1, KTRL('x'), EC_CUT},
3087 {MN_COPY, 1, KTRL('c'), EC_COPY},
3088 {MN_PASTE, 1, KTRL('v'), EC_PASTE},
3089 {MN_BLOCK, 1, KTRL('g'), EC_BLOCK},
3090 {MN_KILL_LINE, 1, KTRL('k'), EC_KILL_LINE},
3091 {MN_DELETE_CHAR, 1, KTRL('d'), EC_DELETE_CHAR},
3092 {MN_BACKSPACE, 1, KTRL('h'), EC_BACKSPACE},
3093 {MN_RETURN, 1, KTRL('j'), EC_RETURN},
3094 {MN_RETURN, 1, KTRL('m'), EC_RETURN},
3096 {MN_SEARCH, 0, -1, -1},
3097 {MN_SEARCH_STR, 1, KTRL('s'), EC_SEARCH_STR},
3098 {MN_SEARCH_FORW, 1, -1, EC_SEARCH_FORW},
3099 {MN_SEARCH_BACK, 1, KTRL('r'), EC_SEARCH_BACK},
3100 {MN_SEARCH_OBJ, 1, -1, EC_SEARCH_OBJ},
3101 {MN_SEARCH_DESTROYED, 1, -1, EC_SEARCH_DESTROYED},
3103 {MN_INSERT, 0, -1, -1},
3104 {MN_INSERT_OBJECT, 1, KTRL('i'), EC_INSERT_OBJECT},
3105 {MN_INSERT_DESTROYED, 1, -1, EC_INSERT_DESTROYED},
3106 {MN_INSERT_BLOCK, 1, -1, EC_INSERT_BLOCK},
3107 {MN_INSERT_MACRO, 1, -1, EC_INSERT_MACRO},
3108 {MN_INSERT_KEYMAP, 1, -1, EC_INSERT_KEYMAP},
3110 {MN_COMMAND_LETTER, 0, -1, -1},
3111 {MN_CL_AUTOPICK, 1, -1, EC_CL_AUTOPICK},
3112 {MN_CL_DESTROY, 1, -1, EC_CL_DESTROY},
3113 {MN_CL_LEAVE, 1, -1, EC_CL_LEAVE},
3114 {MN_CL_QUERY, 1, -1, EC_CL_QUERY},
3115 {MN_CL_NO_DISP, 1, -1, EC_CL_NO_DISP},
3117 {MN_ADJECTIVE_GEN, 0, -1, -1},
3118 {KEY_UNAWARE, 1, -1, EC_IK_UNAWARE},
3119 {KEY_UNIDENTIFIED, 1, -1, EC_IK_UNIDENTIFIED},
3120 {KEY_IDENTIFIED, 1, -1, EC_IK_IDENTIFIED},
3121 {KEY_STAR_IDENTIFIED, 1, -1, EC_IK_STAR_IDENTIFIED},
3122 {KEY_COLLECTING, 1, -1, EC_OK_COLLECTING},
3123 {KEY_WORTHLESS, 1, -1, EC_OK_WORTHLESS},
3125 {MN_ADJECTIVE_SPECIAL, 0, -1, -1},
3126 {MN_BOOSTED, 1, -1, EC_OK_BOOSTED},
3127 {MN_MORE_THAN, 1, -1, EC_OK_MORE_THAN},
3128 {MN_MORE_BONUS, 1, -1, EC_OK_MORE_BONUS},
3129 {MN_ARTIFACT, 1, -1, EC_OK_ARTIFACT},
3130 {MN_EGO, 1, -1, EC_OK_EGO},
3131 {MN_NAMELESS, 1, -1, EC_OK_NAMELESS},
3132 {MN_WANTED, 1, -1, EC_OK_WANTED},
3133 {MN_UNIQUE, 1, -1, EC_OK_UNIQUE},
3134 {MN_HUMAN, 1, -1, EC_OK_HUMAN},
3135 {MN_UNREADABLE, 1, -1, EC_OK_UNREADABLE},
3136 {MN_REALM1, 1, -1, EC_OK_REALM1},
3137 {MN_REALM2, 1, -1, EC_OK_REALM2},
3138 {MN_FIRST, 1, -1, EC_OK_FIRST},
3139 {MN_SECOND, 1, -1, EC_OK_SECOND},
3140 {MN_THIRD, 1, -1, EC_OK_THIRD},
3141 {MN_FOURTH, 1, -1, EC_OK_FOURTH},
3143 {MN_NOUN, 0, -1, -1},
3144 {KEY_WEAPONS, 1, -1, EC_KK_WEAPONS},
3145 {KEY_FAVORITE, 1, -1, EC_KK_FAVORITE},
3146 {KEY_ARMORS, 1, -1, EC_KK_ARMORS},
3147 {KEY_MISSILES, 1, -1, EC_KK_MISSILES},
3148 {KEY_DEVICES, 1, -1, EC_KK_DEVICES},
3149 {KEY_LIGHTS, 1, -1, EC_KK_LIGHTS},
3150 {KEY_JUNKS, 1, -1, EC_KK_JUNKS},
3151 {KEY_SPELLBOOKS, 1, -1, EC_KK_SPELLBOOKS},
3152 {KEY_SHIELDS, 1, -1, EC_KK_SHIELDS},
3153 {KEY_BOWS, 1, -1, EC_KK_BOWS},
3154 {KEY_RINGS, 1, -1, EC_KK_RINGS},
3155 {KEY_AMULETS, 1, -1, EC_KK_AMULETS},
3156 {KEY_SUITS, 1, -1, EC_KK_SUITS},
3157 {KEY_CLOAKS, 1, -1, EC_KK_CLOAKS},
3158 {KEY_HELMS, 1, -1, EC_KK_HELMS},
3159 {KEY_GLOVES, 1, -1, EC_KK_GLOVES},
3160 {KEY_BOOTS, 1, -1, EC_KK_BOOTS},
3167 * Find a command by 'key'.
3169 static int get_com_id(char key)
3173 for (i = 0; menu_data[i].name; i++)
3175 if (menu_data[i].key == key)
3177 return menu_data[i].com_id;
3186 * Display the menu, and get a command
3188 static int do_command_menu(int level, int start)
3193 int col0 = 5 + level*7;
3194 int row0 = 1 + level*3;
3196 int menu_id_list[26];
3198 char linestr[MAX_LINELEN];
3200 /* Get max length */
3202 for (i = start; menu_data[i].level >= level; i++)
3206 /* Ignore lower level sub menus */
3207 if (menu_data[i].level > level) continue;
3209 len = strlen(menu_data[i].name);
3210 if (len > max_len) max_len = len;
3212 menu_id_list[menu_key] = i;
3216 while (menu_key < 26)
3218 menu_id_list[menu_key] = -1;
3222 /* Extra space for displaying menu key and command key */
3223 max_menu_wid = max_len + 3 + 3;
3225 /* Prepare box line */
3227 strcat(linestr, "+");
3228 for (i = 0; i < max_menu_wid + 2; i++)
3230 strcat(linestr, "-");
3232 strcat(linestr, "+");
3242 int row1 = row0 + 1;
3245 Term_putstr(col0, row0, -1, TERM_WHITE, linestr);
3247 /* Draw menu items */
3249 for (i = start; menu_data[i].level >= level; i++)
3251 char com_key_str[3];
3254 /* Ignore lower level sub menus */
3255 if (menu_data[i].level > level) continue;
3257 if (menu_data[i].com_id == -1)
3260 strcpy(com_key_str, "¢§");
3262 strcpy(com_key_str, ">");
3265 else if (menu_data[i].key != -1)
3267 com_key_str[0] = '^';
3268 com_key_str[1] = menu_data[i].key + '@';
3269 com_key_str[2] = '\0';
3273 com_key_str[0] = '\0';
3276 str = format("| %c) %-*s %2s | ", menu_key + 'a', max_len, menu_data[i].name, com_key_str);
3278 Term_putstr(col0, row1++, -1, TERM_WHITE, str);
3283 /* Draw bottom line */
3284 Term_putstr(col0, row1, -1, TERM_WHITE, linestr);
3286 /* The menu was shown */
3290 prt(format("(a-%c) ¥³¥Þ¥ó¥É:", menu_key + 'a' - 1), 0, 0);
3292 prt(format("(a-%c) Command:", menu_key + 'a' - 1), 0, 0);
3296 if (key == ESCAPE) return 0;
3298 if ('a' <= key && key <= 'z')
3300 menu_id = menu_id_list[key - 'a'];
3304 com_id = menu_data[menu_id].com_id;
3308 com_id = do_command_menu(level + 1, menu_id + 1);
3310 if (com_id) return com_id;
3322 com_id = get_com_id(key);
3323 if (com_id) return com_id;
3330 static chain_str_type *new_chain_str(cptr str)
3332 chain_str_type *chain;
3334 size_t len = strlen(str);
3336 chain = (chain_str_type *)ralloc(sizeof(chain_str_type) + len * sizeof(char));
3338 strcpy(chain->s, str);
3345 static void kill_yank_chain(text_body_type *tb)
3347 chain_str_type *chain = tb->yank;
3352 chain_str_type *next = chain->next;
3353 size_t len = strlen(chain->s);
3355 rnfree(chain, sizeof(chain_str_type) + len * sizeof(char));
3362 static void add_str_to_yank(text_body_type *tb, cptr str)
3364 chain_str_type *chain;
3366 tb->yank_eol = FALSE;
3368 if (NULL == tb->yank)
3370 tb->yank = new_chain_str(str);
3380 chain->next = new_chain_str(str);
3385 chain = chain->next;
3390 #define DESCRIPT_HGT 3
3395 static void draw_text_editor(text_body_type *tb)
3398 int by1 = -1, bx1 = -1, by2 = -1, bx2 = -1;
3401 Term_get_size(&tb->wid, &tb->hgt);
3404 * Top line (-1), description line (-3), separator (-1)
3407 tb->hgt -= 2 + DESCRIPT_HGT;
3410 /* Don't let cursor at second byte of kanji */
3411 for (i = 0; tb->lines_list[tb->cy][i]; i++)
3412 if (iskanji(tb->lines_list[tb->cy][i]))
3423 /* Scroll if necessary */
3424 if (tb->cy < tb->upper || tb->upper + tb->hgt <= tb->cy)
3425 tb->upper = tb->cy - (tb->hgt)/2;
3428 if ((tb->cx < tb->left + 10 && tb->left > 0) || tb->left + tb->wid - 5 <= tb->cx)
3429 tb->left = tb->cx - (tb->wid)*2/3;
3433 /* Redraw whole window after resize */
3434 if (tb->old_wid != tb->wid || tb->old_hgt != tb->hgt)
3435 tb->dirty_flags |= DIRTY_SCREEN;
3437 /* Redraw all text after scroll */
3438 else if (tb->old_upper != tb->upper || tb->old_left != tb->left)
3439 tb->dirty_flags |= DIRTY_ALL;
3442 if (tb->dirty_flags & DIRTY_SCREEN)
3444 tb->dirty_flags |= (DIRTY_ALL | DIRTY_MODE);
3450 /* Redraw mode line */
3451 if (tb->dirty_flags & DIRTY_MODE)
3453 char buf[MAX_LINELEN];
3455 int sepa_length = tb->wid;
3458 for (i = 0; i < sepa_length; i++)
3462 Term_putstr(0, tb->hgt + 1, sepa_length, TERM_WHITE, buf);
3467 /* Correct cursor location */
3468 int tmp_cx = MIN(tb->cx, (int)strlen(tb->lines_list[tb->cy]));
3470 tb->dirty_flags |= DIRTY_ALL;
3472 if (tb->my < tb->cy ||
3473 (tb->my == tb->cy && tb->mx < tmp_cx))
3489 /* Dump up to tb->hgt lines of messages */
3490 for (i = 0; i < tb->hgt; i++)
3495 int y = tb->upper+i;
3497 /* clean or dirty? */
3498 if (!(tb->dirty_flags & DIRTY_ALL) && (tb->dirty_line != y))
3501 msg = tb->lines_list[y];
3504 /* Apply horizontal scroll */
3505 for (j = 0; *msg; msg++, j++)
3507 if (j == tb->left) break;
3523 Term_erase(0, i + 1, tb->wid);
3527 /* Dump the messages, bottom to top */
3528 Term_putstr(leftcol, i + 1, tb->wid - 1, TERM_WHITE, msg);
3533 int x0 = leftcol + tb->left;
3538 if (by1 <= y && y < by2) sx1 = strlen(msg);
3539 if (y == by1) sx0 = bx1;
3540 if (y == by2) sx1 = bx2;
3542 Term_gotoxy(leftcol, i + 1);
3543 if (x0 < sx0) Term_addstr(sx0 - x0, TERM_WHITE, msg);
3544 if (x0 < sx1) Term_addstr(sx1 - sx0, TERM_YELLOW, msg + (sx0 - x0));
3545 Term_addstr(-1, TERM_WHITE, msg + (sx1 - x0));
3549 for (; i < tb->hgt; i++)
3552 Term_erase(0, i + 1, tb->wid);
3555 /* Display information when updated */
3556 if (tb->old_cy != tb->cy || (tb->dirty_flags & (DIRTY_ALL | DIRTY_NOT_FOUND | DIRTY_NO_SEARCH)) || tb->dirty_line == tb->cy)
3558 autopick_type an_entry, *entry = &an_entry;
3560 /* Clear information line */
3561 for (i = 0; i < DESCRIPT_HGT; i++)
3564 Term_erase(0, tb->hgt + 2 + i, tb->wid);
3567 /* Display information */
3568 if (tb->dirty_flags & DIRTY_NOT_FOUND)
3571 prt(format("¥Ñ¥¿¡¼¥ó¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s", tb->search_str), tb->hgt + 1 + 1, 0);
3573 prt(format("Pattern not found: %s", tb->search_str), tb->hgt + 1 + 1, 0);
3576 else if (tb->dirty_flags & DIRTY_NO_SEARCH)
3579 prt("¸¡º÷Ãæ¤Î¥Ñ¥¿¡¼¥ó¤¬¤¢¤ê¤Þ¤»¤ó('/'¤Ç¸¡º÷)¡£", tb->hgt + 1 + 1, 0);
3581 prt("No pattern to search. (Press '/' to search.)", tb->hgt +1 + 1, 0);
3584 else if (tb->lines_list[tb->cy][0] == '#')
3587 prt("¤³¤Î¹Ô¤Ï¥³¥á¥ó¥È¤Ç¤¹¡£", tb->hgt +1 + 1, 0);
3589 prt("This line is a comment.", tb->hgt +1 + 1, 0);
3592 else if (tb->lines_list[tb->cy][1] == ':')
3594 switch(tb->lines_list[tb->cy][0])
3598 prt("¤³¤Î¹Ô¤Ï¾ò·ïʬ´ô¼°¤Ç¤¹¡£", tb->hgt +1 + 1, 0);
3600 prt("This line is a Conditional Expression.", tb->hgt +1 + 1, 0);
3605 prt("¤³¤Î¹Ô¤Ï¥Þ¥¯¥í¤Î¼Â¹ÔÆâÍƤòÄêµÁ¤·¤Þ¤¹¡£", tb->hgt +1 + 1, 0);
3607 prt("This line defines a Macro action.", tb->hgt +1 + 1, 0);
3612 prt("¤³¤Î¹Ô¤Ï¥Þ¥¯¥í¤Î¥È¥ê¥¬¡¼¡¦¥¡¼¤òÄêµÁ¤·¤Þ¤¹¡£", tb->hgt +1 + 1, 0);
3614 prt("This line defines a Macro trigger key.", tb->hgt +1 + 1, 0);
3619 prt("¤³¤Î¹Ô¤Ï¥¡¼ÇÛÃÖ¤òÄêµÁ¤·¤Þ¤¹¡£", tb->hgt +1 + 1, 0);
3621 prt("This line defines a Keymap.", tb->hgt +1 + 1, 0);
3627 /* Get description of an autopicker preference line */
3628 else if (autopick_new_entry(entry, tb->lines_list[tb->cy]))
3630 char buf[MAX_LINELEN];
3631 char temp[MAX_LINELEN];
3634 describe_autopick(buf, entry);
3636 roff_to_buf(buf, 81, temp, sizeof(temp));
3638 for (i = 0; i < 3; i++)
3644 prt(t, tb->hgt +1 + 1 + i, 0);
3648 autopick_free_entry(entry);
3655 * Kill segment of a line
3657 static void kill_line_segment(text_body_type *tb, int y, int x0, int x1)
3659 char buf[MAX_LINELEN];
3660 cptr s = tb->lines_list[y];
3665 if (x0 == x1) return;
3667 /* Kill whole line? */
3668 if (x0 == 0 && s[x1] == '\0')
3672 string_free(tb->lines_list[y]);
3674 /* Shift lines up */
3675 for (i = y; tb->lines_list[i+1]; i++)
3676 tb->lines_list[i] = tb->lines_list[i+1];
3677 tb->lines_list[i] = NULL;
3682 /* Before the segment */
3683 for (x = 0; x < x0; x++)
3686 /* After the segment */
3687 for (x = x1; s[x]; x++)
3693 string_free(tb->lines_list[y]);
3694 tb->lines_list[y] = string_make(buf);
3699 * Kill text in the block selection
3701 static bool kill_text_in_selection(text_body_type *tb)
3703 int by1, bx1, by2, bx2;
3706 /* Correct cursor location */
3707 if ((uint)tb->cx > strlen(tb->lines_list[tb->cy]))
3708 tb->cx = (int)strlen(tb->lines_list[tb->cy]);
3710 if (tb->my < tb->cy ||
3711 (tb->my == tb->cy && tb->mx < tb->cx))
3726 /* Kill lines in reverse order */
3727 for (y = by2; y >= by1; y--)
3730 int x1 = strlen(tb->lines_list[y]);
3732 if (y == by1) x0 = bx1;
3733 if (y == by2) x1 = bx2;
3735 kill_line_segment(tb, y, x0, x1);
3738 /* Correct cursor position */
3742 /* Disable selection */
3746 tb->dirty_flags |= DIRTY_ALL;
3753 * Get a trigger key and insert ASCII string for the trigger
3755 static bool insert_macro_line(cptr *lines_list, int cy)
3764 /* Do not process macros */
3770 /* Read the pattern */
3776 /* Do not process macros */
3779 /* Do not wait for keys */
3782 /* Attempt to read a key */
3792 /* Convert the trigger */
3793 ascii_to_text(tmp, buf);
3796 if(!tmp[0]) return FALSE;
3798 /* Insert preference string */
3799 insert_return_code(lines_list, 0, cy);
3800 string_free(lines_list[cy]);
3801 lines_list[cy] = string_make(format("P:%s", tmp));
3803 /* Acquire action */
3804 i = macro_find_exact(buf);
3808 /* Nothing defined */
3813 /* Analyze the current action */
3814 ascii_to_text(tmp, macro__act[i]);
3817 /* Insert blank action preference line */
3818 insert_return_code(lines_list, 0, cy);
3819 string_free(lines_list[cy]);
3820 lines_list[cy] = string_make(format("A:%s", tmp));
3827 * Get a command key and insert ASCII string for the key
3829 static bool insert_keymap_line(cptr *lines_list, int cy)
3837 if (rogue_like_commands)
3839 mode = KEYMAP_MODE_ROGUE;
3845 mode = KEYMAP_MODE_ORIG;
3858 /* Convert the trigger */
3859 ascii_to_text(tmp, buf);
3862 if(!tmp[0]) return FALSE;
3864 /* Insert preference string */
3865 insert_return_code(lines_list, 0, cy);
3866 string_free(lines_list[cy]);
3867 lines_list[cy] = string_make(format("C:%d:%s", mode, tmp));
3869 /* Look up the keymap */
3870 act = keymap_act[mode][(byte)(buf[0])];
3872 /* Insert blank action preference line */
3873 insert_return_code(lines_list, 0, cy);
3874 string_free(lines_list[cy]);
3875 lines_list[cy] = string_make(format("A:%s", act));
3882 * Execute a single editor command
3884 static bool do_editor_command(text_body_type *tb, int com_id)
3892 /* Revert to original */
3894 if (!get_check("Á´¤Æ¤ÎÊѹ¹¤òÇË´þ¤·¤Æ¸µ¤Î¾õÂÖ¤ËÌᤷ¤Þ¤¹¡£¤è¤í¤·¤¤¤Ç¤¹¤«¡© ")) break;
3896 if (!get_check("Discard all changes and revert to original file. Are you sure? ")) break;
3899 free_text_lines(tb->lines_list);
3900 tb->lines_list = read_pickpref_text_lines(&tb->filename_mode);
3901 tb->dirty_flags |= DIRTY_ALL | DIRTY_MODE;
3902 tb->cx = tb->cy = 0;
3907 /* Peruse the main help file */
3909 (void)show_file(TRUE, "jeditor.txt", NULL, 0, 0);
3911 (void)show_file(TRUE, "editor.txt", NULL, 0, 0);
3914 tb->dirty_flags |= DIRTY_SCREEN;
3919 /* Split a line or insert end of line */
3922 * If there is a selection, kill it, and replace it
3925 if (tb->mark) kill_text_in_selection(tb);
3927 insert_return_code(tb->lines_list, tb->cx, tb->cy);
3932 tb->dirty_flags |= DIRTY_ALL;
3942 len = strlen(tb->lines_list[tb->cy]);
3943 if (len < tb->cx) tb->cx = len;
3945 else if (tb->cy > 0)
3948 tb->cx = strlen(tb->lines_list[tb->cy]);
3954 if (tb->lines_list[tb->cy + 1]) tb->cy++;
3959 if (tb->cy > 0) tb->cy--;
3968 if (iskanji(tb->lines_list[tb->cy][tb->cx])) tb->cx++;
3971 len = strlen(tb->lines_list[tb->cy]);
3974 if (tb->lines_list[tb->cy + 1])
3986 /* Beginning of line */
3992 tb->cx = strlen(tb->lines_list[tb->cy]);
3996 while (0 < tb->cy && tb->upper <= tb->cy)
3998 while (0 < tb->upper && tb->cy + 1 < tb->upper + tb->hgt)
4004 while (tb->cy < tb->upper + tb->hgt && tb->lines_list[tb->cy + 1])
4014 while (tb->lines_list[tb->cy + 1])
4020 /* Copy the text first */
4021 do_editor_command(tb, EC_COPY);
4024 kill_text_in_selection(tb);
4031 int by1, bx1, by2, bx2;
4034 /* Use single line? */
4039 if (!tb->lines_list[tb->cy])
4041 /* Select bottom line */
4042 tb->cx = strlen(tb->lines_list[tb->cy]);
4046 /* Select a single line */
4052 /* Correct cursor location */
4053 if ((uint)tb->cx > strlen(tb->lines_list[tb->cy]))
4054 tb->cx = (int)strlen(tb->lines_list[tb->cy]);
4056 if (tb->my < tb->cy ||
4057 (tb->my == tb->cy && tb->mx < tb->cx))
4072 /* Kill old yank buffer */
4073 kill_yank_chain(tb);
4075 /* Copy string to yank buffer */
4076 for (y = by1; y <= by2; y++)
4079 char buf[MAX_LINELEN];
4082 int x1 = strlen(tb->lines_list[y]);
4084 if (y == by1) x0 = bx1;
4085 if (y == by2) x1 = bx2;
4087 for (i = 0; i < x1 - x0; i++)
4089 buf[i] = tb->lines_list[y][x0 + i];
4093 add_str_to_yank(tb, buf);
4096 /* Disable selection */
4100 tb->dirty_flags |= DIRTY_ALL;
4106 /* Paste killed text */
4108 chain_str_type *chain = tb->yank;
4110 /* Nothing to do? */
4113 /* Correct cursor location */
4114 if ((uint)tb->cx > strlen(tb->lines_list[tb->cy]))
4115 tb->cx = (int)strlen(tb->lines_list[tb->cy]);
4118 * If there is a selection, kill text, and
4119 * replace it with the yank text.
4121 if (tb->mark) kill_text_in_selection(tb);
4126 cptr yank_str = chain->s;
4128 char buf[MAX_LINELEN];
4130 char rest[MAX_LINELEN], *rest_ptr = rest;
4132 /* Save preceding string */
4133 for(i = 0; i < tb->cx; i++)
4134 buf[i] = tb->lines_list[tb->cy][i];
4136 strcpy(rest, &(tb->lines_list[tb->cy][i]));
4138 /* Paste yank buffer */
4139 while (*yank_str && i < MAX_LINELEN-1)
4141 buf[i++] = *yank_str++;
4147 chain = chain->next;
4149 if (chain || tb->yank_eol)
4151 /* There is an end of line between chain nodes */
4153 insert_return_code(tb->lines_list, tb->cx, tb->cy);
4155 /* Replace this line with new one */
4156 string_free(tb->lines_list[tb->cy]);
4157 tb->lines_list[tb->cy] = string_make(buf);
4159 /* Move to next line */
4166 /* Final line doesn't have end of line */
4168 tb->cx = strlen(buf);
4170 /* Rest of original line */
4171 while (*rest_ptr && i < MAX_LINELEN-1)
4173 buf[i++] = *rest_ptr++;
4179 /* Replace this line with new one */
4180 string_free(tb->lines_list[tb->cy]);
4181 tb->lines_list[tb->cy] = string_make(buf);
4188 tb->dirty_flags |= DIRTY_ALL;
4195 /* Disable the selection */
4199 tb->dirty_flags |= DIRTY_ALL;
4203 tb->mark = MARK_MARK;
4205 /* Repeating this command swaps cursor position */
4206 if (com_id == tb->old_com_id)
4218 tb->dirty_flags |= DIRTY_ALL;
4222 /* Mark the point 1 */
4231 /* Kill rest of line */
4234 char buf[MAX_LINELEN];
4237 /* If there is a selection, kill it */
4240 if (kill_text_in_selection(tb)) break;
4243 /* Correct cursor location */
4244 if ((uint)tb->cx > strlen(tb->lines_list[tb->cy]))
4245 tb->cx = (int)strlen(tb->lines_list[tb->cy]);
4247 /* Save preceding string */
4248 for (i = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
4251 if (iskanji(tb->lines_list[tb->cy][i]))
4253 buf[i] = tb->lines_list[tb->cy][i];
4257 buf[i] = tb->lines_list[tb->cy][i];
4260 line = string_make(buf);
4262 /* Append only if this command is repeated. */
4263 if (tb->old_com_id != com_id)
4265 kill_yank_chain(tb);
4269 /* Really deleted some text */
4270 if (strlen(tb->lines_list[tb->cy] + i))
4272 /* Add deleted string to yank buffer */
4273 add_str_to_yank(tb, tb->lines_list[tb->cy] + i);
4275 /* Replace current line with 'preceding string' */
4276 string_free(tb->lines_list[tb->cy]);
4277 tb->lines_list[tb->cy] = line;
4280 tb->dirty_line = tb->cy;
4282 /* Leave end of line character */
4286 /* Delete the end of line character only */
4287 if (tb->yank_eol) add_str_to_yank(tb, "");
4288 else tb->yank_eol = TRUE;
4290 do_editor_command(tb, EC_DELETE_CHAR);
4294 case EC_DELETE_CHAR:
4295 /* DELETE == go forward + BACK SPACE */
4297 /* If there is a selection, kill it */
4300 if (kill_text_in_selection(tb)) break;
4304 if (iskanji(tb->lines_list[tb->cy][tb->cx])) tb->cx++;
4308 do_editor_command(tb, EC_BACKSPACE);
4316 char buf[MAX_LINELEN];
4318 /* If there is a selection, kill it */
4321 if (kill_text_in_selection(tb)) break;
4324 len = strlen(tb->lines_list[tb->cy]);
4327 if (tb->lines_list[tb->cy + 1])
4341 /* delete a return code and union two lines */
4342 if (tb->cy == 0) break;
4343 tb->cx = strlen(tb->lines_list[tb->cy-1]);
4344 strcpy(buf, tb->lines_list[tb->cy-1]);
4345 strcat(buf, tb->lines_list[tb->cy]);
4346 string_free(tb->lines_list[tb->cy-1]);
4347 string_free(tb->lines_list[tb->cy]);
4348 tb->lines_list[tb->cy-1] = string_make(buf);
4349 for (i = tb->cy; tb->lines_list[i+1]; i++)
4350 tb->lines_list[i] = tb->lines_list[i+1];
4351 tb->lines_list[i] = NULL;
4355 tb->dirty_flags |= DIRTY_ALL;
4359 for (i = j = k = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
4363 if (iskanji(tb->lines_list[tb->cy][i]))
4364 buf[j++] = tb->lines_list[tb->cy][i++];
4366 buf[j++] = tb->lines_list[tb->cy][i];
4373 for (; tb->lines_list[tb->cy][i]; i++)
4374 buf[j++] = tb->lines_list[tb->cy][i];
4376 string_free(tb->lines_list[tb->cy]);
4377 tb->lines_list[tb->cy] = string_make(buf);
4380 tb->dirty_line = tb->cy;
4388 /* Become dirty because of item/equip menu */
4389 tb->dirty_flags |= DIRTY_SCREEN;
4391 search_dir = get_string_for_search(&tb->search_o_ptr, &tb->search_str);
4393 if (!search_dir) break;
4395 if (search_dir == 1) do_editor_command(tb, EC_SEARCH_FORW);
4396 else do_editor_command(tb, EC_SEARCH_BACK);
4400 case EC_SEARCH_FORW:
4401 if (tb->search_o_ptr)
4403 if (!search_for_object(tb->lines_list, tb->search_o_ptr, &tb->cx, &tb->cy, TRUE)) tb->dirty_flags |= DIRTY_NOT_FOUND;
4405 else if (tb->search_str)
4407 if (!search_for_string(tb->lines_list, tb->search_str, &tb->cx, &tb->cy, TRUE)) tb->dirty_flags |= DIRTY_NOT_FOUND;
4411 tb->dirty_flags |= DIRTY_NO_SEARCH;
4415 case EC_SEARCH_BACK:
4416 if (tb->search_o_ptr)
4418 if (!search_for_object(tb->lines_list, tb->search_o_ptr, &tb->cx, &tb->cy, FALSE)) tb->dirty_flags |= DIRTY_NOT_FOUND;
4420 else if (tb->search_str)
4422 if (!search_for_string(tb->lines_list, tb->search_str, &tb->cx, &tb->cy, FALSE)) tb->dirty_flags |= DIRTY_NOT_FOUND;
4426 tb->dirty_flags |= DIRTY_NO_SEARCH;
4431 /* Become dirty because of item/equip menu */
4432 tb->dirty_flags |= DIRTY_SCREEN;
4434 if (!get_object_for_search(&tb->search_o_ptr, &tb->search_str)) break;
4436 do_editor_command(tb, EC_SEARCH_FORW);
4439 case EC_SEARCH_DESTROYED:
4440 if (!get_destroyed_object_for_search(&tb->search_o_ptr, &tb->search_str)) break;
4442 do_editor_command(tb, EC_SEARCH_FORW);
4445 case EC_INSERT_OBJECT:
4447 /* Insert choosen item name */
4449 autopick_type an_entry, *entry = &an_entry;
4451 if (!entry_from_choosed_object(entry))
4453 /* Now dirty because of item/equip menu */
4454 tb->dirty_flags |= DIRTY_SCREEN;
4458 insert_return_code(tb->lines_list, 0, tb->cy);
4459 string_free(tb->lines_list[tb->cy]);
4460 tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
4463 /* Now dirty because of item/equip menu */
4464 tb->dirty_flags |= DIRTY_SCREEN;
4469 case EC_INSERT_DESTROYED:
4470 /* Insert a name of last destroyed item */
4471 if (tb->last_destroyed)
4473 insert_return_code(tb->lines_list, 0, tb->cy);
4474 string_free(tb->lines_list[tb->cy]);
4475 tb->lines_list[tb->cy] = string_make(tb->last_destroyed);
4479 tb->dirty_flags |= DIRTY_ALL;
4483 case EC_INSERT_BLOCK:
4485 /* Insert a conditinal expression line */
4488 /* Conditional Expression for Class and Race */
4489 sprintf(classrace, "?:[AND [EQU $RACE %s] [EQU $CLASS %s]]",
4491 rp_ptr->E_title, cp_ptr->E_title
4493 rp_ptr->title, cp_ptr->title
4497 insert_return_code(tb->lines_list, 0, tb->cy);
4498 string_free(tb->lines_list[tb->cy]);
4499 tb->lines_list[tb->cy] = string_make(classrace);
4501 insert_return_code(tb->lines_list, 0, tb->cy);
4502 string_free(tb->lines_list[tb->cy]);
4503 tb->lines_list[tb->cy] = string_make("?:1");
4507 tb->dirty_flags |= DIRTY_ALL;
4511 case EC_INSERT_MACRO:
4512 /* Draw_everythig (delete menu) */
4513 draw_text_editor(tb);
4516 Term_erase(0, tb->cy - tb->upper + 1, tb->wid);
4520 Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW, "P:<¥È¥ê¥¬¡¼¥¡¼>: ");
4522 Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW, "P:<Trigger key>: ");
4524 if (insert_macro_line(tb->lines_list, tb->cy))
4526 /* Prepare to input action */
4530 tb->dirty_flags |= DIRTY_ALL;
4531 tb->dirty_flags |= DIRTY_MODE;
4536 case EC_INSERT_KEYMAP:
4537 /* Draw_everythig (delete menu) */
4538 draw_text_editor(tb);
4541 Term_erase(0, tb->cy - tb->upper + 1, tb->wid);
4545 Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW, format("C:%d:<¥³¥Þ¥ó¥É¥¡¼>: ", (rogue_like_commands ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG)));
4547 Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW, format("C:%d:<Keypress>: ", (rogue_like_commands ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG)));
4550 if (insert_keymap_line(tb->lines_list, tb->cy))
4552 /* Prepare to input action */
4556 tb->dirty_flags |= DIRTY_ALL;
4557 tb->dirty_flags |= DIRTY_MODE;
4561 case EC_CL_AUTOPICK: toggle_command_letter(tb, DO_AUTOPICK); break;
4562 case EC_CL_DESTROY: toggle_command_letter(tb, DO_AUTODESTROY); break;
4563 case EC_CL_LEAVE: toggle_command_letter(tb, DONT_AUTOPICK); break;
4564 case EC_CL_QUERY: toggle_command_letter(tb, DO_QUERY_AUTOPICK); break;
4565 case EC_CL_NO_DISP: toggle_command_letter(tb, DO_DISPLAY); break;
4567 case EC_IK_UNAWARE: toggle_keyword(tb, FLG_UNAWARE); break;
4568 case EC_IK_UNIDENTIFIED: toggle_keyword(tb, FLG_UNIDENTIFIED); break;
4569 case EC_IK_IDENTIFIED: toggle_keyword(tb, FLG_IDENTIFIED); break;
4570 case EC_IK_STAR_IDENTIFIED: toggle_keyword(tb, FLG_STAR_IDENTIFIED); break;
4571 case EC_KK_WEAPONS: toggle_keyword(tb, FLG_WEAPONS); break;
4572 case EC_KK_FAVORITE: toggle_keyword(tb, FLG_FAVORITE); break;
4573 case EC_KK_ARMORS: toggle_keyword(tb, FLG_ARMORS); break;
4574 case EC_KK_MISSILES: toggle_keyword(tb, FLG_MISSILES); break;
4575 case EC_KK_DEVICES: toggle_keyword(tb, FLG_DEVICES); break;
4576 case EC_KK_LIGHTS: toggle_keyword(tb, FLG_LIGHTS); break;
4577 case EC_KK_JUNKS: toggle_keyword(tb, FLG_JUNKS); break;
4578 case EC_KK_SPELLBOOKS: toggle_keyword(tb, FLG_SPELLBOOKS); break;
4579 case EC_KK_SHIELDS: toggle_keyword(tb, FLG_SHIELDS); break;
4580 case EC_KK_BOWS: toggle_keyword(tb, FLG_BOWS); break;
4581 case EC_KK_RINGS: toggle_keyword(tb, FLG_RINGS); break;
4582 case EC_KK_AMULETS: toggle_keyword(tb, FLG_AMULETS); break;
4583 case EC_KK_SUITS: toggle_keyword(tb, FLG_SUITS); break;
4584 case EC_KK_CLOAKS: toggle_keyword(tb, FLG_CLOAKS); break;
4585 case EC_KK_HELMS: toggle_keyword(tb, FLG_HELMS); break;
4586 case EC_KK_GLOVES: toggle_keyword(tb, FLG_GLOVES); break;
4587 case EC_KK_BOOTS: toggle_keyword(tb, FLG_BOOTS); break;
4588 case EC_OK_COLLECTING: toggle_keyword(tb, FLG_COLLECTING); break;
4589 case EC_OK_BOOSTED: toggle_keyword(tb, FLG_BOOSTED); break;
4590 case EC_OK_MORE_THAN: toggle_keyword(tb, FLG_MORE_THAN); break;
4591 case EC_OK_MORE_BONUS: toggle_keyword(tb, FLG_MORE_BONUS); break;
4592 case EC_OK_WORTHLESS: toggle_keyword(tb, FLG_WORTHLESS); break;
4593 case EC_OK_ARTIFACT: toggle_keyword(tb, FLG_ARTIFACT); break;
4594 case EC_OK_EGO: toggle_keyword(tb, FLG_EGO); break;
4595 case EC_OK_NAMELESS: toggle_keyword(tb, FLG_NAMELESS); break;
4596 case EC_OK_WANTED: toggle_keyword(tb, FLG_WANTED); break;
4597 case EC_OK_UNIQUE: toggle_keyword(tb, FLG_UNIQUE); break;
4598 case EC_OK_HUMAN: toggle_keyword(tb, FLG_HUMAN); break;
4599 case EC_OK_UNREADABLE:
4600 toggle_keyword(tb, FLG_UNREADABLE);
4601 add_keyword(tb, FLG_SPELLBOOKS);
4604 toggle_keyword(tb, FLG_REALM1);
4605 add_keyword(tb, FLG_SPELLBOOKS);
4608 toggle_keyword(tb, FLG_REALM2);
4609 add_keyword(tb, FLG_SPELLBOOKS);
4612 toggle_keyword(tb, FLG_FIRST);
4613 add_keyword(tb, FLG_SPELLBOOKS);
4616 toggle_keyword(tb, FLG_SECOND);
4617 add_keyword(tb, FLG_SPELLBOOKS);
4620 toggle_keyword(tb, FLG_THIRD);
4621 add_keyword(tb, FLG_SPELLBOOKS);
4624 toggle_keyword(tb, FLG_FOURTH);
4625 add_keyword(tb, FLG_SPELLBOOKS);
4629 /* Save old command */
4630 tb->old_com_id = com_id;
4637 * Insert single letter at cursor position.
4639 static void insert_single_letter(text_body_type *tb, int key)
4642 char buf[MAX_LINELEN];
4644 /* Save preceding string */
4645 for (i = j = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
4646 buf[j++] = tb->lines_list[tb->cy][i];
4648 /* Add a character */
4656 if (j+2 < MAX_LINELEN)
4668 if (j+1 < MAX_LINELEN)
4674 for (; tb->lines_list[tb->cy][i] && j + 1 < MAX_LINELEN; i++)
4675 buf[j++] = tb->lines_list[tb->cy][i];
4678 /* Replace current line with new line */
4679 string_free(tb->lines_list[tb->cy]);
4680 tb->lines_list[tb->cy] = string_make(buf);
4682 /* Move to correct collumn */
4683 len = strlen(tb->lines_list[tb->cy]);
4684 if (len < tb->cx) tb->cx = len;
4687 tb->dirty_line = tb->cy;
4691 * In-game editor of Object Auto-picker/Destoryer
4693 void do_cmd_edit_autopick(void)
4695 text_body_type text_body, *tb = &text_body;
4697 autopick_type an_entry, *entry = &an_entry;
4698 char buf[MAX_LINELEN];
4703 static s32b old_autosave_turn = 0L;
4706 tb->cx = tb->cy = tb->upper = tb->left = 0;
4708 tb->mx = tb->my = 0;
4709 tb->old_cy = tb->old_upper = tb->old_left = -1;
4710 tb->old_wid = tb->old_hgt = -1;
4714 tb->search_o_ptr = NULL;
4715 tb->search_str = NULL;
4716 tb->last_destroyed = NULL;
4717 tb->dirty_flags = DIRTY_ALL | DIRTY_MODE;
4718 tb->dirty_line = -1;
4719 tb->filename_mode = PT_WITH_PNAME;
4722 if (turn > old_autosave_turn + 100L)
4724 do_cmd_save_game(TRUE);
4725 old_autosave_turn = turn;
4728 /* HACK -- Reset start_time to stop counting playtime while edit */
4731 /* Free old entries */
4734 /* Command Description of the 'Last Destroyed Item' */
4735 if (autopick_last_destroyed_object.k_idx)
4737 autopick_entry_from_object(entry, &autopick_last_destroyed_object);
4738 tb->last_destroyed = autopick_line_from_entry_kill(entry);
4741 /* Read or initialize whole text */
4742 tb->lines_list = read_pickpref_text_lines(&tb->filename_mode);
4744 /* Reset cursor position if needed */
4745 for (i = 0; i < tb->cy; i++)
4747 if (!tb->lines_list[i])
4749 tb->cy = tb->cx = 0;
4754 /* Save the screen */
4757 /* Process requests until done */
4763 /* Draw_everythig */
4764 draw_text_editor(tb);
4766 /* Display header line */
4768 prt("(^Q:½ªÎ», ESC:¥á¥Ë¥å¡¼, ¤½¤Î¾:ÆþÎÏ)", 0, 0);
4770 prt("(^Q:quit, ESC:menu, Other:input text)", 0, 0);
4774 /* Display current position */
4775 prt (format("(%d,%d)", tb->cx, tb->cy), 0, 60);
4779 /* Display current position and mark position */
4780 prt (format("(%d,%d)-(%d,%d)", tb->mx, tb->my, tb->cx, tb->cy), 0, 60);
4784 Term_gotoxy(tb->cx - tb->left, tb->cy - tb->upper + 1);
4787 tb->dirty_flags = 0;
4788 tb->dirty_line = -1;
4790 /* Save old key and location */
4791 tb->old_cy = tb->cy;
4792 tb->old_upper = tb->upper;
4793 tb->old_left = tb->left;
4794 tb->old_wid = tb->wid;
4795 tb->old_hgt = tb->hgt;
4800 /* Count length of macro trigger which induced this key */
4801 trig_len = strlen(inkey_macro_trigger_string);
4803 /* HACK -- ignore macro defined on ASCII keys */
4806 /* Get original key */
4807 key = inkey_macro_trigger_string[0];
4811 if (key == 0x7F) key = KTRL('d');
4814 /* Cursor key macroes to direction command */
4836 * Un-shifted cursor keys cancells
4837 * selection created by shift+cursor.
4839 if (tb->mark & MARK_BY_SHIFT)
4844 tb->dirty_flags |= DIRTY_ALL;
4848 /* Mega Hack!!! Start selection with shift + cursor keys */
4853 /* Get ascii form */
4854 ascii_to_text(buf, inkey_macro_trigger_string);
4856 if (strstr(buf, "shift-Down"))
4858 else if (strstr(buf, "shift-Left"))
4860 else if (strstr(buf, "shift-Right"))
4862 else if (strstr(buf, "shift-Up"))
4867 /* Kill further macro expansion */
4870 /* Start selection */
4873 tb->mark = MARK_MARK | MARK_BY_SHIFT;
4877 /* Need to redraw text */
4878 if (com_id == EC_UP || com_id == EC_DOWN)
4880 /* Redraw all text */
4881 tb->dirty_flags |= DIRTY_ALL;
4885 tb->dirty_line = tb->cy;
4898 else if (key == ESCAPE)
4900 com_id = do_command_menu(0, 0);
4902 /* Redraw all text later */
4903 tb->dirty_flags |= DIRTY_SCREEN;
4906 /* Insert a character */
4907 else if (!iscntrl(key & 0xff))
4910 * If there is a selection, kill text, and
4911 * replace it with a single letter.
4913 if (tb->mark) kill_text_in_selection(tb);
4915 insert_single_letter(tb, key);
4921 /* Other commands */
4924 com_id = get_com_id(key);
4927 if (com_id) quit = do_editor_command(tb, com_id);
4930 /* Restore the screen */
4933 switch (tb->filename_mode)
4937 strcpy(buf, "picktype.prf");
4939 strcpy(buf, "pickpref.prf");
4945 sprintf(buf, "picktype-%s.prf", player_name);
4947 sprintf(buf, "pickpref-%s.prf", player_name);
4952 write_text_lines(buf, tb->lines_list);
4953 free_text_lines(tb->lines_list);
4955 string_free(tb->last_destroyed);
4957 /* Destroy string chain */
4958 kill_yank_chain(tb);
4960 /* Reload autopick pref */
4961 process_pickpref_file(buf);
4963 /* HACK -- reset start_time so that playtime is not increase while edit */
4964 start_time = time(NULL);