OSDN Git Service

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