OSDN Git Service

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