OSDN Git Service

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