OSDN Git Service

下部の区切り線の位置に現在のモード名を表示するようにした。
[hengbandforosx/hengbandosx.git] / src / autopick.c
1 /* File: autopick.c */
2
3 /* Purpose: Object Auto-picker/Destroyer */
4
5 /*
6  * Copyright (c) 2002  Mogami
7  *
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.
11  */
12
13 #include "angband.h"
14
15 /*
16  * Macros for Keywords
17  */
18 #define FLG_ALL 0
19 #define FLG_COLLECTING 1
20 #define FLG_UNIDENTIFIED 2
21 #define FLG_IDENTIFIED 3
22 #define FLG_STAR_IDENTIFIED 4
23 #define FLG_NAMELESS 5
24 #define FLG_UNAWARE 6
25 #define FLG_WORTHLESS 7
26 #define FLG_BOOSTED 8
27 #define FLG_MORE_THAN 9
28 #define FLG_DICE 10
29 #define FLG_WANTED 11
30 #define FLG_UNIQUE 12
31 #define FLG_HUMAN 13
32 #define FLG_UNREADABLE 14
33 #define FLG_REALM1 15
34 #define FLG_REALM2 16
35 #define FLG_FIRST 17
36 #define FLG_SECOND 18
37 #define FLG_THIRD 19
38 #define FLG_FOURTH 20
39 #define FLG_ITEMS 21
40 #define FLG_ARTIFACTS 22
41 #define FLG_WEAPONS 23
42 #define FLG_ARMORS 24
43 #define FLG_MISSILES 25
44 #define FLG_DEVICES 26
45 #define FLG_LIGHTS 27
46 #define FLG_JUNKS 28
47 #define FLG_SPELLBOOKS 29
48 #define FLG_HAFTED 30
49 #define FLG_SHIELDS 31
50 #define FLG_BOWS 32
51 #define FLG_RINGS 33
52 #define FLG_AMULETS 34
53 #define FLG_SUITS 35
54 #define FLG_CLOAKS 36
55 #define FLG_HELMS 37
56 #define FLG_GLOVES 38
57 #define FLG_BOOTS 39
58
59 #ifdef JP
60
61 #define KEY_ALL "¤¹¤Ù¤Æ¤Î"
62 #define KEY_COLLECTING "¼ý½¸Ãæ¤Î"
63 #define KEY_UNIDENTIFIED "̤´ÕÄê¤Î"
64 #define KEY_IDENTIFIED "´ÕÄêºÑ¤ß¤Î"
65 #define KEY_STAR_IDENTIFIED "*´ÕÄê*ºÑ¤ß¤Î"
66 #define KEY_NAMELESS "̵ÌäÎ"
67 #define KEY_UNAWARE "̤ȽÌÀ¤Î"
68 #define KEY_WORTHLESS "̵²ÁÃͤÎ"
69 #define KEY_BOOSTED "¥À¥¤¥¹Ìܤΰ㤦"
70 #define KEY_MORE_THAN  "¥À¥¤¥¹ÌÜ"
71 #define KEY_DICE  "°Ê¾å¤Î"
72 #define KEY_WANTED "¾Þ¶â¼ó¤Î"
73 #define KEY_UNIQUE "¥æ¥Ë¡¼¥¯¡¦¥â¥ó¥¹¥¿¡¼¤Î"
74 #define KEY_HUMAN "¿Í´Ö¤Î"
75 #define KEY_UNREADABLE "Æɤá¤Ê¤¤"
76 #define KEY_REALM1 "Âè°ìÎΰè¤Î"
77 #define KEY_REALM2 "ÂèÆóÎΰè¤Î"
78 #define KEY_FIRST "1ºýÌܤÎ"
79 #define KEY_SECOND "2ºýÌܤÎ"
80 #define KEY_THIRD "3ºýÌܤÎ"
81 #define KEY_FOURTH "4ºýÌܤÎ"
82 #define KEY_ITEMS "¥¢¥¤¥Æ¥à"
83 #define KEY_ARTIFACTS "¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È"
84 #define KEY_WEAPONS "Éð´ï"
85 #define KEY_ARMORS "Ëɶñ"
86 #define KEY_MISSILES "Ìð"
87 #define KEY_DEVICES "ËâË¡¥¢¥¤¥Æ¥à"
88 #define KEY_LIGHTS "¸÷¸»"
89 #define KEY_JUNKS "¤¬¤é¤¯¤¿"
90 #define KEY_SPELLBOOKS "ËâË¡½ñ"
91 #define KEY_HAFTED "Æß´ï"
92 #define KEY_SHIELDS "½â"
93 #define KEY_BOWS "µÝ"
94 #define KEY_RINGS "»ØÎØ"
95 #define KEY_AMULETS "¥¢¥ß¥å¥ì¥Ã¥È"
96 #define KEY_SUITS "³»"
97 #define KEY_CLOAKS "¥¯¥í¡¼¥¯"
98 #define KEY_HELMS "³õ"
99 #define KEY_GLOVES "äƼê"
100 #define KEY_BOOTS "·¤"
101
102 #else 
103
104 #define KEY_ALL "all"
105 #define KEY_COLLECTING "collecting"
106 #define KEY_UNIDENTIFIED "unidentified"
107 #define KEY_IDENTIFIED "identified"
108 #define KEY_STAR_IDENTIFIED "*identified*"
109 #define KEY_NAMELESS "nameless"
110 #define KEY_UNAWARE "unaware"
111 #define KEY_WORTHLESS "worthless"
112 #define KEY_BOOSTED "dice boosted"
113 #define KEY_MORE_THAN  "more than "
114 #define KEY_DICE  " dice "
115 #define KEY_WANTED "wanted"
116 #define KEY_UNIQUE "unique monster's"
117 #define KEY_HUMAN "human"
118 #define KEY_UNREADABLE "unreadable"
119 #define KEY_REALM1 "first realm's"
120 #define KEY_REALM2 "second realm's"
121 #define KEY_FIRST "first"
122 #define KEY_SECOND "second"
123 #define KEY_THIRD "third"
124 #define KEY_FOURTH "fourth"
125 #define KEY_ITEMS "items"
126 #define KEY_ARTIFACTS "artifacts"
127 #define KEY_WEAPONS "weapons"
128 #define KEY_ARMORS "armors"
129 #define KEY_MISSILES "missiles"
130 #define KEY_DEVICES "magical devices"
131 #define KEY_LIGHTS "lights"
132 #define KEY_JUNKS "junks"
133 #define KEY_SPELLBOOKS "spellbooks"
134 #define KEY_HAFTED "hafted weapons"
135 #define KEY_SHIELDS "shields"
136 #define KEY_BOWS "bows"
137 #define KEY_RINGS "rings"
138 #define KEY_AMULETS "amulets"
139 #define KEY_SUITS "suits"
140 #define KEY_CLOAKS "cloaks"
141 #define KEY_HELMS "helms"
142 #define KEY_GLOVES "gloves"
143 #define KEY_BOOTS "boots"
144
145 #endif /* JP */
146
147 #define MATCH_KEY(KEY) (!strncmp(ptr, KEY, sizeof(KEY)-1)\
148      ? (prev_ptr = ptr, ptr += sizeof(KEY)-1, (' '==*ptr) ? ptr++ : 0, TRUE) : FALSE)
149
150 #ifdef JP
151 #define ADD_KEY(KEY) strcat(ptr, KEY)
152 #else
153 #define ADD_KEY(KEY) (strcat(ptr, KEY), strcat(ptr, " "))
154 #endif
155 #define ADD_KEY2(KEY) strcat(ptr, KEY)
156
157 #define ADD_FLG(FLG) (entry->flag[FLG / 32] |= (1L << (FLG % 32)))
158 #define REM_FLG(FLG) (entry->flag[FLG / 32] &= ~(1L << (FLG % 32)))
159 #define ADD_FLG2(FLG) (entry->flag[FLG / 32] |= (1L << (FLG % 32)), prev_flg = FLG)
160 #define IS_FLG(FLG) (entry->flag[FLG / 32] & (1L << (FLG % 32)))
161
162 #ifdef JP
163         static char kanji_colon[] = "¡§";
164 #endif
165
166
167 /*
168  * Reconstruct preference line from entry
169  */
170 cptr autopick_line_from_entry(autopick_type *entry)
171 {
172         char buf[1024];
173         char *ptr;
174         bool sepa_flag = TRUE;
175
176         *buf = '\0';
177         if (!(entry->action & DO_DISPLAY)) strcat(buf, "(");
178         if (entry->action & DO_AUTODESTROY) strcat(buf, "!");
179         if (entry->action & DONT_AUTOPICK) strcat(buf, "~");
180
181         ptr = buf;
182
183         if (IS_FLG(FLG_ALL)) ADD_KEY(KEY_ALL);
184         if (IS_FLG(FLG_COLLECTING)) ADD_KEY(KEY_COLLECTING);
185         if (IS_FLG(FLG_UNIDENTIFIED)) ADD_KEY(KEY_UNIDENTIFIED);
186         if (IS_FLG(FLG_IDENTIFIED)) ADD_KEY(KEY_IDENTIFIED);
187         if (IS_FLG(FLG_STAR_IDENTIFIED)) ADD_KEY(KEY_STAR_IDENTIFIED);
188         if (IS_FLG(FLG_NAMELESS)) ADD_KEY(KEY_NAMELESS);
189         if (IS_FLG(FLG_UNAWARE)) ADD_KEY(KEY_UNAWARE);
190         if (IS_FLG(FLG_WORTHLESS)) ADD_KEY(KEY_WORTHLESS);
191         if (IS_FLG(FLG_BOOSTED)) ADD_KEY(KEY_BOOSTED);
192
193         if (IS_FLG(FLG_MORE_THAN))
194         {
195                 ADD_KEY(KEY_MORE_THAN);
196                 strcat(ptr, format("%2d", entry->dice));
197                 ADD_KEY(KEY_DICE);
198         }
199
200         if (IS_FLG(FLG_WANTED)) ADD_KEY(KEY_WANTED);
201         if (IS_FLG(FLG_UNIQUE)) ADD_KEY(KEY_UNIQUE);
202         if (IS_FLG(FLG_HUMAN)) ADD_KEY(KEY_HUMAN);
203         if (IS_FLG(FLG_UNREADABLE)) ADD_KEY(KEY_UNREADABLE);
204         if (IS_FLG(FLG_REALM1)) ADD_KEY(KEY_REALM1);
205         if (IS_FLG(FLG_REALM2)) ADD_KEY(KEY_REALM2);
206         if (IS_FLG(FLG_FIRST)) ADD_KEY(KEY_FIRST);
207         if (IS_FLG(FLG_SECOND)) ADD_KEY(KEY_SECOND);
208         if (IS_FLG(FLG_THIRD)) ADD_KEY(KEY_THIRD);
209         if (IS_FLG(FLG_FOURTH)) ADD_KEY(KEY_FOURTH);
210
211         if (IS_FLG(FLG_ITEMS)) ADD_KEY2(KEY_ITEMS);
212         else if (IS_FLG(FLG_ARTIFACTS)) ADD_KEY2(KEY_ARTIFACTS);
213         else if (IS_FLG(FLG_WEAPONS)) ADD_KEY2(KEY_WEAPONS);
214         else if (IS_FLG(FLG_ARMORS)) ADD_KEY2(KEY_ARMORS);
215         else if (IS_FLG(FLG_MISSILES)) ADD_KEY2(KEY_MISSILES);
216         else if (IS_FLG(FLG_DEVICES)) ADD_KEY2(KEY_DEVICES);
217         else if (IS_FLG(FLG_LIGHTS)) ADD_KEY2(KEY_LIGHTS);
218         else if (IS_FLG(FLG_JUNKS)) ADD_KEY2(KEY_JUNKS);
219         else if (IS_FLG(FLG_SPELLBOOKS)) ADD_KEY2(KEY_SPELLBOOKS);
220         else if (IS_FLG(FLG_HAFTED)) ADD_KEY2(KEY_HAFTED);
221         else if (IS_FLG(FLG_SHIELDS)) ADD_KEY2(KEY_SHIELDS);
222         else if (IS_FLG(FLG_BOWS)) ADD_KEY2(KEY_BOWS);
223         else if (IS_FLG(FLG_RINGS)) ADD_KEY2(KEY_RINGS);
224         else if (IS_FLG(FLG_AMULETS)) ADD_KEY2(KEY_AMULETS);
225         else if (IS_FLG(FLG_SUITS)) ADD_KEY2(KEY_SUITS);
226         else if (IS_FLG(FLG_CLOAKS)) ADD_KEY2(KEY_CLOAKS);
227         else if (IS_FLG(FLG_HELMS)) ADD_KEY2(KEY_HELMS);
228         else if (IS_FLG(FLG_GLOVES)) ADD_KEY2(KEY_GLOVES);
229         else if (IS_FLG(FLG_BOOTS)) ADD_KEY2(KEY_BOOTS);
230         else
231                 sepa_flag = FALSE;
232
233         if (entry->name && *entry->name)
234         {
235                 if (sepa_flag)
236                         strcat(buf, ":");
237                 strcat(buf, entry->name);
238         }
239         else
240         {
241                 if (entry->flag[0] == 0L && entry->flag[0] == 0L)
242                         return NULL;
243         }
244
245         if (entry->insc)
246         {
247                 strcat(buf, "#");
248                 strcat(buf, entry->insc);
249         }
250
251         return string_make(buf);
252 }
253
254 /*
255  * A function to create new entry
256  */
257 bool autopick_new_entry(autopick_type *entry, cptr str)
258 {
259         cptr insc;
260         int i;
261         byte act = 0;
262         char buf[1024];
263         cptr prev_ptr, ptr;
264         int prev_flg;
265
266         if (str[1] == ':') switch (str[0])
267         {
268         case '?': case '%':
269         case 'A': case 'P': case 'C':
270                 return FALSE;
271         }
272
273         entry->flag[0] = entry->flag[1] = 0L;
274         entry->dice = 0;
275
276         act = DO_AUTOPICK | DO_DISPLAY;
277         while (1)
278         {
279                 if (*str == '!')
280                 {
281                         act &= ~DO_AUTOPICK;
282                         act |= DO_AUTODESTROY;
283                         str++;
284                 }
285                 else if (*str == '~')
286                 {
287                         act &= ~DO_AUTOPICK;
288                         act |= DONT_AUTOPICK;
289                         str++;
290                 }
291                 else if (*str == '(')
292                 {
293                         act &= ~DO_DISPLAY;
294                         str++;
295                 }
296                 else
297                         break;
298         }
299
300         /* don't mind upper or lower case */
301         insc = NULL;
302         for (i = 0; *str; i++)
303         {
304                 char c = *str++;
305 #ifdef JP
306                 if (iskanji(c))
307                 {
308                         buf[i++] = c;
309                         buf[i] = *str++;
310                         continue;
311                 }
312 #endif
313                 /* Auto-inscription? */
314                 if (c == '#')
315                 {
316                         buf[i] = '\0';
317                         insc = str;
318                         break;
319                 }
320
321                 if (isupper(c)) c = tolower(c);
322
323                 buf[i] = c;
324         }
325         buf[i] = '\0';
326         
327         /* Skip empty line */
328         if (*buf == 0) return FALSE;
329
330         /* Found flags */
331         prev_ptr = ptr = buf;
332         prev_flg = -1;
333         if (MATCH_KEY(KEY_ALL)) ADD_FLG(FLG_ALL);
334         if (MATCH_KEY(KEY_COLLECTING)) ADD_FLG(FLG_COLLECTING);
335         if (MATCH_KEY(KEY_UNIDENTIFIED)) ADD_FLG(FLG_UNIDENTIFIED);
336         if (MATCH_KEY(KEY_IDENTIFIED)) ADD_FLG(FLG_IDENTIFIED);
337         if (MATCH_KEY(KEY_STAR_IDENTIFIED)) ADD_FLG(FLG_STAR_IDENTIFIED);
338         if (MATCH_KEY(KEY_NAMELESS)) ADD_FLG(FLG_NAMELESS);
339         if (MATCH_KEY(KEY_UNAWARE)) ADD_FLG(FLG_UNAWARE);
340         if (MATCH_KEY(KEY_WORTHLESS)) ADD_FLG(FLG_WORTHLESS);
341         if (MATCH_KEY(KEY_BOOSTED)) ADD_FLG(FLG_BOOSTED);
342
343         /*** Weapons whic dd*ds is more than nn ***/
344         if (MATCH_KEY(KEY_MORE_THAN))
345         {
346                 if (isdigit(ptr[0]) && isdigit(ptr[1]))
347                 {
348                         entry->dice = (ptr[0] - '0') * 10 + (ptr[1] - '0');
349                         ptr += 2;
350                         (void)MATCH_KEY(KEY_DICE);
351                         ADD_FLG(FLG_MORE_THAN);
352                 }
353                 else
354                         ptr = prev_ptr;
355         }
356
357         if (MATCH_KEY(KEY_WANTED)) ADD_FLG(FLG_WANTED);
358         if (MATCH_KEY(KEY_UNIQUE)) ADD_FLG(FLG_UNIQUE);
359         if (MATCH_KEY(KEY_HUMAN)) ADD_FLG(FLG_HUMAN);
360         if (MATCH_KEY(KEY_UNREADABLE)) ADD_FLG(FLG_UNREADABLE);
361         if (MATCH_KEY(KEY_REALM1)) ADD_FLG(FLG_REALM1);
362         if (MATCH_KEY(KEY_REALM2)) ADD_FLG(FLG_REALM2);
363         if (MATCH_KEY(KEY_FIRST)) ADD_FLG(FLG_FIRST);
364         if (MATCH_KEY(KEY_SECOND)) ADD_FLG(FLG_SECOND);
365         if (MATCH_KEY(KEY_THIRD)) ADD_FLG(FLG_THIRD);
366         if (MATCH_KEY(KEY_FOURTH)) ADD_FLG(FLG_FOURTH);
367
368         /* Reset previous word location */
369         prev_ptr = ptr;
370
371         if (MATCH_KEY(KEY_ITEMS)) ADD_FLG2(FLG_ITEMS);
372         else if (MATCH_KEY(KEY_ARTIFACTS)) ADD_FLG2(FLG_ARTIFACTS);
373         else if (MATCH_KEY(KEY_WEAPONS)) ADD_FLG2(FLG_WEAPONS);
374         else if (MATCH_KEY(KEY_ARMORS)) ADD_FLG2(FLG_ARMORS);
375         else if (MATCH_KEY(KEY_MISSILES)) ADD_FLG2(FLG_MISSILES);
376         else if (MATCH_KEY(KEY_DEVICES)) ADD_FLG2(FLG_DEVICES);
377         else if (MATCH_KEY(KEY_LIGHTS)) ADD_FLG2(FLG_LIGHTS);
378         else if (MATCH_KEY(KEY_JUNKS)) ADD_FLG2(FLG_JUNKS);
379         else if (MATCH_KEY(KEY_SPELLBOOKS)) ADD_FLG2(FLG_SPELLBOOKS);
380         else if (MATCH_KEY(KEY_HAFTED)) ADD_FLG2(FLG_HAFTED);
381         else if (MATCH_KEY(KEY_SHIELDS)) ADD_FLG2(FLG_SHIELDS);
382         else if (MATCH_KEY(KEY_BOWS)) ADD_FLG2(FLG_BOWS);
383         else if (MATCH_KEY(KEY_RINGS)) ADD_FLG2(FLG_RINGS);
384         else if (MATCH_KEY(KEY_AMULETS)) ADD_FLG2(FLG_AMULETS);
385         else if (MATCH_KEY(KEY_SUITS)) ADD_FLG2(FLG_SUITS);
386         else if (MATCH_KEY(KEY_CLOAKS)) ADD_FLG2(FLG_CLOAKS);
387         else if (MATCH_KEY(KEY_HELMS)) ADD_FLG2(FLG_HELMS);
388         else if (MATCH_KEY(KEY_GLOVES)) ADD_FLG2(FLG_GLOVES);
389         else if (MATCH_KEY(KEY_BOOTS)) ADD_FLG2(FLG_BOOTS);
390
391         /* Last 'keyword' must be at the correct location */
392         if (*ptr == ':')
393                 ptr++;
394         else if (*ptr == '\0')
395                 ; /* nothing to do */
396 #ifdef JP
397         else if (ptr[0] == kanji_colon[0] && ptr[1] == kanji_colon[1])
398                 ptr += 2;
399 #endif
400         else
401         {
402                 if (prev_flg != -1)
403                         entry->flag[prev_flg/32] &= ~(1L<< (prev_flg%32));
404                 ptr = prev_ptr;
405         }
406         entry->name = string_make(ptr);
407         entry->action = act;
408         entry->insc = string_make(insc);
409
410         return TRUE;
411 }
412
413 /*
414  * A function to delete entry
415  */
416 void autopick_free_entry(autopick_type *entry)
417 {
418         string_free(entry->name);
419         string_free(entry->insc);
420 }
421
422 /*
423  * A function for Auto-picker/destroyer
424  * Examine whether the object matches to the list of keywords or not.
425  */
426
427 int is_autopick(object_type *o_ptr)
428 {
429         int i;
430         char o_name[MAX_NLEN];
431
432         if (o_ptr->tval == TV_GOLD) return -1;
433         
434         object_desc(o_name, o_ptr, FALSE, 3);
435
436         /* Force to be lower case string */
437         for (i = 0; o_name[i]; i++)
438         {
439 #ifdef JP
440                 if (iskanji(o_name[i]))
441                         i++;
442                 else
443 #endif
444                 if (isupper(o_name[i]))
445                         o_name[i] = tolower(o_name[i]);
446         }
447         
448         for (i=0; i < max_autopick; i++)
449         {
450                 autopick_type *entry = &autopick_list[i];
451                 bool flag = FALSE;
452                 cptr ptr = autopick_list[i].name;
453
454                 /*** Unidentified ***/
455                 if (IS_FLG(FLG_UNIDENTIFIED)
456                     && (object_known_p(o_ptr) || (o_ptr->ident & IDENT_SENSE)))
457                         continue;
458
459                 /*** Identified ***/
460                 if (IS_FLG(FLG_IDENTIFIED) && !object_known_p(o_ptr))
461                         continue;
462
463                 /*** *Identified* ***/
464                 if (IS_FLG(FLG_STAR_IDENTIFIED) &&
465                     (!object_known_p(o_ptr) || !(o_ptr->ident & IDENT_MENTAL)))
466                         continue;
467
468                 /*** Nameless ***/
469                 if (IS_FLG(FLG_NAMELESS))
470                 {
471                         switch (o_ptr->tval)
472                         {
473                         case TV_WHISTLE:
474                         case TV_SHOT: case TV_ARROW: case TV_BOLT: case TV_BOW:
475                         case TV_DIGGING: case TV_HAFTED: case TV_POLEARM: case TV_SWORD: 
476                         case TV_BOOTS: case TV_GLOVES: case TV_HELM: case TV_CROWN:
477                         case TV_SHIELD: case TV_CLOAK:
478                         case TV_SOFT_ARMOR: case TV_HARD_ARMOR: case TV_DRAG_ARMOR:
479                         case TV_LITE: case TV_AMULET: case TV_RING: case TV_CARD:
480                                 if ((!object_known_p(o_ptr) || o_ptr->inscription
481                                      || o_ptr->name1 || o_ptr->name2 || o_ptr->art_name))
482                                         continue;
483                                 break;
484                         default:
485                                 /* don't match */
486                                 continue;
487                         }
488                 }
489
490                 /*** Unaware items ***/
491                 if (IS_FLG(FLG_UNAWARE) && object_aware_p(o_ptr))
492                         continue;
493
494                 /*** Worthless items ***/
495                 if (IS_FLG(FLG_WORTHLESS) && object_value(o_ptr) > 0)
496                         continue;
497
498                 /*** Dice boosted (weapon of slaying) ***/
499                 if (IS_FLG(FLG_BOOSTED))
500                 {
501                         object_kind *k_ptr = &k_info[o_ptr->k_idx];
502                         
503                         switch( o_ptr->tval )
504                         {
505                         case TV_HAFTED:
506                         case TV_POLEARM:
507                         case TV_SWORD:
508                         case TV_DIGGING:
509                                 if ((o_ptr->dd != k_ptr->dd) || (o_ptr->ds != k_ptr->ds))
510                                         break;
511                                 else
512                                         continue;
513                         default:
514                                 continue;
515                         }
516                 }
517
518                 /*** Weapons whic dd*ds is more than nn ***/
519                 if (IS_FLG(FLG_MORE_THAN))
520                 {
521                         if (o_ptr->dd * o_ptr->ds < entry->dice)
522                                 continue;
523                 }
524                                 
525                 /*** Wanted monster's corpse/skeletons ***/
526                 if (IS_FLG(FLG_WANTED) &&
527                     (o_ptr->tval != TV_CORPSE || !object_is_shoukinkubi(o_ptr)))
528                         continue;
529
530                 /*** Unique monster's corpse/skeletons/statues ***/
531                 if (IS_FLG(FLG_UNIQUE) &&
532                     ((o_ptr->tval != TV_CORPSE && o_ptr->tval != TV_STATUE) ||
533                     !(r_info[o_ptr->pval].flags1 & RF1_UNIQUE)))
534                         continue;
535
536                 /*** Human corpse/skeletons (for Daemon magic) ***/
537                 if (IS_FLG(FLG_HUMAN) &&
538                     (o_ptr->tval != TV_CORPSE ||
539                     !strchr("pht", r_info[o_ptr->pval].d_char)))
540                         continue;
541
542                 /*** Unreadable spellbooks ***/
543                 if (IS_FLG(FLG_UNREADABLE) &&
544                     (o_ptr->tval < TV_LIFE_BOOK ||
545                     check_book_realm(o_ptr->tval, o_ptr->sval)))
546                         continue;
547
548                 /*** First realm spellbooks ***/
549                 if (IS_FLG(FLG_REALM1) && 
550                     (REALM1_BOOK != o_ptr->tval ||
551                     p_ptr->pclass == CLASS_SORCERER ||
552                     p_ptr->pclass == CLASS_RED_MAGE))
553                         continue;
554
555                 /*** Second realm spellbooks ***/
556                 if (IS_FLG(FLG_REALM2) &&
557                     (REALM2_BOOK != o_ptr->tval ||
558                     p_ptr->pclass == CLASS_SORCERER ||
559                     p_ptr->pclass == CLASS_RED_MAGE))
560                         continue;
561
562                 /*** First rank spellbooks ***/
563                 if (IS_FLG(FLG_FIRST) &&
564                     (o_ptr->tval < TV_LIFE_BOOK || 0 != o_ptr->sval))
565                         continue;
566
567                 /*** Second rank spellbooks ***/
568                 if (IS_FLG(FLG_SECOND) &&
569                     (o_ptr->tval < TV_LIFE_BOOK || 1 != o_ptr->sval))
570                         continue;
571
572                 /*** Third rank spellbooks ***/
573                 if (IS_FLG(FLG_THIRD) && 
574                     (o_ptr->tval < TV_LIFE_BOOK || 2 != o_ptr->sval))
575                         continue;
576
577                 /*** Fourth rank spellbooks ***/
578                 if (IS_FLG(FLG_FOURTH) &&
579                     (o_ptr->tval < TV_LIFE_BOOK || 3 != o_ptr->sval))
580                         continue;
581
582                 /*** Items ***/
583                 if (IS_FLG(FLG_ARTIFACTS))
584                 {
585                         if (!(object_known_p(o_ptr)
586                               && (artifact_p(o_ptr) || o_ptr->art_name)))
587                                 continue;
588                 }
589                 else if (IS_FLG(FLG_WEAPONS))
590                 {
591                         switch(o_ptr->tval)
592                         {
593                         case TV_BOW: case TV_HAFTED: case TV_POLEARM:
594                         case TV_SWORD: case TV_DIGGING:
595                                 break;
596                         default: continue;
597                         }
598                 }
599                 else if (IS_FLG(FLG_ARMORS))
600                 {
601                         switch(o_ptr->tval)
602                         {
603                         case TV_BOOTS: case TV_GLOVES: case TV_CLOAK: case TV_CROWN:
604                         case TV_HELM: case TV_SHIELD: case TV_SOFT_ARMOR:
605                         case TV_HARD_ARMOR: case TV_DRAG_ARMOR:
606                                 break;
607                         default: continue;
608                         }
609                 }
610                 else if (IS_FLG(FLG_MISSILES))
611                 {
612                         switch(o_ptr->tval)
613                         {
614                         case TV_SHOT: case TV_BOLT: case TV_ARROW:
615                                 break;
616                         default: continue;
617                         }
618                 }
619                 else if (IS_FLG(FLG_DEVICES))
620                 {
621                         switch(o_ptr->tval)
622                         {
623                         case TV_SCROLL: case TV_STAFF: case TV_WAND: case TV_ROD:
624                                 break;
625                         default: continue;
626                         }
627                 }
628                 else if (IS_FLG(FLG_LIGHTS))
629                 {
630                         if (!(o_ptr->tval == TV_LITE))
631                                 continue;
632                 }
633                 else if (IS_FLG(FLG_JUNKS))
634                 {
635                         switch(o_ptr->tval)
636                         {
637                         case TV_SKELETON: case TV_BOTTLE:
638                         case TV_JUNK: case TV_STATUE:
639                                 break;
640                         default: continue;
641                         }
642                 }
643                 else if (IS_FLG(FLG_SPELLBOOKS))
644                 {
645                         if (!(o_ptr->tval >= TV_LIFE_BOOK))
646                                 continue;
647                 }
648                 else if (IS_FLG(FLG_HAFTED))
649                 {
650                         if (!(o_ptr->tval == TV_HAFTED))
651                                 continue;
652                 }
653                 else if (IS_FLG(FLG_SHIELDS))
654                 {
655                         if (!(o_ptr->tval == TV_SHIELD))
656                                 continue;
657                 }
658                 else if (IS_FLG(FLG_BOWS))
659                 {
660                         if (!(o_ptr->tval == TV_BOW))
661                                 continue;
662                 }
663                 else if (IS_FLG(FLG_RINGS))
664                 {
665                         if (!(o_ptr->tval == TV_RING))
666                                 continue;
667                 }
668                 else if (IS_FLG(FLG_AMULETS))
669                 {
670                         if (!(o_ptr->tval == TV_AMULET))
671                                 continue;
672                 }
673                 else if (IS_FLG(FLG_SUITS))
674                 {
675                         if (!(o_ptr->tval == TV_DRAG_ARMOR ||
676                               o_ptr->tval == TV_HARD_ARMOR ||
677                               o_ptr->tval == TV_SOFT_ARMOR))
678                                 continue;
679                 }
680                 else if (IS_FLG(FLG_CLOAKS))
681                 {
682                         if (!(o_ptr->tval == TV_CLOAK))
683                                 continue;
684                 }
685                 else if (IS_FLG(FLG_HELMS))
686                 {
687                         if (!(o_ptr->tval == TV_CROWN || o_ptr->tval == TV_HELM))
688                                 continue;
689                 }
690                 else if (IS_FLG(FLG_GLOVES))
691                 {
692                         if (!(o_ptr->tval == TV_GLOVES))
693                                 continue;
694                 }
695                 else if (IS_FLG(FLG_BOOTS))
696                 {
697                         if (!(o_ptr->tval == TV_BOOTS))
698                                 continue;
699                 }
700
701
702                 if (*ptr == '^')
703                 {
704                         ptr++;
705                         if (!strncmp(o_name, ptr, strlen(ptr)))
706                                 flag = TRUE;
707                 }
708                 else
709 #ifdef JP
710                         if (strstr_j(o_name, ptr))
711 #else
712                         if (strstr(o_name, ptr))
713 #endif
714                 {
715                         flag = TRUE;
716                 }
717
718                 if (flag)
719                 {
720                         int j;
721                         if (!IS_FLG(FLG_COLLECTING))
722                                 return i;
723                         /* Check if there is a same item */
724                         for (j = 0; j < INVEN_PACK; j++)
725                         {
726                                 if (object_similar(&inventory[j], o_ptr))
727                                         return i;
728                         }
729                 }
730         }/* for */
731
732         return -1;
733 }
734
735
736 /*
737  * Describe which kind of object is Auto-picked/destroyed
738  */
739 static void describe_autopick(char *buff, autopick_type *entry)
740 {
741         cptr str = entry->name;
742         byte act = entry->action;
743         cptr insc = entry->insc;
744         int i;
745
746         bool top = FALSE;
747
748 #ifdef JP
749         cptr before_str[20], body_str;
750         int before_n = 0;
751
752         body_str = "¥¢¥¤¥Æ¥à";
753
754         /*** Collecting items ***/
755         /*** Which can be absorbed into a slot as a bundle ***/
756         if (IS_FLG(FLG_COLLECTING))
757                 before_str[before_n++] = "¼ý½¸Ãæ¤Ç´û¤Ë»ý¤Ã¤Æ¤¤¤ë¥¹¥í¥Ã¥È¤Ë¤Þ¤È¤á¤é¤ì¤ë";
758         
759         /*** Unidentified ***/
760         if (IS_FLG(FLG_UNIDENTIFIED))
761                 before_str[before_n++] = "̤´ÕÄê¤Î";
762
763         /*** Identified ***/
764         if (IS_FLG(FLG_IDENTIFIED))
765                 before_str[before_n++] = "´ÕÄêºÑ¤ß¤Î";
766
767         /*** *Identified* ***/
768         if (IS_FLG(FLG_STAR_IDENTIFIED))
769                 before_str[before_n++] = "´°Á´¤Ë´ÕÄêºÑ¤ß¤Î";
770
771         /*** Nameless ***/
772         if (IS_FLG(FLG_NAMELESS))
773         {
774                 before_str[before_n++] = "¥¨¥´¤Ç¤â¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È¤Ç¤â¤Ê¤¤";
775                 body_str = "ÁõÈ÷";
776         }
777
778         /*** Unaware items ***/
779         if (IS_FLG(FLG_UNAWARE))
780                 before_str[before_n++] = "̤´ÕÄê¤Ç¤½¤Î¸ú²Ì¤âȽÌÀ¤·¤Æ¤¤¤Ê¤¤";
781
782         /*** Worthless items ***/
783         if (IS_FLG(FLG_WORTHLESS))
784                 before_str[before_n++] = "Ź¤Ç̵²ÁÃͤÈȽÄꤵ¤ì¤ë";
785
786         /*** Dice boosted (weapon of slaying) ***/
787         if (IS_FLG(FLG_BOOSTED))
788         {
789                 before_str[before_n++] = "¥À¥á¡¼¥¸¥À¥¤¥¹¤¬Ä̾ï¤è¤êÂ礭¤¤";
790                 body_str = "Éð´ï";
791         }
792
793         /*** Weapons whose dd*ds is more than nn ***/
794         if (IS_FLG(FLG_MORE_THAN))
795         {
796                 static char more_than_desc_str[] = "___";
797                 before_str[before_n++] = "¥À¥á¡¼¥¸¥À¥¤¥¹¤ÎºÇÂçÃͤ¬";
798                 body_str = "Éð´ï";
799                         
800                 sprintf(more_than_desc_str,"%2d", entry->dice);
801                 before_str[before_n++] = more_than_desc_str;
802                 before_str[before_n++] = "°Ê¾å¤Î";
803         }
804
805         /*** Wanted monster's corpse/skeletons ***/
806         if (IS_FLG(FLG_WANTED))
807         {
808                 before_str[before_n++] = "¥Ï¥ó¥¿¡¼»ö̳½ê¤Ç¾Þ¶â¼ó¤È¤µ¤ì¤Æ¤¤¤ë";
809                 body_str = "»àÂΤä¹ü";
810         }
811
812         /*** Human corpse/skeletons (for Daemon magic) ***/
813         if (IS_FLG(FLG_HUMAN))
814         {
815                 before_str[before_n++] = "°­ËâËâË¡¤Ç»È¤¦¤¿¤á¤Î¿Í´Ö¤ä¥Ò¥å¡¼¥Þ¥Î¥¤¥É¤Î";
816                 body_str = "»àÂΤä¹ü";
817         }
818
819         /*** Unique monster's corpse/skeletons/statues ***/
820         if (IS_FLG(FLG_UNIQUE))
821         {
822                 before_str[before_n++] = "¥æ¥Ë¡¼¥¯¥â¥ó¥¹¥¿¡¼¤Î";
823                 body_str = "»àÂΤä¹ü";
824         }
825
826         /*** Unreadable spellbooks ***/
827         if (IS_FLG(FLG_UNREADABLE))
828         {
829                 before_str[before_n++] = "Îΰ褬°Û¤Ê¤ë°Ù¤Ë¤¢¤Ê¤¿¤Ë¤ÏÆɤá¤Ê¤¤";
830                 body_str = "ËâË¡½ñ";
831         }
832
833         /*** First realm spellbooks ***/
834         if (IS_FLG(FLG_REALM1))
835         {
836                 before_str[before_n++] = "Âè°ìÎΰè¤Î";
837                 body_str = "ËâË¡½ñ";
838         }
839
840         /*** Second realm spellbooks ***/
841         if (IS_FLG(FLG_REALM2))
842         {
843                 before_str[before_n++] = "ÂèÆóÎΰè¤Î";
844                 body_str = "ËâË¡½ñ";
845         }
846
847         /*** First rank spellbooks ***/
848         if (IS_FLG(FLG_FIRST))
849         {
850                 before_str[before_n++] = "Á´4ºý¤ÎÆâ¤Î1ºýÌܤÎ";
851                 body_str = "ËâË¡½ñ";
852         }
853
854         /*** Second rank spellbooks ***/
855         if (IS_FLG(FLG_SECOND))
856         {
857                 before_str[before_n++] = "Á´4ºý¤ÎÆâ¤Î2ºýÌܤÎ";
858                 body_str = "ËâË¡½ñ";
859         }
860
861         /*** Third rank spellbooks ***/
862         if (IS_FLG(FLG_THIRD))
863         {
864                 before_str[before_n++] = "Á´4ºý¤ÎÆâ¤Î3ºýÌܤÎ";
865                 body_str = "ËâË¡½ñ";
866         }
867
868         /*** Fourth rank spellbooks ***/
869         if (IS_FLG(FLG_FOURTH))
870         {
871                 before_str[before_n++] = "Á´4ºý¤ÎÆâ¤Î4ºýÌܤÎ";
872                 body_str = "ËâË¡½ñ";
873         }
874
875         /*** Items ***/
876         if (IS_FLG(FLG_ITEMS))
877                 ; /* Nothing to do */
878         else if (IS_FLG(FLG_ARTIFACTS))
879                 body_str = "¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È";
880         else if (IS_FLG(FLG_WEAPONS))
881                 body_str = "Éð´ï";
882         else if (IS_FLG(FLG_ARMORS))
883                 body_str = "Ëɶñ";
884         else if (IS_FLG(FLG_MISSILES))
885                 body_str = "ÃƤäÌð¤ä¥¯¥í¥¹¥Ü¥¦¤ÎÌð";
886         else if (IS_FLG(FLG_DEVICES))
887                 body_str = "´¬Êª¤äËâË¡ËÀ¤ä¾ó¤ä¥í¥Ã¥É";
888         else if (IS_FLG(FLG_LIGHTS))
889                 body_str = "¸÷¸»ÍѤΥ¢¥¤¥Æ¥à";
890         else if (IS_FLG(FLG_JUNKS))
891                 body_str = "Àޤ줿ËÀÅù¤Î¥¬¥é¥¯¥¿";
892         else if (IS_FLG(FLG_SPELLBOOKS))
893                 body_str = "ËâË¡½ñ";
894         else if (IS_FLG(FLG_HAFTED))
895                 body_str = "Æß´ï";
896         else if (IS_FLG(FLG_SHIELDS))
897                 body_str = "½â";
898         else if (IS_FLG(FLG_BOWS))
899                 body_str = "¥¹¥ê¥ó¥°¤äµÝ¤ä¥¯¥í¥¹¥Ü¥¦";
900         else if (IS_FLG(FLG_RINGS))
901                 body_str = "»ØÎØ";
902         else if (IS_FLG(FLG_AMULETS))
903                 body_str = "¥¢¥ß¥å¥ì¥Ã¥È";
904         else if (IS_FLG(FLG_SUITS))
905                 body_str = "³»";
906         else if (IS_FLG(FLG_CLOAKS))
907                 body_str = "¥¯¥í¡¼¥¯";
908         else if (IS_FLG(FLG_HELMS))
909                 body_str = "¥Ø¥ë¥á¥Ã¥È¤ä´§";
910         else if (IS_FLG(FLG_GLOVES))
911                 body_str = "¾®¼ê";
912         else if (IS_FLG(FLG_BOOTS))
913                 body_str = "¥Ö¡¼¥Ä";
914
915         *buff = '\0';
916         if (!before_n) 
917                 strcat(buff, "Á´¤Æ¤Î");
918         else for (i = 0; i < before_n && before_str[i]; i++)
919                 strcat(buff, before_str[i]);
920
921         strcat(buff, body_str);
922
923         if (*str)
924         {
925                 if (*str == '^')
926                 {
927                         str++;
928                         top = TRUE;
929                 }
930
931                 strcat(buff, "¤Ç¡¢Ì¾Á°¤¬¡Ö");
932                 strncat(buff, str, 80);
933                 if (top)
934                         strcat(buff, "¡×¤Ç»Ï¤Þ¤ë¤â¤Î");
935                 else
936                         strcat(buff, "¡×¤ò´Þ¤à¤â¤Î");
937         }
938
939         if (insc)
940                 strncat(buff, format("¤Ë¡Ö%s¡×¤È¹ï¤ó¤Ç", insc), 80);
941         else
942                 strcat(buff, "¤ò");
943
944         if (act & DONT_AUTOPICK)
945                 strcat(buff, "ÊüÃÖ¤¹¤ë¡£");
946         else if (act & DO_AUTODESTROY)
947                 strcat(buff, "Ç˲õ¤¹¤ë¡£");
948         else
949                 strcat(buff, "½¦¤¦¡£");
950
951         if (act & DO_DISPLAY)
952         {
953                 if (act & DONT_AUTOPICK)
954                         strcat(buff, "Á´ÂΥޥå×('M')¤Ç'N'¤ò²¡¤·¤¿¤È¤­¤Ëɽ¼¨¤¹¤ë¡£");
955                 else if (act & DO_AUTODESTROY)
956                         strcat(buff, "Á´ÂΥޥå×('M')¤Ç'K'¤ò²¡¤·¤¿¤È¤­¤Ëɽ¼¨¤¹¤ë¡£");
957                 else
958                         strcat(buff, "Á´ÂΥޥå×('M')¤Ç'M'¤ò²¡¤·¤¿¤È¤­¤Ëɽ¼¨¤¹¤ë¡£");
959         }
960         else
961                 strcat(buff, "Á´ÂΥޥåפˤÏɽ¼¨¤·¤Ê¤¤");
962
963 #else /* JP */
964
965         cptr before_str[20], after_str[20], which_str[20], whose_str[20], body_str;
966         int before_n = 0, after_n = 0, which_n = 0, whose_n = 0;
967
968         body_str = "items";
969
970         /*** Collecting items ***/
971         /*** Which can be absorbed into a slot as a bundle ***/
972         if (IS_FLG(FLG_COLLECTING))
973                 which_str[which_n++] = "can be absorbed into an existing inventory slot";
974         
975         /*** Unidentified ***/
976         if (IS_FLG(FLG_UNIDENTIFIED))
977                 before_str[before_n++] = "unidentified";
978
979         /*** Identified ***/
980         if (IS_FLG(FLG_IDENTIFIED))
981                 before_str[before_n++] = "identified";
982
983         /*** *Identified* ***/
984         if (IS_FLG(FLG_STAR_IDENTIFIED))
985                 before_str[before_n++] = "fully identified";
986
987         /*** Nameless ***/
988         if (IS_FLG(FLG_NAMELESS))
989         {
990                 body_str = "equipment";
991                 which_str[which_n++] = "is neither ego-item nor artifact";
992         }
993
994         /*** Unaware items ***/
995         if (IS_FLG(FLG_UNAWARE))
996         {
997                 before_str[before_n++] = "unidentified";
998                 whose_str[whose_n++] = "basic abilities are not known";
999         }
1000
1001         /*** Worthless items ***/
1002         if (IS_FLG(FLG_WORTHLESS))
1003         {
1004                 before_str[before_n++] = "worthless";
1005                 which_str[which_n++] = "can not be sold at stores";
1006         }
1007
1008         /*** Dice boosted (weapon of slaying) ***/
1009         if (IS_FLG(FLG_BOOSTED))
1010         {
1011                 body_str = "weapons";
1012                 whose_str[whose_n++] = "damage dice is bigger than normal";
1013         }
1014
1015         /*** Weapons whic dd*ds is more than nn ***/
1016         if (IS_FLG(FLG_MORE_THAN))
1017         {
1018                 static char more_than_desc_str[] =
1019                         "maximum damage from dice is bigger than __";
1020                 body_str = "weapons";
1021                         
1022                 sprintf(more_than_desc_str + sizeof(more_than_desc_str) - 3,
1023                         "%2d", entry->dice);
1024                 whose_str[whose_n++] = more_than_desc_str;
1025         }
1026
1027         /*** Wanted monster's corpse/skeletons ***/
1028         if (IS_FLG(FLG_WANTED))
1029         {
1030                 body_str = "corpse or skeletons";
1031                 which_str[which_n++] = "is wanted at the Hunter's Office";
1032         }
1033
1034         /*** Human corpse/skeletons (for Daemon magic) ***/
1035         if (IS_FLG(FLG_HUMAN))
1036         {
1037                 before_str[before_n++] = "humanoid";
1038                 body_str = "corpse or skeletons";
1039                 which_str[which_n++] = "can be used for Daemon magic";
1040         }
1041
1042         /*** Unique monster's corpse/skeletons/statues ***/
1043         if (IS_FLG(FLG_UNIQUE))
1044         {
1045                 before_str[before_n++] = "unique monster's";
1046                 body_str = "corpse or skeletons";
1047         }
1048
1049         /*** Unreadable spellbooks ***/
1050         if (IS_FLG(FLG_UNREADABLE))
1051         {
1052                 body_str = "spellbooks";
1053                 after_str[after_n++] = "of different realms from yours";
1054         }
1055
1056         /*** First realm spellbooks ***/
1057         if (IS_FLG(FLG_REALM1))
1058         {
1059                 body_str = "spellbooks";
1060                 after_str[after_n++] = "of your first realm";
1061         }
1062
1063         /*** Second realm spellbooks ***/
1064         if (IS_FLG(FLG_REALM2))
1065         {
1066                 body_str = "spellbooks";
1067                 after_str[after_n++] = "of your second realm";
1068         }
1069
1070         /*** First rank spellbooks ***/
1071         if (IS_FLG(FLG_FIRST))
1072         {
1073                 before_str[before_n++] = "first one of four";
1074                 body_str = "spellbooks";
1075         }
1076
1077         /*** Second rank spellbooks ***/
1078         if (IS_FLG(FLG_SECOND))
1079         {
1080                 before_str[before_n++] = "second one of four";
1081                 body_str = "spellbooks";
1082         }
1083
1084         /*** Third rank spellbooks ***/
1085         if (IS_FLG(FLG_THIRD))
1086         {
1087                 before_str[before_n++] = "third one of four";
1088                 body_str = "spellbooks";
1089         }
1090
1091         /*** Fourth rank spellbooks ***/
1092         if (IS_FLG(FLG_FOURTH))
1093         {
1094                 before_str[before_n++] = "fourth one of four";
1095                 body_str = "spellbooks";
1096         }
1097
1098         /*** Items ***/
1099         if (IS_FLG(FLG_ITEMS))
1100                 ; /* Nothing to do */
1101         else if (IS_FLG(FLG_WEAPONS))
1102                 body_str = "weapons";
1103         else if (IS_FLG(FLG_ARMORS))
1104                 body_str = "armors";
1105         else if (IS_FLG(FLG_MISSILES))
1106                 body_str = "shots, arrows or crossbow bolts";
1107         else if (IS_FLG(FLG_DEVICES))
1108                 body_str = "scrolls, wands, staves or rods";
1109         else if (IS_FLG(FLG_LIGHTS))
1110                 body_str = "light sources";
1111         else if (IS_FLG(FLG_JUNKS))
1112                 body_str = "junk such as broken sticks";
1113         else if (IS_FLG(FLG_SPELLBOOKS))
1114                 body_str = "spellbooks";
1115         else if (IS_FLG(FLG_HAFTED))
1116                 body_str = "hafted weapons";
1117         else if (IS_FLG(FLG_SHIELDS))
1118                 body_str = "shields";
1119         else if (IS_FLG(FLG_BOWS))
1120                 body_str = "slings, bows or crossbows";
1121         else if (IS_FLG(FLG_RINGS))
1122                 body_str = "rings";
1123         else if (IS_FLG(FLG_AMULETS))
1124                 body_str = "amulets";
1125         else if (IS_FLG(FLG_SUITS))
1126                 body_str = "body armors";
1127         else if (IS_FLG(FLG_CLOAKS))
1128                 body_str = "cloaks";
1129         else if (IS_FLG(FLG_HELMS))
1130                 body_str = "helms or crowns";
1131         else if (IS_FLG(FLG_GLOVES))
1132                 body_str = "gloves";
1133         else if (IS_FLG(FLG_BOOTS))
1134                 body_str = "boots";
1135
1136         /* Prepare a string for item name */
1137         if (*str)
1138         {
1139                 if (*str == '^')
1140                 {
1141                         str++;
1142                         top = TRUE;
1143                         whose_str[whose_n++] = "name is beginning with \"";
1144                 }
1145                 else
1146                         which_str[which_n++] = "have \"";
1147         }
1148
1149
1150         /* Describe action flag */
1151         if (act & DONT_AUTOPICK)
1152                 strcpy(buff, "Leave on floor ");
1153         else if (act & DO_AUTODESTROY)
1154                 strcpy(buff, "Destroy ");
1155         else
1156                 strcpy(buff, "Pickup ");
1157
1158         /* Auto-insctiption */
1159         if (insc)
1160                 strncat(buff, format("and inscribe \"%s\" on ", insc), 80);
1161
1162         /* Adjective */
1163         if (!before_n) 
1164                 strcat(buff, "all ");
1165         else for (i = 0; i < before_n && before_str[i]; i++)
1166         {
1167                 strcat(buff, before_str[i]);
1168                 strcat(buff, " ");
1169         }
1170
1171         /* Item class */
1172         strcat(buff, body_str);
1173
1174         /* of ... */
1175         for (i = 0; i < after_n && after_str[i]; i++)
1176         {
1177                 strcat(buff, " ");
1178                 strcat(buff, after_str[i]);
1179         }
1180
1181         /* which ... */
1182         for (i = 0; i < whose_n && whose_str[i]; i++)
1183         {
1184                 if (i == 0)
1185                         strcat(buff, " whose ");
1186                 else
1187                         strcat(buff, ", and ");
1188
1189                 strcat(buff, whose_str[i]);
1190         }
1191
1192         /* Item name ; whose name is beginning with "str" */
1193         if (*str && top)
1194         {
1195                 strcat(buff, str);
1196                 strcat(buff, "\"");
1197         }
1198
1199         /* whose ..., and which .... */
1200         if (whose_n && which_n)
1201                 strcat(buff, ", and ");
1202
1203         /* which ... */
1204         for (i = 0; i < which_n && which_str[i]; i++)
1205         {
1206                 if (i == 0)
1207                         strcat(buff, " which ");
1208                 else
1209                         strcat(buff, ", and ");
1210
1211                 strcat(buff, which_str[i]);
1212         }
1213
1214         /* Item name ; which have "str" as part of its name */
1215         if (*str && !top)
1216         {
1217                 strncat(buff, str, 80);
1218                 strcat(buff, "\" as part of its name");
1219         }
1220         strcat(buff, ".");
1221
1222         /* Describe whether it will be displayed on the full map or not */
1223         if (act & DO_DISPLAY)
1224         {
1225                 if (act & DONT_AUTOPICK)
1226                         strcat(buff, "  Display these items when you press 'N' in the full map('M').");
1227                 else if (act & DO_AUTODESTROY)
1228                         strcat(buff, "  Display these items when you press 'K' in the full map('M').");
1229                 else
1230                         strcat(buff, "  Display these items when you press 'M' in the full map('M').");
1231         }
1232         else
1233                 strcat(buff, " Not displayed in the full map.");
1234 #endif /* JP */
1235
1236 }
1237
1238
1239 #define MAX_LINES 3000
1240
1241 /*
1242  * Read whole lines of a file to memory
1243  */
1244 static cptr *read_text_lines(cptr filename, bool user)
1245 {
1246         cptr *lines_list = NULL;
1247         FILE *fff;
1248
1249         int lines = 0;
1250         char buf[1024];
1251
1252         if (user)
1253         {
1254                 /* Hack -- drop permissions */
1255                 safe_setuid_drop();
1256                 path_build(buf, 1024, ANGBAND_DIR_USER, filename);
1257         }
1258         else
1259         {
1260                 path_build(buf, 1024, ANGBAND_DIR_PREF, filename);
1261         }
1262         
1263         /* Open the file */
1264         fff = my_fopen(buf, "r");
1265
1266         if (fff)
1267         {
1268                 /* Allocate list of pointers */
1269                 C_MAKE(lines_list, MAX_LINES, cptr);
1270
1271                 /* Parse it */
1272                 while (0 == my_fgets(fff, buf, 1024))
1273                 {
1274                         lines_list[lines++] = string_make(buf);
1275                         if (lines >= MAX_LINES - 1) break;
1276                 }
1277                 if (lines == 0)
1278                         lines_list[0] = string_make("");
1279
1280                 my_fclose(fff);
1281         }
1282
1283         /* Grab priv's */
1284         safe_setuid_grab();
1285
1286         if (!fff) return NULL;
1287         return lines_list;
1288 }
1289
1290 static cptr *read_pickpref_text_lines()
1291 {
1292         char buf[1024];
1293         cptr *lines_list;
1294
1295 #ifdef JP
1296         sprintf(buf, "picktype-%s.prf", player_name);
1297 #else
1298         sprintf(buf, "pickpref-%s.prf", player_name);
1299 #endif
1300         lines_list = read_text_lines(buf, TRUE);
1301
1302         if (!lines_list)
1303         {
1304 #ifdef JP
1305                 lines_list = read_text_lines("picktype.prf", TRUE);
1306 #else
1307                 lines_list = read_text_lines("pickpref.prf", TRUE);
1308 #endif
1309         }
1310
1311         if (!lines_list)
1312         {
1313 #ifdef JP
1314                 lines_list = read_text_lines("picktype.prf", FALSE);
1315 #else
1316                 lines_list = read_text_lines("pickpref.prf", FALSE);
1317 #endif
1318         }
1319
1320         if (!lines_list)
1321         {
1322                 /* Allocate list of pointers */
1323                 C_MAKE(lines_list, MAX_LINES, cptr);
1324                 lines_list[0] = string_make("");
1325         }
1326         return lines_list;
1327 }
1328
1329 /*
1330  * Write whole lines of memory to a file.
1331  */
1332 static bool write_text_lines(cptr filename, cptr *lines_list)
1333 {
1334         FILE *fff;
1335
1336         int lines = 0;
1337         char buf[1024];
1338
1339         /* Hack -- drop permissions */
1340         safe_setuid_drop();
1341
1342         /* Build the filename */
1343         path_build(buf, 1024, ANGBAND_DIR_USER, filename);
1344         
1345         /* Open the file */
1346         fff = my_fopen(buf, "w");
1347         if (fff)
1348         {
1349                 for (lines = 0; lines_list[lines]; lines++)
1350                         my_fputs(fff, lines_list[lines], 1024);
1351
1352                 my_fclose(fff);
1353         }
1354
1355         /* Grab priv's */
1356         safe_setuid_grab();
1357
1358         if (!fff) return FALSE;
1359         return TRUE;
1360 }
1361
1362
1363 /*
1364  * Free memory of lines_list.
1365  */
1366 static void free_text_lines(cptr *lines_list)
1367 {
1368         int lines;
1369
1370         for (lines = 0; lines_list[lines]; lines++)
1371                 string_free(lines_list[lines]);
1372
1373         /* free list of pointers */
1374         C_FREE((char **)lines_list, MAX_LINES, char *);
1375 }
1376
1377
1378 /*
1379  * Insert string
1380  */
1381 static void insert_string(cptr *lines_list, cptr str, int x, int y)
1382 {
1383         char buf[1024];
1384         int i, j;
1385
1386         for (i = j = 0; lines_list[y][i] && i < x; i++)
1387                 buf[j++] = lines_list[y][i];
1388
1389         while (*str) buf[j++] = *str++;
1390
1391         for (; lines_list[y][i]; i++)
1392                 buf[j++] = lines_list[y][i];
1393         buf[j] = '\0';
1394         string_free(lines_list[y]);
1395         lines_list[y] = string_make(buf);
1396 }
1397
1398 /*
1399  * Delete n letters
1400  */
1401 static void delete_string(cptr *lines_list, int n, int x, int y)
1402 {
1403         int i, j;
1404         char buf[1024];
1405
1406         for (i = j = 0; lines_list[y][i] && i < x; i++)
1407         {
1408 #ifdef JP
1409                 if (iskanji(lines_list[y][i]))
1410                         buf[j++] = lines_list[y][i++];
1411 #endif
1412                 buf[j++] = lines_list[y][i];
1413         }
1414         i += n;
1415
1416         for (; lines_list[y][i]; i++)
1417                 buf[j++] = lines_list[y][i];
1418         buf[j] = '\0';
1419         string_free(lines_list[y]);
1420         lines_list[y] = string_make(buf);
1421 }
1422
1423
1424 /*
1425  * Delete or insert string
1426  */
1427 void toggle_string(cptr *lines_list, int flg, int y)
1428 {
1429         autopick_type an_entry, *entry = &an_entry;
1430
1431         if (!autopick_new_entry(entry, lines_list[y]))
1432                 return;
1433
1434         string_free(lines_list[y]);
1435         if (IS_FLG(flg)) 
1436                 REM_FLG(flg);
1437         else
1438                 ADD_FLG(flg);
1439
1440         lines_list[y] = autopick_line_from_entry(entry);
1441 }
1442
1443 /*
1444  * Insert return code and split the line
1445  */
1446 static bool insert_return_code(cptr *lines_list, int cx, int cy)
1447 {
1448         char buf[1024];
1449         int i, j, k;
1450
1451         for (k = 0; lines_list[k]; k++)
1452                 /* count number of lines */ ;
1453
1454         if (k >= MAX_LINES - 2) return FALSE;
1455         k--;
1456
1457         /* Move down lines */
1458         for (; cy < k; k--)
1459                 lines_list[k+1] = lines_list[k];
1460
1461         /* Split current line */
1462         for (i = j = 0; lines_list[cy][i] && i < cx; i++)
1463         {
1464 #ifdef JP
1465                 if (iskanji(lines_list[cy][i]))
1466                         buf[j++] = lines_list[cy][i++];
1467 #endif
1468                 buf[j++] = lines_list[cy][i];
1469         }
1470         buf[j] = '\0';
1471         lines_list[cy+1] = string_make(&lines_list[cy][i]);
1472         string_free(lines_list[cy]);
1473         lines_list[cy] = string_make(buf);
1474         return TRUE;
1475 }
1476
1477
1478 /*
1479  * Get auto-picker entry from o_ptr.
1480  */
1481 void autopick_entry_from_object(autopick_type *entry, object_type *o_ptr)
1482 {
1483         char o_name[MAX_NLEN];
1484         object_desc(o_name, o_ptr, FALSE, 0);
1485
1486         entry->name = string_make(o_name);
1487         entry->insc = string_make(quark_str(o_ptr->inscription));
1488         entry->action = DO_AUTOPICK | DO_DISPLAY;
1489         entry->flag[0] = entry->flag[1] = 0L;
1490         entry->dice = 0;
1491
1492         if (!object_aware_p(o_ptr))
1493                 ADD_FLG(FLG_UNAWARE);
1494         if (object_value(o_ptr) <= 0)
1495                 ADD_FLG(FLG_WORTHLESS);
1496
1497         switch(o_ptr->tval)
1498         {
1499                 object_kind *k_ptr; 
1500         case TV_HAFTED: case TV_POLEARM: case TV_SWORD: case TV_DIGGING:
1501                 k_ptr = &k_info[o_ptr->k_idx];
1502                 if ((o_ptr->dd != k_ptr->dd) || (o_ptr->ds != k_ptr->ds))
1503                         ADD_FLG(FLG_BOOSTED);
1504         }
1505
1506         if (o_ptr->tval == TV_CORPSE && object_is_shoukinkubi(o_ptr))
1507         {
1508                 REM_FLG(FLG_WORTHLESS);
1509                 ADD_FLG(FLG_WANTED);
1510         }
1511
1512         if ((o_ptr->tval == TV_CORPSE || o_ptr->tval == TV_STATUE)
1513             && (r_info[o_ptr->pval].flags1 & RF1_UNIQUE))
1514         {
1515                 REM_FLG(FLG_WORTHLESS);
1516                 ADD_FLG(FLG_UNIQUE);
1517         }
1518
1519         if (o_ptr->tval == TV_CORPSE && strchr("pht", r_info[o_ptr->pval].d_char))
1520         {
1521                 REM_FLG(FLG_WORTHLESS);
1522                 ADD_FLG(FLG_HUMAN);
1523         }
1524
1525         if (o_ptr->tval >= TV_LIFE_BOOK &&
1526             !check_book_realm(o_ptr->tval, o_ptr->sval))
1527                 ADD_FLG(FLG_UNREADABLE);
1528
1529         if (REALM1_BOOK == o_ptr->tval &&
1530             p_ptr->pclass != CLASS_SORCERER &&
1531             p_ptr->pclass != CLASS_RED_MAGE)
1532                 ADD_FLG(FLG_REALM1);
1533
1534         if (REALM2_BOOK == o_ptr->tval &&
1535             p_ptr->pclass != CLASS_SORCERER &&
1536             p_ptr->pclass != CLASS_RED_MAGE)
1537                 ADD_FLG(FLG_REALM2);
1538
1539         if (o_ptr->tval >= TV_LIFE_BOOK && 0 == o_ptr->sval)
1540                 ADD_FLG(FLG_FIRST);
1541         if (o_ptr->tval >= TV_LIFE_BOOK && 1 == o_ptr->sval)
1542                 ADD_FLG(FLG_SECOND);
1543         if (o_ptr->tval >= TV_LIFE_BOOK && 2 == o_ptr->sval)
1544                 ADD_FLG(FLG_THIRD);
1545         if (o_ptr->tval >= TV_LIFE_BOOK && 3 == o_ptr->sval)
1546                 ADD_FLG(FLG_FOURTH);
1547
1548         if (object_known_p(o_ptr) && (artifact_p(o_ptr) || o_ptr->art_name))
1549                 ADD_FLG(FLG_ARTIFACTS);
1550         
1551         else if (o_ptr->tval == TV_SHOT || o_ptr->tval == TV_BOLT
1552                  || o_ptr->tval == TV_ARROW)
1553                 ADD_FLG(FLG_MISSILES);
1554         else if (o_ptr->tval == TV_SCROLL || o_ptr->tval == TV_STAFF
1555                  || o_ptr->tval == TV_WAND || o_ptr->tval == TV_ROD)
1556                 ADD_FLG(FLG_DEVICES);
1557         else if (o_ptr->tval == TV_LITE)
1558                 ADD_FLG(FLG_LIGHTS);
1559         else if (o_ptr->tval == TV_SKELETON || o_ptr->tval == TV_BOTTLE
1560                  || o_ptr->tval == TV_JUNK || o_ptr->tval == TV_STATUE)
1561                 ADD_FLG(FLG_JUNKS);
1562         else if (o_ptr->tval >= TV_LIFE_BOOK)
1563                 ADD_FLG(FLG_SPELLBOOKS);
1564         else if (o_ptr->tval == TV_HAFTED)
1565                 ADD_FLG(FLG_HAFTED);
1566         else if (o_ptr->tval == TV_POLEARM || o_ptr->tval == TV_SWORD
1567                  || o_ptr->tval == TV_DIGGING)
1568                 ADD_FLG(FLG_WEAPONS);
1569         else if (o_ptr->tval == TV_SHIELD)
1570                 ADD_FLG(FLG_SHIELDS);
1571         else if (o_ptr->tval == TV_BOW)
1572                 ADD_FLG(FLG_BOWS);
1573         else if (o_ptr->tval == TV_RING)
1574                 ADD_FLG(FLG_RINGS);
1575         else if (o_ptr->tval == TV_AMULET)
1576                 ADD_FLG(FLG_AMULETS);
1577         else if (o_ptr->tval == TV_DRAG_ARMOR || o_ptr->tval == TV_HARD_ARMOR ||
1578                  o_ptr->tval == TV_SOFT_ARMOR)
1579                 ADD_FLG(FLG_SUITS);
1580         else if (o_ptr->tval == TV_CLOAK)
1581                 ADD_FLG(FLG_CLOAKS);
1582         else if (o_ptr->tval == TV_HELM)
1583                 ADD_FLG(FLG_HELMS);
1584         else if (o_ptr->tval == TV_GLOVES)
1585                 ADD_FLG(FLG_GLOVES);
1586         else if (o_ptr->tval == TV_BOOTS)
1587                 ADD_FLG(FLG_BOOTS);
1588
1589         return;
1590 }
1591
1592 /*
1593  * Choose an item and get auto-picker entry from it.
1594  */
1595 static bool entry_from_object(autopick_type *entry)
1596 {
1597         int item;
1598         object_type *o_ptr;
1599         cptr q, s;
1600
1601         /* Get an item */
1602 #ifdef JP
1603         q = "¤É¤Î¥¢¥¤¥Æ¥à¤òÅÐÏ¿¤·¤Þ¤¹¤«? ";
1604         s = "¥¢¥¤¥Æ¥à¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¡£";
1605 #else
1606         q = "Entry which item? ";
1607         s = "You have nothing to entry.";
1608 #endif
1609         if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EQUIP))) return FALSE;
1610
1611         /* Get the item (in the pack) */
1612         if (item >= 0)
1613         {
1614                 o_ptr = &inventory[item];
1615         }
1616
1617         /* Get the item (on the floor) */
1618         else
1619         {
1620                 o_ptr = &o_list[0 - item];
1621         }
1622
1623         autopick_entry_from_object(entry, o_ptr);
1624         return TRUE;
1625 }
1626
1627
1628 /*
1629  * Description of control commands
1630  */
1631
1632 #define WID_DESC 31
1633
1634 static cptr ctrl_command_desc[] =
1635 {
1636 #ifdef JP
1637 #define LAST_DESTROYED 6
1638         "^P ^N ^B ^F ¾å²¼º¸±¦¤Ë°ÜÆ°",
1639         "^A ^E ¹Ô¤ÎÀèƬ¡¢½ªÃ¼",
1640         "^Q ÆþÎÏ/¥³¥Þ¥ó¥É¥â¡¼¥ÉÀÚ¤êÂؤ¨",
1641         "^R Êѹ¹¤òÁ´¤Æ¼è¤ê¾Ã¤·¤Æ¸µ¤ËÌ᤹",
1642         "------------------------------------",
1643         "^I »ý¤Áʪ/ÁõÈ÷¤«¤éÁªÂò",
1644         "^L",
1645         "^K ¥«¡¼¥½¥ë¤«¤é½ªÃ¼¤Þ¤Çºï½ü",
1646         "^Y ºï½ü(^K)¤·¤¿¹Ô¤òÁÞÆþ",
1647         "^C ¼ï²¡¢¿¦¶È¤Î¾ò·ï¼°¤òÁÞÆþ",
1648         "------------------------------------",
1649         "^S Êѹ¹ (!Ç˲õ/~ÊüÃÖ/½¦¤¦)",
1650         "^G \"(\" Á´ÂΥޥåפÇɽ¼¨¤·¤Ê¤¤",
1651         "^O \"#\" ¼«Æ°¹ï¤ß",
1652         "------------------------------------",
1653         "^U Ì¤´ÕÄê/̤ȽÌÀ/´ÕÄê/*´ÕÄê*",
1654         "^W \"̵²ÁÃͤÎ\"",
1655         "^X \"̵ÌäÎ\"",
1656         "^Z \"¼ý½¸Ãæ¤Î\"",
1657         NULL
1658 #else
1659 #define LAST_DESTROYED 6
1660         "^P ^N ^B ^F Move Cursor",
1661         "^A ^E Beginning and End of Line",
1662         "^Q Toggle Insert/Command mode",
1663         "^R Revert to Original File",
1664         "------------------------------------",
1665         "^I Object in Inventry/Equipment",
1666         "^L",
1667         "^K Kill Rest of Line",
1668         "^Y Insert killed(^K) text",
1669         "^C Insert conditional expression",
1670         "------------------------------------",
1671         "^S Toggle(!Destroy/~Leave/Pick)",
1672         "^G \"(\" No display in the 'M'ap",
1673         "^O \"#\" Auto-Inscribe",
1674         "------------------------------------",
1675         "^U Toggle 'identified' state",
1676         "^W \"worthless\"",
1677         "^X \"nameless\"",
1678         "^Z \"collecting\"",
1679         NULL
1680 #endif
1681 };
1682
1683
1684 #define MAX_YANK 1024
1685
1686 /*
1687  * In-game editor of Object Auto-picker/Destoryer
1688  */
1689 void do_cmd_edit_autopick()
1690 {
1691         static int cx = 0, cy = 0;
1692         static int upper = 0, left = 0;
1693
1694         cptr last_destroyed;
1695         char last_destroyed_command[WID_DESC+3];
1696         char yank_buf[MAX_YANK];
1697         char classrace[80];
1698         autopick_type an_entry, *entry = &an_entry;
1699         char buf[1024];
1700         cptr *lines_list;
1701
1702         int i, j, k, len;
1703         cptr tmp;
1704
1705         int old_upper = -1, old_left = -1;
1706         int old_cy = -1;
1707         int key = -1, old_key;
1708
1709         bool edit_mode = FALSE;
1710         int dirty_line = -2;
1711
1712         int wid, hgt, old_wid = -1, old_hgt = -1;
1713
1714         /* Name of the Last Destroyed Item */
1715         last_destroyed = autopick_line_from_entry(&autopick_entry_last_destroyed);
1716
1717         /* Command Description of the Last Destroyed Item */
1718         if (last_destroyed)
1719         {
1720                 strcpy(last_destroyed_command, "^L \"");
1721                 strncpy(last_destroyed_command + 4, last_destroyed, WID_DESC-4);
1722                 last_destroyed_command[WID_DESC+2] = '\0';
1723         }
1724         else
1725         {
1726 #ifdef JP
1727                 strcpy(last_destroyed_command, "^L ºÇ¸å¤Ë¼«Æ°Ç˲õ¤·¤¿¥¢¥¤¥Æ¥à̾");
1728 #else
1729                 strcpy(last_destroyed_command, "^L Last destroyed object");
1730 #endif
1731         }
1732         ctrl_command_desc[LAST_DESTROYED] = last_destroyed_command;
1733
1734         /* Conditional Expression for Class and Race */
1735         sprintf(classrace, "?:[AND [EQU $RACE %s] [EQU $CLASS %s]]", 
1736 #ifdef JP
1737                 rp_ptr->E_title, cp_ptr->E_title
1738 #else
1739                 rp_ptr->title, cp_ptr->title
1740 #endif
1741                 );
1742
1743         /* Clear yank buffer */
1744         yank_buf[0] = '\0';
1745
1746         lines_list = read_pickpref_text_lines();
1747
1748         /* Reset cursor position if needed */
1749         for (i = 0; i < cy; i++)
1750         {
1751                 if (!lines_list[i])
1752                 {
1753                         cy = cx = 0;
1754                         break;
1755                 }
1756         }
1757
1758         /* Save the screen */
1759         screen_save();
1760
1761         /* Clear screen */
1762         Term_clear();
1763
1764         /* Process requests until done */
1765         while (1)
1766         {
1767                 /* Get size */
1768                 Term_get_size(&wid, &hgt);
1769
1770 #ifdef JP
1771                 for (i = 0; lines_list[cy][i]; i++)
1772                         if (iskanji(lines_list[cy][i]))
1773                         {
1774                                 i++;
1775                                 if (i == cx)
1776                                 {
1777                                         cx--;
1778                                         break;
1779                                 }
1780                         }
1781 #endif
1782
1783                 if (cy < upper || upper + hgt - 4 <= cy)
1784                         upper = cy - (hgt-4)/2;
1785                 if (upper < 0)
1786                         upper = 0;
1787                 if ((cx < left + 10 && left > 0) || left + wid - WID_DESC - 5 <= cx)
1788                         left = cx - (wid - WID_DESC)*2/3;
1789                 if (left < 0)
1790                         left = 0;
1791
1792                 if (old_upper != upper || old_left != left || 
1793                     old_wid != wid || old_hgt != hgt)
1794                         dirty_line = -2;
1795
1796                 if (dirty_line != -1)
1797                 {
1798                         int sepa_length = wid - WID_DESC;
1799
1800                         /* Separator */
1801                         for (i = 0; i < sepa_length; i++)
1802                                 buf[i] = '-';
1803                         buf[i] = '\0';
1804
1805                         /* Mode line */
1806                         if (edit_mode)
1807                                 strncpy(buf + sepa_length - 21, " (INSERT MODE)  ", 16);
1808                         else
1809                                 strncpy(buf + sepa_length - 21, " (COMMAND MODE) ", 16);
1810
1811                         prt(buf, hgt - 3, 0);
1812
1813                         /* Display control command */
1814                         for (i = 0; ctrl_command_desc[i]; i++)
1815                                 prt(ctrl_command_desc[i], i + 1, wid - WID_DESC);
1816                 }
1817
1818                 /* Dump up to 20 lines of messages */
1819                 for (i = 0; i < hgt - 4; i++)
1820                 {
1821                         int leftcol = 0;
1822                         cptr msg;
1823
1824                         /* clean or dirty? */
1825                         if (dirty_line != -2 && dirty_line != upper+i)
1826                                 continue;
1827
1828                         msg = lines_list[upper+i];
1829                         if (!msg) break;
1830
1831                         /* Apply horizontal scroll */
1832                         for (j = 0; *msg; msg++, j++)
1833                         {
1834                                 if (j == left) break;
1835 #ifdef JP
1836                                 if (j > left)
1837                                 {
1838                                         leftcol = 1;
1839                                         break;
1840                                 }
1841                                 if (iskanji(*msg))
1842                                 {
1843                                         msg++;
1844                                         j++;
1845                                 }
1846 #endif
1847                         }
1848
1849                         /* Erase line */
1850                         Term_erase(0, i + 1, wid - WID_DESC);
1851
1852                         /* Dump the messages, bottom to top */
1853                         Term_putstr(leftcol, i + 1, wid - WID_DESC - 1, TERM_WHITE, msg);
1854                 }
1855
1856                 for (; i < hgt - 4; i++)
1857                 {
1858                         /* Erase line */
1859                         Term_erase(0, i + 1, wid - WID_DESC);
1860                 }
1861
1862                 /* Display header XXX XXX XXX */
1863 #ifdef JP
1864                 if (edit_mode)
1865                         prt("^Q ESC ¤Ç¥³¥Þ¥ó¥É¥â¡¼¥É¤Ø°Ü¹Ô¡¢Ä̾ï¤Îʸ»ú¤Ï¤½¤Î¤Þ¤ÞÆþÎÏ", 0, 0);
1866                 else
1867                         prt("q _ ¤Ç½ªÎ»¡¢hjkl2468 ¤Ç°ÜÆ°¡¢^Q a i ¤ÇÆþÎϥ⡼¥É", 0, 0);
1868 #else   
1869                 if (edit_mode)
1870                         prt("Press ^Q ESC to command mode, any letters to insert", 0, 0);
1871                 else
1872                         prt("Press q _ to quit, hjkl2468 to move, ^Q a i to insert mode", 0, 0);
1873 #endif
1874                 /* Display current position */
1875                 prt (format("(%d,%d)", cx, cy), 0, 70);
1876
1877                 /* Display information when updated */
1878                 if (old_cy != cy || dirty_line == -2 || dirty_line == cy)
1879                 {
1880                         /* Clear information line */
1881                         prt("", hgt - 3 + 1, 0);
1882                         prt("", hgt - 3 + 2, 0);
1883
1884                         /* Display information */
1885                         if (lines_list[cy][0] == '#')
1886                         {
1887 #ifdef JP
1888                                 prt("¤³¤Î¹Ô¤Ï¥³¥á¥ó¥È¤Ç¤¹¡£", hgt - 3 + 1, 0);
1889 #else
1890                                 prt("This line is comment.", hgt - 3 + 1, 0);
1891 #endif
1892                         }
1893                         else if (lines_list[cy][1] == ':')
1894                         {
1895                                 switch(lines_list[cy][0])
1896                                 {
1897                                 case '?':
1898 #ifdef JP
1899                                         prt("¤³¤Î¹Ô¤Ï¾ò·ïʬ´ô¼°¤Ç¤¹¡£", hgt - 3 + 1, 0);
1900 #else
1901                                         prt("This line is Conditional Expression.", hgt - 3 + 1, 0);
1902 #endif
1903                                         break;
1904                                 case 'A':
1905 #ifdef JP
1906                                         prt("¤³¤Î¹Ô¤Ï¥Þ¥¯¥í¤Î¼Â¹ÔÆâÍƤòÄêµÁ¤·¤Þ¤¹¡£", hgt - 3 + 1, 0);
1907 #else
1908                                         prt("This line defines Macro action.", hgt - 3 + 1, 0);
1909 #endif
1910                                         break;
1911                                 case 'P':
1912 #ifdef JP
1913                                         prt("¤³¤Î¹Ô¤Ï¥Þ¥¯¥í¤Î¥È¥ê¥¬¡¼¡¦¥­¡¼¤òÄêµÁ¤·¤Þ¤¹¡£", hgt - 3 + 1, 0);
1914 #else
1915                                         prt("This line defines Macro trigger key.", hgt - 3 + 1, 0);
1916 #endif
1917                                         break;
1918                                 case 'C':
1919 #ifdef JP
1920                                         prt("¤³¤Î¹Ô¤Ï¥­¡¼ÇÛÃÖ¤òÄêµÁ¤·¤Þ¤¹¡£", hgt - 3 + 1, 0);
1921 #else
1922                                         prt("This line defines Keymap.", hgt - 3 + 1, 0);
1923 #endif
1924                                         break;
1925                                 }
1926                         }
1927                         else if (autopick_new_entry(entry, lines_list[cy]))
1928                         {
1929                                 char temp[80*4];
1930                                 cptr t;
1931
1932                                 describe_autopick(buf, entry);
1933
1934                                 roff_to_buf(buf, 79, temp);
1935                                 t = temp;
1936                                 for (i = 0; i< 2; i++)
1937                                 {
1938                                         if(t[0] == 0)
1939                                                 break; 
1940                                         else
1941                                         {
1942                                                 prt(t, hgt - 3 + 1 + i, 0);
1943                                                 t += strlen(t) + 1;
1944                                         }
1945                                 }
1946                                 autopick_free_entry(entry);
1947                         }
1948                 }
1949
1950                 /* Place cursor */
1951                 Term_gotoxy(cx - left, cy - upper + 1);
1952
1953                 /* Now clean */
1954                 dirty_line = -1;
1955
1956                 /* Save old key and location */
1957                 old_cy = cy;
1958                 old_key = key;
1959                 old_upper = upper;
1960                 old_left = left;
1961                 old_wid = wid;
1962                 old_hgt = hgt;
1963
1964                 /* Do not process macros except special keys */
1965                 inkey_special = TRUE;
1966
1967                 /* Get a command */
1968                 key = inkey();
1969
1970                 if (edit_mode)
1971                 {
1972                         if (key == ESCAPE)
1973                         {
1974                                 edit_mode = FALSE;
1975
1976                                 /* Mode line is now dirty */
1977                                 dirty_line = -3;
1978                         }
1979                         else if (!iscntrl(key&0xff))
1980                         {
1981                                 int next;
1982
1983                                 for (i = j = 0; lines_list[cy][i] && i < cx; i++)
1984                                         buf[j++] = lines_list[cy][i];
1985
1986 #ifdef JP
1987                                 if (iskanji(key))
1988                                 {
1989                                         inkey_base = TRUE;
1990                                         next = inkey();
1991                                         if (j+2 < 1024)
1992                                         {
1993                                                 buf[j++] = key;
1994                                                 buf[j++] = next;
1995                                                 cx += 2;
1996                                         }
1997                                         else
1998                                                 bell();
1999                                 }
2000                                 else
2001 #endif
2002                                 {
2003                                         if (j+1 < 1024)
2004                                                 buf[j++] = key;
2005                                         cx++;
2006                                 }
2007                                 for (; lines_list[cy][i] && j + 1 < 1024; i++)
2008                                         buf[j++] = lines_list[cy][i];
2009                                 buf[j] = '\0';
2010                                 string_free(lines_list[cy]);
2011                                 lines_list[cy] = string_make(buf);
2012                                 len = strlen(lines_list[cy]);
2013                                 if (len < cx) cx = len;
2014
2015                                 /* Now dirty */
2016                                 dirty_line = cy;
2017                         }
2018                 }
2019                 else
2020                 {
2021                         /* Exit on 'q' */
2022                         if (key == 'q' || key == '_') break;
2023
2024                         switch(key)
2025                         {
2026                         case 'a': case 'i':
2027                                 edit_mode = TRUE;
2028
2029                                 /* Mode line is now dirty */
2030                                 dirty_line = -3;
2031                                 break;
2032                         case '~':
2033                                 if (!autopick_new_entry(entry, lines_list[cy]))
2034                                         break;
2035                                 string_free(lines_list[cy]);
2036
2037                                 entry->action &= ~DO_AUTODESTROY;
2038                                 if (entry->action & DO_AUTOPICK)
2039                                 {
2040                                         entry->action &= ~DO_AUTOPICK;
2041                                         entry->action |= DONT_AUTOPICK;
2042                                 }
2043                                 else 
2044                                 {
2045                                         entry->action &= ~DONT_AUTOPICK;
2046                                         entry->action |= DO_AUTOPICK;
2047                                 }
2048
2049                                 lines_list[cy] = autopick_line_from_entry(entry);
2050
2051                                 /* Now dirty */
2052                                 dirty_line = cy;
2053                                 break;
2054                         case '!':
2055                                 if (!autopick_new_entry(entry, lines_list[cy]))
2056                                         break;
2057                                 string_free(lines_list[cy]);
2058
2059                                 entry->action &= ~DONT_AUTOPICK;
2060                                 if (entry->action & DO_AUTOPICK)
2061                                 {
2062                                         entry->action &= ~DO_AUTOPICK;
2063                                         entry->action |= DO_AUTODESTROY;
2064                                 }
2065                                 else 
2066                                 {
2067                                         entry->action &= ~DO_AUTODESTROY;
2068                                         entry->action |= DO_AUTOPICK;
2069                                 }
2070
2071                                 lines_list[cy] = autopick_line_from_entry(entry);
2072
2073                                 /* Now dirty */
2074                                 dirty_line = cy;
2075                                 break;
2076                         case '(':
2077                                 key = KTRL('g');
2078                                 break;
2079                         case '#':
2080                         case '{':
2081                                 key = KTRL('o');
2082                                 break;
2083                         case 'h': case '4':
2084                                 key = KTRL('b');
2085                                 break;
2086                         case 'l': case '6':
2087                                 key = KTRL('f');
2088                                 break;
2089                         case 'j': case '2':
2090                                 key = KTRL('n');
2091                                 break;
2092                         case 'k': case '8':
2093                                 key = KTRL('p');
2094                                 break;
2095                         case ' ':
2096                                 while (cy < upper + hgt-4 && lines_list[cy + 1])
2097                                         cy++;
2098                                 upper = cy;
2099                                 break;
2100                         case '-': case 'b':
2101                                 while (0 < cy && upper <= cy)
2102                                         cy--;
2103                                 while (0 < upper && cy + 1 < upper + hgt - 4)
2104                                         upper--;
2105                                 break;
2106                         }
2107                 }
2108
2109                 switch(key)
2110                 {
2111                 case KTRL('a'):
2112                         cx = 0;
2113                         break;
2114                 case KTRL('b'):
2115                         if (0 < cx)
2116                         {
2117                                 cx--;
2118                                 len = strlen(lines_list[cy]);
2119                                 if (len < cx) cx = len;
2120                         }
2121                         else if (cy > 0)
2122                         {
2123                                 cy--;
2124                                 cx = strlen(lines_list[cy]);
2125                         }
2126                         break;
2127                 case KTRL('c'):
2128                         insert_return_code(lines_list, 0, cy);
2129                         lines_list[cy] = string_make(classrace);
2130                         cy++;
2131                         insert_return_code(lines_list, 0, cy);
2132                         lines_list[cy] = string_make("?:1");
2133                         cx = 0;
2134
2135                         /* Now dirty */
2136                         dirty_line = -2;
2137                         break;
2138                 case KTRL('e'):
2139                         cx = strlen(lines_list[cy]);
2140                         break;
2141                 case KTRL('f'):
2142 #ifdef JP
2143                         if (iskanji(lines_list[cy][cx])) cx++;
2144 #endif
2145                         cx++;
2146                         len = strlen(lines_list[cy]);
2147                         if (len < cx)
2148                         {
2149                                 if (lines_list[cy + 1])
2150                                 {
2151                                         cy++;
2152                                         cx = 0;
2153                                 }
2154                                 else
2155                                         cx = len;
2156                         }
2157                         break;
2158                 case KTRL('g'):
2159                         if (lines_list[cy][0] != '(' && lines_list[cy][1] != '(')
2160                                 insert_string(lines_list, "(", 0, cy);
2161                         else if (lines_list[cy][0] == '(')
2162                                 delete_string(lines_list, 1, 0, cy);
2163                         else if (lines_list[cy][1] == '(')
2164                                 delete_string(lines_list, 1, 1, cy);
2165
2166                         /* Now dirty */
2167                         dirty_line = cy;
2168                         break;
2169                 case KTRL('i'):
2170                         if (!entry_from_object(entry))
2171                         {
2172                                 dirty_line = -2;
2173                                 break;
2174                         }
2175                         tmp = autopick_line_from_entry(entry);
2176                         autopick_free_entry(entry);
2177                         if (tmp)
2178                         {
2179                                 insert_return_code(lines_list, 0, cy);
2180                                 lines_list[cy] = tmp;
2181                                 cx = 0;
2182
2183                                 /* Now dirty */
2184                                 dirty_line = -2;
2185                         }
2186                         break;
2187                 case KTRL('l'):
2188                         if (last_destroyed)
2189                         {
2190                                 insert_return_code(lines_list, 0, cy);
2191                                 lines_list[cy] = string_make(last_destroyed);
2192                                 cx = 0;
2193
2194                                 /* Now dirty */
2195                                 dirty_line = -2;
2196                         }
2197                         break;
2198                 case '\n': case '\r':
2199                         insert_return_code(lines_list, cx, cy);
2200                         cy++;
2201                         cx = 0;
2202
2203                         /* Now dirty */
2204                         dirty_line = -2;
2205                         break;
2206                 case KTRL('n'):
2207                         if (lines_list[cy + 1]) cy++;
2208                         break;
2209                 case KTRL('o'):
2210                         for (i = 0; lines_list[cy][i]; i++)
2211                                 if (lines_list[cy][i] == '#') break;
2212                         if (!lines_list[cy][i]) insert_string(lines_list, "#", i, cy);
2213                         cx = i + 1;
2214                         edit_mode = TRUE;
2215
2216                         /* Now dirty */
2217                         dirty_line = cy;
2218                         break;
2219                 case KTRL('p'):
2220                         if (cy > 0) cy--;
2221                         break;
2222                 case KTRL('q'):
2223                         edit_mode = !edit_mode;
2224                         
2225                         /* Mode line is now dirty */
2226                         dirty_line = -3;
2227                         break;
2228                 case KTRL('r'):
2229 #ifdef JP
2230                         if (!get_check("Á´¤Æ¤ÎÊѹ¹¤òÇË´þ¤·¤Æ¸µ¤Î¾õÂÖ¤ËÌᤷ¤Þ¤¹¡£¤è¤í¤·¤¤¤Ç¤¹¤«¡© "))
2231 #else
2232                         if (!get_check("Discard all change and revert to original file. Are you sure? "))
2233 #endif
2234                                 break;
2235
2236                         free_text_lines(lines_list);
2237                         lines_list = read_pickpref_text_lines();
2238                         dirty_line = -2;
2239                         cx = cy = 0;
2240                         edit_mode = FALSE;
2241                         break;
2242                 case KTRL('s'):
2243                         if (!autopick_new_entry(entry, lines_list[cy]))
2244                                 break;
2245                         string_free(lines_list[cy]);
2246
2247                         if (entry->action & DO_AUTOPICK)
2248                         {
2249                                 entry->action &= ~DO_AUTOPICK;
2250                                 entry->action |= DO_AUTODESTROY;
2251                         }
2252                         else if (entry->action & DO_AUTODESTROY)
2253                         {
2254                                 entry->action &= ~DO_AUTODESTROY;
2255                                 entry->action |= DONT_AUTOPICK;
2256                         }
2257                         else if (entry->action & DONT_AUTOPICK)
2258                         {
2259                                 entry->action &= ~DONT_AUTOPICK;
2260                                 entry->action |= DO_AUTOPICK;
2261                         }
2262
2263                         lines_list[cy] = autopick_line_from_entry(entry);
2264                         /* Now dirty */
2265                         dirty_line = cy;
2266
2267                         break;
2268                 case KTRL('t'):
2269                         break;
2270                 case KTRL('u'):
2271                         if (!autopick_new_entry(entry, lines_list[cy]))
2272                                 break;
2273                         string_free(lines_list[cy]);
2274
2275                         if (IS_FLG(FLG_UNIDENTIFIED)) 
2276                         {
2277                                 REM_FLG(FLG_UNIDENTIFIED);
2278                                 ADD_FLG(FLG_UNAWARE);
2279                                 REM_FLG(FLG_IDENTIFIED);
2280                                 REM_FLG(FLG_STAR_IDENTIFIED);
2281                         }
2282                         else if (IS_FLG(FLG_UNAWARE)) 
2283                         {
2284                                 REM_FLG(FLG_UNIDENTIFIED);
2285                                 REM_FLG(FLG_UNAWARE);
2286                                 ADD_FLG(FLG_IDENTIFIED);
2287                                 REM_FLG(FLG_STAR_IDENTIFIED);
2288                         }
2289                         else if (IS_FLG(FLG_STAR_IDENTIFIED)) 
2290                         {
2291                                 REM_FLG(FLG_UNIDENTIFIED);
2292                                 REM_FLG(FLG_UNAWARE);
2293                                 REM_FLG(FLG_IDENTIFIED);
2294                                 REM_FLG(FLG_STAR_IDENTIFIED);
2295                         }
2296                         else if (IS_FLG(FLG_IDENTIFIED)) 
2297                         {
2298                                 REM_FLG(FLG_UNIDENTIFIED);
2299                                 REM_FLG(FLG_UNAWARE);
2300                                 REM_FLG(FLG_IDENTIFIED);
2301                                 ADD_FLG(FLG_STAR_IDENTIFIED);
2302                         }
2303                         else
2304                         {
2305                                 ADD_FLG(FLG_UNIDENTIFIED);
2306                                 REM_FLG(FLG_UNAWARE);
2307                                 REM_FLG(FLG_IDENTIFIED);
2308                                 REM_FLG(FLG_STAR_IDENTIFIED);
2309                         }
2310
2311                         lines_list[cy] = autopick_line_from_entry(entry);
2312
2313                         /* Now dirty */
2314                         dirty_line = cy;
2315                         break;
2316                 case KTRL('v'):
2317                         while (cy < upper + hgt-4 && lines_list[cy + 1])
2318                                 cy++;
2319                         upper = cy;
2320                         break;
2321                 case KTRL('w'):
2322                         toggle_string(lines_list, FLG_WORTHLESS, cy);
2323                         /* Now dirty */
2324                         dirty_line = cy;
2325                         break;
2326                 case KTRL('x'):
2327                         toggle_string(lines_list, FLG_NAMELESS, cy);
2328                         /* Now dirty */
2329                         dirty_line = cy;
2330                         break;
2331                 case KTRL('y'):
2332                         if (strlen(yank_buf))
2333                         {
2334                                 cx = 0;
2335                                 for (j = 0; yank_buf[j]; j += strlen(yank_buf + j) + 1)
2336                                 {
2337                                         insert_return_code(lines_list, 0, cy);
2338                                         lines_list[cy] = string_make(yank_buf + j);
2339                                         cy++;
2340                                 }
2341
2342                                 /* Now dirty */
2343                                 dirty_line = -2;
2344                         }
2345                         break;
2346                 case KTRL('z'):
2347                         toggle_string(lines_list, FLG_COLLECTING, cy);
2348                         /* Now dirty */
2349                         dirty_line = cy;
2350                         break;
2351
2352                 case KTRL('k'):
2353                         if (lines_list[cy][0] != '\0' && cx < strlen(lines_list[cy]))
2354                         {
2355                                 for (i = j = 0; lines_list[cy][i] && i < cx; i++)
2356                                 {
2357 #ifdef JP
2358                                         if (iskanji(lines_list[cy][i]))
2359                                                 buf[j++] = lines_list[cy][i++];
2360 #endif
2361                                         buf[j++] = lines_list[cy][i];
2362                                 }
2363                                 buf[j] = '\0';
2364
2365                                 j = 0;
2366                                 if (old_key == KTRL('k'))
2367                                         while (yank_buf[j])
2368                                                 j += strlen(yank_buf + j) + 1;
2369
2370                                 if (j < MAX_YANK - 2)
2371                                 {
2372                                         strncpy(yank_buf + j, lines_list[cy] + i, MAX_YANK-j-2);
2373                                         yank_buf[MAX_YANK-2] = '\0';
2374                                         yank_buf[j + strlen(lines_list[cy] + i) + 1] = '\0';
2375                                 }
2376                                 string_free(lines_list[cy]);
2377                                 lines_list[cy] = string_make(buf);
2378
2379                                 /* Now dirty */
2380                                 dirty_line = cy;
2381                                 break;                  
2382                         }
2383                         /* fall through */
2384                 case KTRL('d'):
2385                 case 0x7F:
2386                         /* DELETE == go forward + BACK SPACE */
2387 #ifdef JP
2388                         if (iskanji(lines_list[cy][cx])) cx++;
2389 #endif
2390                         cx++;
2391                         len = strlen(lines_list[cy]);
2392                         if (len < cx)
2393                         {
2394                                 if (lines_list[cy + 1])
2395                                 {
2396                                         cy++;
2397                                         cx = 0;
2398                                 }
2399                                 else
2400                                 {
2401                                         cx = len;
2402                                         break;
2403                                 }
2404                         }
2405
2406                         /* fall through */
2407
2408                 case '\010':
2409                         /* BACK SPACE */
2410                         if (cx == 0)
2411                         {
2412                                 /* delete a return code and union two lines */
2413                                 if (cy == 0) break;
2414                                 cx = strlen(lines_list[cy-1]);
2415                                 strcpy(buf, lines_list[cy-1]);
2416                                 strcat(buf, lines_list[cy]);
2417                                 string_free(lines_list[cy-1]);
2418                                 string_free(lines_list[cy]);
2419                                 lines_list[cy-1] = string_make(buf);
2420                                 for (i = cy; lines_list[i+1]; i++)
2421                                         lines_list[i] = lines_list[i+1];
2422                                 lines_list[i] = NULL;
2423                                 cy--;
2424
2425                                 /* Now dirty */
2426                                 dirty_line = -2;
2427                                 break;
2428                         }
2429
2430                         for (i = j = 0; lines_list[cy][i] && i < cx; i++)
2431                         {
2432                                 k = j;
2433 #ifdef JP
2434                                 if (iskanji(lines_list[cy][i]))
2435                                         buf[j++] = lines_list[cy][i++];
2436 #endif
2437                                 buf[j++] = lines_list[cy][i];
2438                         }
2439                         while (j > k)
2440                         {
2441                                 cx--;
2442                                 j--;
2443                         }
2444                         for (; lines_list[cy][i]; i++)
2445                                 buf[j++] = lines_list[cy][i];
2446                         buf[j] = '\0';
2447                         string_free(lines_list[cy]);
2448                         lines_list[cy] = string_make(buf);
2449
2450                         /* Now dirty */
2451                         dirty_line = cy;
2452                         break;
2453                 }
2454
2455         } /* while (1) */
2456
2457         /* Restore the screen */
2458         screen_load();
2459
2460 #ifdef JP
2461         sprintf(buf, "picktype-%s.prf", player_name);
2462 #else
2463         sprintf(buf, "pickpref-%s.prf", player_name);
2464 #endif
2465         write_text_lines(buf, lines_list);
2466         free_text_lines(lines_list);
2467
2468         /* Clear old entries */
2469         for( i = 0; i < max_autopick; i++)
2470                 autopick_free_entry(&autopick_list[i]);
2471         max_autopick = 0;
2472
2473         string_free(last_destroyed);
2474
2475         /* Reload autopick pref */
2476         process_pickpref_file(buf);
2477 }