OSDN Git Service

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