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 (o_ptr->tval == TV_GOLD) return FALSE;
938         
939         return TRUE;
940 }
941
942
943 /*
944  *  Auto inscription
945  */
946 void auto_inscribe_item(int item, int idx)
947 {
948         object_type *o_ptr;
949
950         /* Get the item (in the pack) */
951         if (item >= 0) o_ptr = &inventory[item];
952
953         /* Get the item (on the floor) */
954         else o_ptr = &o_list[0 - item];
955
956         /* Auto-inscription or Re-inscribe for resistances {%} */
957         if ((idx < 0 || !autopick_list[idx].insc) && !o_ptr->inscription)
958                 return;
959
960         if (o_ptr->inscription)
961                 o_ptr->inscription = inscribe_flags(o_ptr, quark_str(o_ptr->inscription));
962         else
963                 o_ptr->inscription = inscribe_flags(o_ptr, autopick_list[idx].insc);
964
965         if (item > INVEN_PACK)
966         {
967                 /* Redraw inscription */
968                 p_ptr->window |= (PW_EQUIP);
969
970                 /* {.} and {$} effect p_ptr->warning and TRC_TELEPORT_SELF */
971                 p_ptr->update |= (PU_BONUS);
972         }
973         else if (item >= 0)
974         {
975                 /* Redraw inscription */
976                 p_ptr->window |= (PW_INVEN);
977         }
978 }
979
980
981 /*
982  * Automatically destroy an item if it is to be destroyed
983  */
984 bool auto_destroy_item(int item, int autopick_idx)
985 {
986         bool destroy = FALSE;
987         object_type *o_ptr;
988
989         /* Don't destroy equipped items */
990         if (item > INVEN_PACK) return FALSE;
991
992         /* Get the item (in the pack) */
993         if (item >= 0) o_ptr = &inventory[item];
994
995         /* Get the item (on the floor) */
996         else o_ptr = &o_list[0 - item];
997
998         /* Easy-Auto-Destroyer */
999         if (is_opt_confirm_destroy(o_ptr)) destroy = TRUE;
1000
1001         /* Protected by auto-picker */
1002         if (autopick_idx >= 0 &&
1003             !(autopick_list[autopick_idx].action & DO_AUTODESTROY))
1004                 destroy = FALSE;
1005
1006         if (!always_pickup)
1007         {
1008                 /* Auto-picker/destroyer */
1009                 if (autopick_idx >= 0 &&
1010                     (autopick_list[autopick_idx].action & DO_AUTODESTROY))
1011                         destroy = TRUE;
1012         }
1013
1014         /* Not to be destroyed */
1015         if (!destroy) return FALSE;
1016
1017         /* Now decided to destroy */
1018
1019         disturb(0,0);
1020
1021         /* Artifact? */
1022         if (!can_player_destroy_object(o_ptr))
1023         {
1024                 char o_name[MAX_NLEN];
1025
1026                 /* Describe the object (with {terrible/special}) */
1027                 object_desc(o_name, o_ptr, TRUE, 3);
1028
1029                 /* Message */
1030 #ifdef JP
1031                 msg_format("%s¤ÏÇ˲õÉÔǽ¤À¡£", o_name);
1032 #else
1033                 msg_format("You cannot auto-destroy %s.", o_name);
1034 #endif
1035
1036                 /* Done */
1037                 return TRUE;
1038         }
1039
1040         /* Record name of destroyed item */
1041         COPY(&autopick_last_destroyed_object, o_ptr, object_type);
1042
1043         /* Destroy Later */
1044         o_ptr->marked |= OM_AUTODESTROY;
1045         p_ptr->notice |= PN_AUTODESTROY;
1046
1047         return TRUE;
1048 }
1049
1050
1051 /*
1052  *  Auto-destroy marked item
1053  */
1054 static void delayed_auto_destroy_aux(int item)
1055 {
1056         object_type *o_ptr;
1057
1058         /* Get the item (in the pack) */
1059         if (item >= 0) o_ptr = &inventory[item];
1060
1061         /* Get the item (on the floor) */
1062         else o_ptr = &o_list[0 - item];
1063
1064         if (o_ptr->k_idx && o_ptr->marked & OM_AUTODESTROY)
1065         {
1066                 char o_name[MAX_NLEN];
1067
1068                 /* Describe the object (with {terrible/special}) */
1069                 object_desc(o_name, o_ptr, TRUE, 3);
1070
1071                 /* Eliminate the item (from the pack) */
1072                 if (item >= 0)
1073                 {
1074                         inven_item_increase(item, -(o_ptr->number));
1075                         inven_item_optimize(item);
1076                 }
1077
1078                 /* Eliminate the item (from the floor) */
1079                 else
1080                 {
1081                         delete_object_idx(0 - item);
1082                 }
1083
1084                 /* Print a message */
1085 #ifdef JP
1086                 msg_format("%s¤ò¼«Æ°Ç˲õ¤·¤Þ¤¹¡£", o_name);
1087 #else
1088                 msg_format("Auto-destroying %s.", o_name);
1089 #endif
1090         }
1091 }
1092
1093
1094 /*
1095  *  Auto-destroy marked item in inventry and on floor
1096  */
1097 void delayed_auto_destroy(void)
1098 {
1099         int item;
1100
1101         /* 
1102          * Scan inventry in reverse order to prevent
1103          * skipping after inven_item_optimize()
1104          */
1105         for (item = INVEN_TOTAL; item >= 0 ; item--)
1106                 delayed_auto_destroy_aux(item);
1107
1108         /* Scan the pile of objects */
1109         item = cave[py][px].o_idx;
1110         while (item)
1111         {
1112                 int next = o_list[item].next_o_idx;
1113                 delayed_auto_destroy_aux(-item);
1114                 item = next;
1115         }
1116 }
1117
1118
1119 /*
1120  * Automatically pickup/destroy items in this grid.
1121  */
1122 void auto_pickup_items(cave_type *c_ptr)
1123 {
1124         s16b this_o_idx, next_o_idx = 0;
1125         
1126         /* Scan the pile of objects */
1127         for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
1128         {
1129                 int idx;
1130         
1131                 /* Acquire object */
1132                 object_type *o_ptr = &o_list[this_o_idx];
1133                 
1134                 /* Acquire next object */
1135                 next_o_idx = o_ptr->next_o_idx;
1136
1137                 idx = is_autopick(o_ptr);
1138
1139                 /* Item index for floor -1,-2,-3,...  */
1140                 auto_inscribe_item((-this_o_idx), idx);
1141
1142                 if (idx >= 0 &&
1143                         (autopick_list[idx].action & (DO_AUTOPICK | DO_QUERY_AUTOPICK)))
1144                 {
1145                         disturb(0,0);
1146
1147                         if (!inven_carry_okay(o_ptr))
1148                         {
1149                                 char o_name[MAX_NLEN];
1150
1151                                 /* Describe the object */
1152                                 object_desc(o_name, o_ptr, TRUE, 3);
1153
1154                                 /* Message */
1155 #ifdef JP
1156                                 msg_format("¥¶¥Ã¥¯¤Ë¤Ï%s¤òÆþ¤ì¤ë·ä´Ö¤¬¤Ê¤¤¡£", o_name);
1157 #else
1158                                 msg_format("You have no room for %s.", o_name);
1159 #endif
1160                                 /* Hack - remember that the item has given a message here. */
1161                                 o_ptr->marked |= OM_NOMSG;
1162
1163                                 continue;
1164                         }
1165                         else if (autopick_list[idx].action & DO_QUERY_AUTOPICK)
1166                         {
1167                                 char out_val[MAX_NLEN+20];
1168                                 char o_name[MAX_NLEN];
1169
1170                                 if (o_ptr->marked & OM_NO_QUERY)
1171                                 {
1172                                         /* Already answered as 'No' */
1173                                         continue;
1174                                 }
1175
1176                                 /* Describe the object */
1177                                 object_desc(o_name, o_ptr, TRUE, 3);
1178
1179 #ifdef JP
1180                                 sprintf(out_val, "%s¤ò½¦¤¤¤Þ¤¹¤«? ", o_name);
1181 #else
1182                                 sprintf(out_val, "Pick up %s? ", o_name);
1183 #endif
1184
1185                                 if (!get_check(out_val))
1186                                 {
1187                                         /* Hack - remember that the item has given a message here. */
1188                                         o_ptr->marked |= (OM_NOMSG | OM_NO_QUERY);
1189                                         continue;
1190                                 }
1191
1192                         }
1193                         py_pickup_aux(this_o_idx);
1194
1195                         continue;
1196                 }
1197                 
1198                 /*
1199                  * Do auto-destroy;
1200                  * When always_pickup is 'yes', we disable
1201                  * auto-destroyer from autopick function, and do only
1202                  * easy-auto-destroyer.
1203                  */
1204                 else
1205                 {
1206                         if (auto_destroy_item((-this_o_idx), idx))
1207                                 continue;
1208                 }
1209         }
1210 }
1211
1212
1213 /*
1214  * Describe which kind of object is Auto-picked/destroyed
1215  */
1216 static void describe_autopick(char *buff, autopick_type *entry)
1217 {
1218         cptr str = entry->name;
1219         byte act = entry->action;
1220         cptr insc = entry->insc;
1221         int i;
1222
1223         bool top = FALSE;
1224
1225 #ifdef JP
1226         cptr before_str[100], body_str;
1227         int before_n = 0;
1228
1229         body_str = "¥¢¥¤¥Æ¥à";
1230
1231         /*** Collecting items ***/
1232         /*** Which can be absorbed into a slot as a bundle ***/
1233         if (IS_FLG(FLG_COLLECTING))
1234                 before_str[before_n++] = "¼ý½¸Ãæ¤Ç´û¤Ë»ý¤Ã¤Æ¤¤¤ë¥¹¥í¥Ã¥È¤Ë¤Þ¤È¤á¤é¤ì¤ë";
1235         
1236         /*** Unidentified ***/
1237         if (IS_FLG(FLG_UNIDENTIFIED))
1238                 before_str[before_n++] = "̤´ÕÄê¤Î";
1239
1240         /*** Identified ***/
1241         if (IS_FLG(FLG_IDENTIFIED))
1242                 before_str[before_n++] = "´ÕÄêºÑ¤ß¤Î";
1243
1244         /*** *Identified* ***/
1245         if (IS_FLG(FLG_STAR_IDENTIFIED))
1246                 before_str[before_n++] = "´°Á´¤Ë´ÕÄêºÑ¤ß¤Î";
1247
1248         /*** Dice boosted (weapon of slaying) ***/
1249         if (IS_FLG(FLG_BOOSTED))
1250         {
1251                 before_str[before_n++] = "¥À¥á¡¼¥¸¥À¥¤¥¹¤¬Ä̾ï¤è¤êÂ礭¤¤";
1252                 body_str = "Éð´ï";
1253         }
1254
1255         /*** Weapons whose dd*ds is more than nn ***/
1256         if (IS_FLG(FLG_MORE_THAN))
1257         {
1258                 static char more_than_desc_str[] = "___";
1259                 before_str[before_n++] = "¥À¥á¡¼¥¸¥À¥¤¥¹¤ÎºÇÂçÃͤ¬";
1260                 body_str = "Éð´ï";
1261                         
1262                 sprintf(more_than_desc_str,"%d", entry->dice);
1263                 before_str[before_n++] = more_than_desc_str;
1264                 before_str[before_n++] = "°Ê¾å¤Î";
1265         }
1266
1267         /*** Items whose magical bonus is more than nn ***/
1268         if (IS_FLG(FLG_MORE_BONUS))
1269         {
1270                 static char more_bonus_desc_str[] = "___";
1271                 before_str[before_n++] = "½¤ÀµÃͤ¬(+";
1272                         
1273                 sprintf(more_bonus_desc_str,"%d", entry->bonus);
1274                 before_str[before_n++] = more_bonus_desc_str;
1275                 before_str[before_n++] = ")°Ê¾å¤Î";
1276         }
1277
1278         /*** Worthless items ***/
1279         if (IS_FLG(FLG_WORTHLESS))
1280                 before_str[before_n++] = "Ź¤Ç̵²ÁÃͤÈȽÄꤵ¤ì¤ë";
1281
1282         /*** Artifact ***/
1283         if (IS_FLG(FLG_ARTIFACT))
1284         {
1285                 before_str[before_n++] = "¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È¤Î";
1286                 body_str = "ÁõÈ÷";
1287         }
1288
1289         /*** Ego ***/
1290         if (IS_FLG(FLG_EGO))
1291         {
1292                 before_str[before_n++] = "¥¨¥´¥¢¥¤¥Æ¥à¤Î";
1293                 body_str = "ÁõÈ÷";
1294         }
1295
1296         /*** Nameless ***/
1297         if (IS_FLG(FLG_NAMELESS))
1298         {
1299                 before_str[before_n++] = "¥¨¥´¤Ç¤â¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È¤Ç¤â¤Ê¤¤";
1300                 body_str = "ÁõÈ÷";
1301         }
1302
1303         /*** Unaware items ***/
1304         if (IS_FLG(FLG_UNAWARE))
1305                 before_str[before_n++] = "̤´ÕÄê¤Ç¤½¤Î¸ú²Ì¤âȽÌÀ¤·¤Æ¤¤¤Ê¤¤";
1306
1307         /*** Wanted monster's corpse/skeletons ***/
1308         if (IS_FLG(FLG_WANTED))
1309         {
1310                 before_str[before_n++] = "¥Ï¥ó¥¿¡¼»ö̳½ê¤Ç¾Þ¶â¼ó¤È¤µ¤ì¤Æ¤¤¤ë";
1311                 body_str = "»àÂΤä¹ü";
1312         }
1313
1314         /*** Human corpse/skeletons (for Daemon magic) ***/
1315         if (IS_FLG(FLG_HUMAN))
1316         {
1317                 before_str[before_n++] = "°­ËâËâË¡¤Ç»È¤¦¤¿¤á¤Î¿Í´Ö¤ä¥Ò¥å¡¼¥Þ¥Î¥¤¥É¤Î";
1318                 body_str = "»àÂΤä¹ü";
1319         }
1320
1321         /*** Unique monster's corpse/skeletons/statues ***/
1322         if (IS_FLG(FLG_UNIQUE))
1323         {
1324                 before_str[before_n++] = "¥æ¥Ë¡¼¥¯¥â¥ó¥¹¥¿¡¼¤Î";
1325                 body_str = "»àÂΤä¹ü";
1326         }
1327
1328         /*** Unreadable spellbooks ***/
1329         if (IS_FLG(FLG_UNREADABLE))
1330         {
1331                 before_str[before_n++] = "¤¢¤Ê¤¿¤¬Æɤá¤Ê¤¤Îΰè¤Î";
1332                 body_str = "ËâË¡½ñ";
1333         }
1334
1335         /*** First realm spellbooks ***/
1336         if (IS_FLG(FLG_REALM1))
1337         {
1338                 before_str[before_n++] = "Âè°ìÎΰè¤Î";
1339                 body_str = "ËâË¡½ñ";
1340         }
1341
1342         /*** Second realm spellbooks ***/
1343         if (IS_FLG(FLG_REALM2))
1344         {
1345                 before_str[before_n++] = "ÂèÆóÎΰè¤Î";
1346                 body_str = "ËâË¡½ñ";
1347         }
1348
1349         /*** First rank spellbooks ***/
1350         if (IS_FLG(FLG_FIRST))
1351         {
1352                 before_str[before_n++] = "Á´4ºý¤ÎÆâ¤Î1ºýÌܤÎ";
1353                 body_str = "ËâË¡½ñ";
1354         }
1355
1356         /*** Second rank spellbooks ***/
1357         if (IS_FLG(FLG_SECOND))
1358         {
1359                 before_str[before_n++] = "Á´4ºý¤ÎÆâ¤Î2ºýÌܤÎ";
1360                 body_str = "ËâË¡½ñ";
1361         }
1362
1363         /*** Third rank spellbooks ***/
1364         if (IS_FLG(FLG_THIRD))
1365         {
1366                 before_str[before_n++] = "Á´4ºý¤ÎÆâ¤Î3ºýÌܤÎ";
1367                 body_str = "ËâË¡½ñ";
1368         }
1369
1370         /*** Fourth rank spellbooks ***/
1371         if (IS_FLG(FLG_FOURTH))
1372         {
1373                 before_str[before_n++] = "Á´4ºý¤ÎÆâ¤Î4ºýÌܤÎ";
1374                 body_str = "ËâË¡½ñ";
1375         }
1376
1377         /*** Items ***/
1378         if (IS_FLG(FLG_ITEMS))
1379                 ; /* Nothing to do */
1380         else if (IS_FLG(FLG_WEAPONS))
1381                 body_str = "Éð´ï";
1382         else if (IS_FLG(FLG_ARMORS))
1383                 body_str = "Ëɶñ";
1384         else if (IS_FLG(FLG_MISSILES))
1385                 body_str = "ÃƤäÌð¤ä¥¯¥í¥¹¥Ü¥¦¤ÎÌð";
1386         else if (IS_FLG(FLG_DEVICES))
1387                 body_str = "´¬Êª¤äËâË¡ËÀ¤ä¾ó¤ä¥í¥Ã¥É";
1388         else if (IS_FLG(FLG_LIGHTS))
1389                 body_str = "¸÷¸»ÍѤΥ¢¥¤¥Æ¥à";
1390         else if (IS_FLG(FLG_JUNKS))
1391                 body_str = "Àޤ줿ËÀÅù¤Î¥¬¥é¥¯¥¿";
1392         else if (IS_FLG(FLG_SPELLBOOKS))
1393                 body_str = "ËâË¡½ñ";
1394         else if (IS_FLG(FLG_HAFTED))
1395                 body_str = "Æß´ï";
1396         else if (IS_FLG(FLG_SHIELDS))
1397                 body_str = "½â";
1398         else if (IS_FLG(FLG_BOWS))
1399                 body_str = "¥¹¥ê¥ó¥°¤äµÝ¤ä¥¯¥í¥¹¥Ü¥¦";
1400         else if (IS_FLG(FLG_RINGS))
1401                 body_str = "»ØÎØ";
1402         else if (IS_FLG(FLG_AMULETS))
1403                 body_str = "¥¢¥ß¥å¥ì¥Ã¥È";
1404         else if (IS_FLG(FLG_SUITS))
1405                 body_str = "³»";
1406         else if (IS_FLG(FLG_CLOAKS))
1407                 body_str = "¥¯¥í¡¼¥¯";
1408         else if (IS_FLG(FLG_HELMS))
1409                 body_str = "¥Ø¥ë¥á¥Ã¥È¤ä´§";
1410         else if (IS_FLG(FLG_GLOVES))
1411                 body_str = "äƼê";
1412         else if (IS_FLG(FLG_BOOTS))
1413                 body_str = "¥Ö¡¼¥Ä";
1414
1415         *buff = '\0';
1416         if (!before_n) 
1417                 strcat(buff, "Á´¤Æ¤Î");
1418         else for (i = 0; i < before_n && before_str[i]; i++)
1419                 strcat(buff, before_str[i]);
1420
1421         strcat(buff, body_str);
1422
1423         if (*str)
1424         {
1425                 if (*str == '^')
1426                 {
1427                         str++;
1428                         top = TRUE;
1429                 }
1430
1431                 strcat(buff, "¤Ç¡¢Ì¾Á°¤¬¡Ö");
1432                 strncat(buff, str, 80);
1433                 if (top)
1434                         strcat(buff, "¡×¤Ç»Ï¤Þ¤ë¤â¤Î");
1435                 else
1436                         strcat(buff, "¡×¤ò´Þ¤à¤â¤Î");
1437         }
1438
1439         if (insc)
1440         {
1441                 strncat(buff, format("¤Ë¡Ö%s¡×", insc), 80);
1442
1443                 if (strstr(insc, "%%all"))
1444                         strcat(buff, "(%%all¤ÏÁ´Ç½ÎϤòɽ¤¹±Ñ»ú¤Îµ­¹æ¤ÇÃÖ´¹)");
1445                 else if (strstr(insc, "%all"))
1446                         strcat(buff, "(%all¤ÏÁ´Ç½ÎϤòɽ¤¹µ­¹æ¤ÇÃÖ´¹)");
1447                 else if (strstr(insc, "%%"))
1448                         strcat(buff, "(%%¤ÏÄɲÃǽÎϤòɽ¤¹±Ñ»ú¤Îµ­¹æ¤ÇÃÖ´¹)");
1449                 else if (strstr(insc, "%"))
1450                         strcat(buff, "(%¤ÏÄɲÃǽÎϤòɽ¤¹µ­¹æ¤ÇÃÖ´¹)");
1451
1452                 strcat(buff, "¤È¹ï¤ó¤Ç");
1453         }
1454         else
1455                 strcat(buff, "¤ò");
1456
1457         if (act & DONT_AUTOPICK)
1458                 strcat(buff, "ÊüÃÖ¤¹¤ë¡£");
1459         else if (act & DO_AUTODESTROY)
1460                 strcat(buff, "Ç˲õ¤¹¤ë¡£");
1461         else if (act & DO_QUERY_AUTOPICK)
1462                 strcat(buff, "³Îǧ¤Î¸å¤Ë½¦¤¦¡£");
1463         else
1464                 strcat(buff, "½¦¤¦¡£");
1465
1466         if (act & DO_DISPLAY)
1467         {
1468                 if (act & DONT_AUTOPICK)
1469                         strcat(buff, "Á´ÂΥޥå×('M')¤Ç'N'¤ò²¡¤·¤¿¤È¤­¤Ëɽ¼¨¤¹¤ë¡£");
1470                 else if (act & DO_AUTODESTROY)
1471                         strcat(buff, "Á´ÂΥޥå×('M')¤Ç'K'¤ò²¡¤·¤¿¤È¤­¤Ëɽ¼¨¤¹¤ë¡£");
1472                 else
1473                         strcat(buff, "Á´ÂΥޥå×('M')¤Ç'M'¤ò²¡¤·¤¿¤È¤­¤Ëɽ¼¨¤¹¤ë¡£");
1474         }
1475         else
1476                 strcat(buff, "Á´ÂΥޥåפˤÏɽ¼¨¤·¤Ê¤¤");
1477
1478 #else /* JP */
1479
1480         cptr before_str[20], after_str[20], which_str[20], whose_str[20], body_str;
1481         int before_n = 0, after_n = 0, which_n = 0, whose_n = 0;
1482
1483         body_str = "items";
1484
1485         /*** Collecting items ***/
1486         /*** Which can be absorbed into a slot as a bundle ***/
1487         if (IS_FLG(FLG_COLLECTING))
1488                 which_str[which_n++] = "can be absorbed into an existing inventory slot";
1489         
1490         /*** Unidentified ***/
1491         if (IS_FLG(FLG_UNIDENTIFIED))
1492                 before_str[before_n++] = "unidentified";
1493
1494         /*** Identified ***/
1495         if (IS_FLG(FLG_IDENTIFIED))
1496                 before_str[before_n++] = "identified";
1497
1498         /*** *Identified* ***/
1499         if (IS_FLG(FLG_STAR_IDENTIFIED))
1500                 before_str[before_n++] = "fully identified";
1501
1502         /*** Worthless items ***/
1503         if (IS_FLG(FLG_WORTHLESS))
1504         {
1505                 before_str[before_n++] = "worthless";
1506                 which_str[which_n++] = "can not be sold at stores";
1507         }
1508
1509         /*** Artifacto ***/
1510         if (IS_FLG(FLG_ARTIFACT))
1511         {
1512                 before_str[before_n++] = "artifact";
1513         }
1514
1515         /*** Ego ***/
1516         if (IS_FLG(FLG_EGO))
1517         {
1518                 before_str[before_n++] = "ego";
1519         }
1520
1521         /*** Nameless ***/
1522         if (IS_FLG(FLG_NAMELESS))
1523         {
1524                 body_str = "equipment";
1525                 which_str[which_n++] = "is neither ego-item nor artifact";
1526         }
1527
1528         /*** Unaware items ***/
1529         if (IS_FLG(FLG_UNAWARE))
1530         {
1531                 before_str[before_n++] = "unidentified";
1532                 whose_str[whose_n++] = "basic abilities are not known";
1533         }
1534
1535         /*** Dice boosted (weapon of slaying) ***/
1536         if (IS_FLG(FLG_BOOSTED))
1537         {
1538                 body_str = "weapons";
1539                 whose_str[whose_n++] = "damage dice is bigger than normal";
1540         }
1541
1542         /*** Weapons whose dd*ds is more than nn ***/
1543         if (IS_FLG(FLG_MORE_THAN))
1544         {
1545                 static char more_than_desc_str[] =
1546                         "maximum damage from dice is bigger than __";
1547                 body_str = "weapons";
1548                         
1549                 sprintf(more_than_desc_str + sizeof(more_than_desc_str) - 3,
1550                         "%d", entry->dice);
1551                 whose_str[whose_n++] = more_than_desc_str;
1552         }
1553
1554         /*** Items whose magical bonus is more than nn ***/
1555         if (IS_FLG(FLG_MORE_BONUS))
1556         {
1557                 static char more_bonus_desc_str[] =
1558                         "magical bonus is bigger than (+__)";
1559                         
1560                 sprintf(more_bonus_desc_str + sizeof(more_bonus_desc_str) - 4,
1561                         "%d)", entry->bonus);
1562                 whose_str[whose_n++] = more_bonus_desc_str;
1563         }
1564
1565         /*** Wanted monster's corpse/skeletons ***/
1566         if (IS_FLG(FLG_WANTED))
1567         {
1568                 body_str = "corpse or skeletons";
1569                 which_str[which_n++] = "is wanted at the Hunter's Office";
1570         }
1571
1572         /*** Human corpse/skeletons (for Daemon magic) ***/
1573         if (IS_FLG(FLG_HUMAN))
1574         {
1575                 before_str[before_n++] = "humanoid";
1576                 body_str = "corpse or skeletons";
1577                 which_str[which_n++] = "can be used for Daemon magic";
1578         }
1579
1580         /*** Unique monster's corpse/skeletons/statues ***/
1581         if (IS_FLG(FLG_UNIQUE))
1582         {
1583                 before_str[before_n++] = "unique monster's";
1584                 body_str = "corpse or skeletons";
1585         }
1586
1587         /*** Unreadable spellbooks ***/
1588         if (IS_FLG(FLG_UNREADABLE))
1589         {
1590                 body_str = "spellbooks";
1591                 after_str[after_n++] = "of different realms from yours";
1592         }
1593
1594         /*** First realm spellbooks ***/
1595         if (IS_FLG(FLG_REALM1))
1596         {
1597                 body_str = "spellbooks";
1598                 after_str[after_n++] = "of your first realm";
1599         }
1600
1601         /*** Second realm spellbooks ***/
1602         if (IS_FLG(FLG_REALM2))
1603         {
1604                 body_str = "spellbooks";
1605                 after_str[after_n++] = "of your second realm";
1606         }
1607
1608         /*** First rank spellbooks ***/
1609         if (IS_FLG(FLG_FIRST))
1610         {
1611                 before_str[before_n++] = "first one of four";
1612                 body_str = "spellbooks";
1613         }
1614
1615         /*** Second rank spellbooks ***/
1616         if (IS_FLG(FLG_SECOND))
1617         {
1618                 before_str[before_n++] = "second one of four";
1619                 body_str = "spellbooks";
1620         }
1621
1622         /*** Third rank spellbooks ***/
1623         if (IS_FLG(FLG_THIRD))
1624         {
1625                 before_str[before_n++] = "third one of four";
1626                 body_str = "spellbooks";
1627         }
1628
1629         /*** Fourth rank spellbooks ***/
1630         if (IS_FLG(FLG_FOURTH))
1631         {
1632                 before_str[before_n++] = "fourth one of four";
1633                 body_str = "spellbooks";
1634         }
1635
1636         /*** Items ***/
1637         if (IS_FLG(FLG_ITEMS))
1638                 ; /* Nothing to do */
1639         else if (IS_FLG(FLG_WEAPONS))
1640                 body_str = "weapons";
1641         else if (IS_FLG(FLG_ARMORS))
1642                 body_str = "armors";
1643         else if (IS_FLG(FLG_MISSILES))
1644                 body_str = "shots, arrows or crossbow bolts";
1645         else if (IS_FLG(FLG_DEVICES))
1646                 body_str = "scrolls, wands, staves or rods";
1647         else if (IS_FLG(FLG_LIGHTS))
1648                 body_str = "light sources";
1649         else if (IS_FLG(FLG_JUNKS))
1650                 body_str = "junk such as broken sticks";
1651         else if (IS_FLG(FLG_SPELLBOOKS))
1652                 body_str = "spellbooks";
1653         else if (IS_FLG(FLG_HAFTED))
1654                 body_str = "hafted weapons";
1655         else if (IS_FLG(FLG_SHIELDS))
1656                 body_str = "shields";
1657         else if (IS_FLG(FLG_BOWS))
1658                 body_str = "slings, bows or crossbows";
1659         else if (IS_FLG(FLG_RINGS))
1660                 body_str = "rings";
1661         else if (IS_FLG(FLG_AMULETS))
1662                 body_str = "amulets";
1663         else if (IS_FLG(FLG_SUITS))
1664                 body_str = "body armors";
1665         else if (IS_FLG(FLG_CLOAKS))
1666                 body_str = "cloaks";
1667         else if (IS_FLG(FLG_HELMS))
1668                 body_str = "helms or crowns";
1669         else if (IS_FLG(FLG_GLOVES))
1670                 body_str = "gloves";
1671         else if (IS_FLG(FLG_BOOTS))
1672                 body_str = "boots";
1673
1674         /* Prepare a string for item name */
1675         if (*str)
1676         {
1677                 if (*str == '^')
1678                 {
1679                         str++;
1680                         top = TRUE;
1681                         whose_str[whose_n++] = "name is beginning with \"";
1682                 }
1683                 else
1684                         which_str[which_n++] = "have \"";
1685         }
1686
1687
1688         /* Describe action flag */
1689         if (act & DONT_AUTOPICK)
1690                 strcpy(buff, "Leave on floor ");
1691         else if (act & DO_AUTODESTROY)
1692                 strcpy(buff, "Destroy ");
1693         else if (act & DO_QUERY_AUTOPICK)
1694                 strcpy(buff, "Ask to pick up ");
1695         else
1696                 strcpy(buff, "Pickup ");
1697
1698         /* Auto-insctiption */
1699         if (insc)
1700         {
1701                 strncat(buff, format("and inscribe \"%s\"", insc), 80);
1702
1703                 if (strstr(insc, "%all"))
1704                         strcat(buff, ", replacing %all with code string representing all abilities,");
1705                 else if (strstr(insc, "%"))
1706                         strcat(buff, ", replacing % with code string representing extra random abilities,");
1707
1708                 strcat(buff, " on ");
1709         }
1710
1711         /* Adjective */
1712         if (!before_n) 
1713                 strcat(buff, "all ");
1714         else for (i = 0; i < before_n && before_str[i]; i++)
1715         {
1716                 strcat(buff, before_str[i]);
1717                 strcat(buff, " ");
1718         }
1719
1720         /* Item class */
1721         strcat(buff, body_str);
1722
1723         /* of ... */
1724         for (i = 0; i < after_n && after_str[i]; i++)
1725         {
1726                 strcat(buff, " ");
1727                 strcat(buff, after_str[i]);
1728         }
1729
1730         /* which ... */
1731         for (i = 0; i < whose_n && whose_str[i]; i++)
1732         {
1733                 if (i == 0)
1734                         strcat(buff, " whose ");
1735                 else
1736                         strcat(buff, ", and ");
1737
1738                 strcat(buff, whose_str[i]);
1739         }
1740
1741         /* Item name ; whose name is beginning with "str" */
1742         if (*str && top)
1743         {
1744                 strcat(buff, str);
1745                 strcat(buff, "\"");
1746         }
1747
1748         /* whose ..., and which .... */
1749         if (whose_n && which_n)
1750                 strcat(buff, ", and ");
1751
1752         /* which ... */
1753         for (i = 0; i < which_n && which_str[i]; i++)
1754         {
1755                 if (i == 0)
1756                         strcat(buff, " which ");
1757                 else
1758                         strcat(buff, ", and ");
1759
1760                 strcat(buff, which_str[i]);
1761         }
1762
1763         /* Item name ; which have "str" as part of its name */
1764         if (*str && !top)
1765         {
1766                 strncat(buff, str, 80);
1767                 strcat(buff, "\" as part of its name");
1768         }
1769         strcat(buff, ".");
1770
1771         /* Describe whether it will be displayed on the full map or not */
1772         if (act & DO_DISPLAY)
1773         {
1774                 if (act & DONT_AUTOPICK)
1775                         strcat(buff, "  Display these items when you press the N key in the full 'M'ap.");
1776                 else if (act & DO_AUTODESTROY)
1777                         strcat(buff, "  Display these items when you press the K key in the full 'M'ap.");
1778                 else
1779                         strcat(buff, "  Display these items when you press the M key in the full 'M'ap.");
1780         }
1781         else
1782                 strcat(buff, " Not displayed in the full map.");
1783 #endif /* JP */
1784
1785 }
1786
1787
1788 #define MAX_LINES 3000
1789
1790 /*
1791  * Read whole lines of a file to memory
1792  */
1793 static cptr *read_text_lines(cptr filename, bool user)
1794 {
1795         cptr *lines_list = NULL;
1796         FILE *fff;
1797
1798         int lines = 0;
1799         char buf[1024];
1800
1801         if (user)
1802         {
1803                 /* Hack -- drop permissions */
1804                 safe_setuid_drop();
1805                 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, filename);
1806         }
1807         else
1808         {
1809                 path_build(buf, sizeof(buf), ANGBAND_DIR_PREF, filename);
1810         }
1811         
1812         /* Open the file */
1813         fff = my_fopen(buf, "r");
1814
1815         if (fff)
1816         {
1817                 /* Allocate list of pointers */
1818                 C_MAKE(lines_list, MAX_LINES, cptr);
1819
1820                 /* Parse it */
1821                 while (0 == my_fgets(fff, buf, sizeof(buf)))
1822                 {
1823                         lines_list[lines++] = string_make(buf);
1824                         if (lines >= MAX_LINES - 1) break;
1825                 }
1826                 if (lines == 0)
1827                         lines_list[0] = string_make("");
1828
1829                 my_fclose(fff);
1830         }
1831
1832         /* Grab priv's */
1833         safe_setuid_grab();
1834
1835         if (!fff) return NULL;
1836         return lines_list;
1837 }
1838
1839
1840 #define PT_DEFAULT 0
1841 #define PT_WITH_PNAME 1
1842
1843 static cptr *read_pickpref_text_lines(int *filename_mode_p)
1844 {
1845         char buf[1024];
1846         cptr *lines_list;
1847
1848 #ifdef JP
1849         sprintf(buf, "picktype-%s.prf", player_name);
1850 #else
1851         sprintf(buf, "pickpref-%s.prf", player_name);
1852 #endif
1853         lines_list = read_text_lines(buf, TRUE);
1854
1855         if (!lines_list)
1856         {
1857 #ifdef JP
1858                 lines_list = read_text_lines("picktype.prf", TRUE);
1859 #else
1860                 lines_list = read_text_lines("pickpref.prf", TRUE);
1861 #endif
1862                 *filename_mode_p = PT_DEFAULT;
1863         }
1864
1865         if (!lines_list)
1866         {
1867 #ifdef JP
1868                 lines_list = read_text_lines("picktype.prf", FALSE);
1869 #else
1870                 lines_list = read_text_lines("pickpref.prf", FALSE);
1871 #endif
1872                 *filename_mode_p = PT_WITH_PNAME;
1873         }
1874
1875         if (!lines_list)
1876         {
1877                 /* Allocate list of pointers */
1878                 C_MAKE(lines_list, MAX_LINES, cptr);
1879                 lines_list[0] = string_make("");
1880                 *filename_mode_p = PT_WITH_PNAME;
1881         }
1882         return lines_list;
1883 }
1884
1885 /*
1886  * Write whole lines of memory to a file.
1887  */
1888 static bool write_text_lines(cptr filename, cptr *lines_list)
1889 {
1890         FILE *fff;
1891
1892         int lines = 0;
1893         char buf[1024];
1894
1895         /* Hack -- drop permissions */
1896         safe_setuid_drop();
1897
1898         /* Build the filename */
1899         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, filename);
1900         
1901         /* Open the file */
1902         fff = my_fopen(buf, "w");
1903         if (fff)
1904         {
1905                 for (lines = 0; lines_list[lines]; lines++)
1906                         my_fputs(fff, lines_list[lines], 1024);
1907
1908                 my_fclose(fff);
1909         }
1910
1911         /* Grab priv's */
1912         safe_setuid_grab();
1913
1914         if (!fff) return FALSE;
1915         return TRUE;
1916 }
1917
1918
1919 /*
1920  * Free memory of lines_list.
1921  */
1922 static void free_text_lines(cptr *lines_list)
1923 {
1924         int lines;
1925
1926         for (lines = 0; lines_list[lines]; lines++)
1927                 string_free(lines_list[lines]);
1928
1929         /* free list of pointers */
1930         C_FREE((char **)lines_list, MAX_LINES, char *);
1931 }
1932
1933
1934 /*
1935  * Delete or insert string
1936  */
1937 static void toggle_string(cptr *lines_list, int flg, int y)
1938 {
1939         autopick_type an_entry, *entry = &an_entry;
1940
1941         if (!autopick_new_entry(entry, lines_list[y]))
1942                 return;
1943
1944         string_free(lines_list[y]);
1945         if (IS_FLG(flg)) 
1946                 REM_FLG(flg);
1947         else
1948                 ADD_FLG(flg);
1949
1950         lines_list[y] = autopick_line_from_entry_kill(entry);
1951 }
1952
1953 /*
1954  * Insert return code and split the line
1955  */
1956 static bool insert_return_code(cptr *lines_list, int cx, int cy)
1957 {
1958         char buf[MAX_LINELEN];
1959         int i, j, k;
1960
1961         for (k = 0; lines_list[k]; k++)
1962                 /* count number of lines */ ;
1963
1964         if (k >= MAX_LINES - 2) return FALSE;
1965         k--;
1966
1967         /* Move down lines */
1968         for (; cy < k; k--)
1969                 lines_list[k+1] = lines_list[k];
1970
1971         /* Split current line */
1972         for (i = j = 0; lines_list[cy][i] && i < cx; i++)
1973         {
1974 #ifdef JP
1975                 if (iskanji(lines_list[cy][i]))
1976                         buf[j++] = lines_list[cy][i++];
1977 #endif
1978                 buf[j++] = lines_list[cy][i];
1979         }
1980         buf[j] = '\0';
1981         lines_list[cy+1] = string_make(&lines_list[cy][i]);
1982         string_free(lines_list[cy]);
1983         lines_list[cy] = string_make(buf);
1984         return TRUE;
1985 }
1986
1987
1988 /*
1989  * Get auto-picker entry from o_ptr.
1990  */
1991 void autopick_entry_from_object(autopick_type *entry, object_type *o_ptr)
1992 {
1993         char o_name[MAX_NLEN];
1994         object_desc(o_name, o_ptr, FALSE, 0);
1995
1996         entry->name = string_make(o_name);
1997         entry->insc = string_make(quark_str(o_ptr->inscription));
1998         entry->action = DO_AUTOPICK | DO_DISPLAY;
1999         entry->flag[0] = entry->flag[1] = 0L;
2000         entry->dice = 0;
2001
2002         if (!object_aware_p(o_ptr))
2003                 ADD_FLG(FLG_UNAWARE);
2004         if (object_value(o_ptr) <= 0)
2005                 ADD_FLG(FLG_WORTHLESS);
2006
2007         if (object_known_p(o_ptr))
2008         {
2009                 if (o_ptr->name2)
2010                         ADD_FLG(FLG_EGO);
2011                 else if (o_ptr->name1 || o_ptr->art_name)
2012                         ADD_FLG(FLG_ARTIFACT);
2013         }
2014
2015         switch(o_ptr->tval)
2016         {
2017                 object_kind *k_ptr; 
2018         case TV_HAFTED: case TV_POLEARM: case TV_SWORD: case TV_DIGGING:
2019                 k_ptr = &k_info[o_ptr->k_idx];
2020                 if ((o_ptr->dd != k_ptr->dd) || (o_ptr->ds != k_ptr->ds))
2021                         ADD_FLG(FLG_BOOSTED);
2022         }
2023
2024         if (o_ptr->tval == TV_CORPSE && object_is_shoukinkubi(o_ptr))
2025         {
2026                 REM_FLG(FLG_WORTHLESS);
2027                 ADD_FLG(FLG_WANTED);
2028         }
2029
2030         if ((o_ptr->tval == TV_CORPSE || o_ptr->tval == TV_STATUE)
2031             && (r_info[o_ptr->pval].flags1 & RF1_UNIQUE))
2032         {
2033                 REM_FLG(FLG_WORTHLESS);
2034                 ADD_FLG(FLG_UNIQUE);
2035         }
2036
2037         if (o_ptr->tval == TV_CORPSE && strchr("pht", r_info[o_ptr->pval].d_char))
2038         {
2039                 REM_FLG(FLG_WORTHLESS);
2040                 ADD_FLG(FLG_HUMAN);
2041         }
2042
2043         if (o_ptr->tval >= TV_LIFE_BOOK &&
2044             !check_book_realm(o_ptr->tval, o_ptr->sval))
2045                 ADD_FLG(FLG_UNREADABLE);
2046
2047         if (REALM1_BOOK == o_ptr->tval &&
2048             p_ptr->pclass != CLASS_SORCERER &&
2049             p_ptr->pclass != CLASS_RED_MAGE)
2050                 ADD_FLG(FLG_REALM1);
2051
2052         if (REALM2_BOOK == o_ptr->tval &&
2053             p_ptr->pclass != CLASS_SORCERER &&
2054             p_ptr->pclass != CLASS_RED_MAGE)
2055                 ADD_FLG(FLG_REALM2);
2056
2057         if (o_ptr->tval >= TV_LIFE_BOOK && 0 == o_ptr->sval)
2058                 ADD_FLG(FLG_FIRST);
2059         if (o_ptr->tval >= TV_LIFE_BOOK && 1 == o_ptr->sval)
2060                 ADD_FLG(FLG_SECOND);
2061         if (o_ptr->tval >= TV_LIFE_BOOK && 2 == o_ptr->sval)
2062                 ADD_FLG(FLG_THIRD);
2063         if (o_ptr->tval >= TV_LIFE_BOOK && 3 == o_ptr->sval)
2064                 ADD_FLG(FLG_FOURTH);
2065
2066         if (o_ptr->tval == TV_SHOT || o_ptr->tval == TV_BOLT
2067                  || o_ptr->tval == TV_ARROW)
2068                 ADD_FLG(FLG_MISSILES);
2069         else if (o_ptr->tval == TV_SCROLL || o_ptr->tval == TV_STAFF
2070                  || o_ptr->tval == TV_WAND || o_ptr->tval == TV_ROD)
2071                 ADD_FLG(FLG_DEVICES);
2072         else if (o_ptr->tval == TV_LITE)
2073                 ADD_FLG(FLG_LIGHTS);
2074         else if (o_ptr->tval == TV_SKELETON || o_ptr->tval == TV_BOTTLE
2075                  || o_ptr->tval == TV_JUNK || o_ptr->tval == TV_STATUE)
2076                 ADD_FLG(FLG_JUNKS);
2077         else if (o_ptr->tval >= TV_LIFE_BOOK)
2078                 ADD_FLG(FLG_SPELLBOOKS);
2079         else if (o_ptr->tval == TV_HAFTED)
2080                 ADD_FLG(FLG_HAFTED);
2081         else if (o_ptr->tval == TV_POLEARM || o_ptr->tval == TV_SWORD
2082                  || o_ptr->tval == TV_DIGGING)
2083                 ADD_FLG(FLG_WEAPONS);
2084         else if (o_ptr->tval == TV_SHIELD)
2085                 ADD_FLG(FLG_SHIELDS);
2086         else if (o_ptr->tval == TV_BOW)
2087                 ADD_FLG(FLG_BOWS);
2088         else if (o_ptr->tval == TV_RING)
2089                 ADD_FLG(FLG_RINGS);
2090         else if (o_ptr->tval == TV_AMULET)
2091                 ADD_FLG(FLG_AMULETS);
2092         else if (o_ptr->tval == TV_DRAG_ARMOR || o_ptr->tval == TV_HARD_ARMOR ||
2093                  o_ptr->tval == TV_SOFT_ARMOR)
2094                 ADD_FLG(FLG_SUITS);
2095         else if (o_ptr->tval == TV_CLOAK)
2096                 ADD_FLG(FLG_CLOAKS);
2097         else if (o_ptr->tval == TV_HELM)
2098                 ADD_FLG(FLG_HELMS);
2099         else if (o_ptr->tval == TV_GLOVES)
2100                 ADD_FLG(FLG_GLOVES);
2101         else if (o_ptr->tval == TV_BOOTS)
2102                 ADD_FLG(FLG_BOOTS);
2103
2104         return;
2105 }
2106
2107
2108 /*
2109  * Choose an item and get auto-picker entry from it.
2110  */
2111 static object_type *choose_object(cptr q, cptr s)
2112 {
2113         int item;
2114
2115         if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EQUIP))) return NULL;
2116
2117         /* Get the item (in the pack) */
2118         if (item >= 0) return &inventory[item];
2119
2120         /* Get the item (on the floor) */
2121         else return &o_list[0 - item];
2122 }
2123
2124
2125 /*
2126  * Choose an item and get auto-picker entry from it.
2127  */
2128 static bool entry_from_choosed_object(autopick_type *entry)
2129 {
2130         object_type *o_ptr;
2131         cptr q, s;
2132
2133         /* Get an item */
2134 #ifdef JP
2135         q = "¤É¤Î¥¢¥¤¥Æ¥à¤òÅÐÏ¿¤·¤Þ¤¹¤«? ";
2136         s = "¥¢¥¤¥Æ¥à¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¡£";
2137 #else
2138         q = "Entry which item? ";
2139         s = "You have nothing to entry.";
2140 #endif
2141         o_ptr = choose_object(q, s);
2142         if (!o_ptr) return FALSE;
2143
2144         autopick_entry_from_object(entry, o_ptr);
2145         return TRUE;
2146 }
2147
2148
2149 /*
2150  * Choose an item or string for search
2151  */
2152 static bool get_string_for_search(object_type **o_handle, cptr *search_strp)
2153 {
2154         int pos = 0;
2155         cptr q, s;
2156         char buf[MAX_NLEN+20];
2157
2158 #ifdef JP
2159         int k_flag[MAX_NLEN+20];
2160         char prompt[] = "¸¡º÷(^I:»ý¤Áʪ ^L:Ç˲õ¤µ¤ì¤¿Êª): ";
2161 #else
2162         char prompt[] = "Search key(^I:inven ^L:destroyed): ";
2163 #endif
2164         int col = sizeof(prompt) - 1;
2165
2166         if (*search_strp) strcpy(buf, *search_strp);
2167         else buf[0] = '\0';
2168
2169         /* Display prompt */
2170         prt(prompt, 0, 0);
2171
2172         /* Display the default answer */
2173         Term_erase(col, 0, 255);
2174         Term_putstr(col, 0, -1, TERM_YELLOW, buf);
2175
2176         /* Process input */
2177         while (1)
2178         {
2179                 object_type *o_ptr;
2180                 int i;
2181
2182                 /* Place cursor */
2183                 Term_gotoxy(col + pos, 0);
2184
2185                 /* Do not process macros except special keys */
2186                 inkey_special = TRUE;
2187
2188                 /* Get a key */
2189                 i = inkey();
2190
2191                 /* Analyze the key */
2192                 switch (i)
2193                 {
2194                 case ESCAPE:
2195                         pos = 0;
2196                         return FALSE;
2197
2198                 case '\n':
2199                 case '\r':
2200                         if (!pos && *o_handle) return TRUE;
2201                         string_free(*search_strp);
2202                         *search_strp = string_make(buf);
2203                         *o_handle = NULL;
2204                         return TRUE;
2205
2206                 case KTRL('i'):
2207                         /* Get an item */
2208 #ifdef JP
2209                         q = "¤É¤Î¥¢¥¤¥Æ¥à¤ò¸¡º÷¤·¤Þ¤¹¤«? ";
2210                         s = "¥¢¥¤¥Æ¥à¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¡£";
2211 #else
2212                         q = "Entry which item? ";
2213                         s = "You have nothing to entry.";
2214 #endif
2215                         o_ptr = choose_object(q, s);
2216                         if (!o_ptr) return FALSE;
2217
2218                         *o_handle = o_ptr;
2219
2220                         string_free(*search_strp);
2221                         object_desc(buf, *o_handle, FALSE, 3);
2222                         *search_strp = string_make(format("<%s>", buf));
2223                         return TRUE;
2224
2225                 case KTRL('l'):
2226                         if (!autopick_last_destroyed_object.k_idx) break;
2227                         *o_handle = &autopick_last_destroyed_object;
2228
2229                         string_free(*search_strp);
2230                         object_desc(buf, *o_handle, FALSE, 3);
2231                         *search_strp = string_make(format("<%s>", buf));
2232                         return TRUE;
2233
2234                 case 0x7F:
2235                 case '\010':
2236 #ifdef JP
2237                         if (pos > 0)
2238                         {
2239                                 pos--;
2240                                 if (k_flag[pos]) pos--;
2241                         }
2242 #else
2243                         if (pos > 0) pos--;
2244 #endif
2245                         break;
2246
2247                 default:
2248 #ifdef JP
2249                         if (iskanji(i))
2250                         {
2251                                 int next;
2252
2253                                 inkey_base = TRUE;
2254                                 next = inkey ();
2255                                 if (pos + 1 < MAX_NLEN)
2256                                 {
2257                                         buf[pos++] = i;
2258                                         buf[pos] = next;
2259                                         k_flag[pos++] = 1;
2260                                 }
2261                                 else bell();
2262                         }
2263                         else if (pos < MAX_NLEN && isprint(i))
2264                         {
2265                                 buf[pos] = i;
2266                                 k_flag[pos++] = 0;
2267                         }
2268                         else bell();
2269 #else
2270                         if (pos < MAX_NLEN && isprint(i)) buf[pos++] = i;
2271                         else bell();
2272 #endif
2273                         break;
2274                 }
2275
2276                 /* Terminate */
2277                 buf[pos] = '\0';
2278
2279                 /* Update the entry */
2280                 Term_erase(col, 0, 255);
2281                 Term_putstr(col, 0, -1, TERM_WHITE, buf);
2282         }
2283
2284         /* Never reached */
2285 }
2286
2287
2288 /*
2289  * Search next line matches for o_ptr
2290  */
2291 static bool search_for_object(cptr *lines_list, object_type *o_ptr, int *cxp, int *cyp, bool forward)
2292 {
2293         int i;
2294         autopick_type an_entry, *entry = &an_entry;
2295         char o_name[MAX_NLEN];
2296
2297         object_desc(o_name, o_ptr, FALSE, 3);
2298
2299         /* Force to be lower case string */
2300         for (i = 0; o_name[i]; i++)
2301         {
2302 #ifdef JP
2303                 if (iskanji(o_name[i]))
2304                         i++;
2305                 else
2306 #endif
2307                 if (isupper(o_name[i]))
2308                         o_name[i] = tolower(o_name[i]);
2309         }
2310         
2311         i = *cyp;
2312
2313         while (1)
2314         {
2315                 if (forward)
2316                 {
2317                         if (!lines_list[++i]) break;
2318                 }
2319                 else
2320                 {
2321                         if (--i < 0) break;
2322                 }
2323
2324                 if (!autopick_new_entry(entry, lines_list[i])) continue;
2325
2326                 if (is_autopick_aux(o_ptr, entry, o_name))
2327                 {
2328                         *cxp = 0;
2329                         *cyp = i;
2330                         return TRUE;
2331                 }
2332         }
2333
2334         return FALSE;
2335 }
2336
2337
2338 /*
2339  * Search next line matches to the string
2340  */
2341 static bool search_for_string(cptr *lines_list, cptr search_str, int *cxp, int *cyp, bool forward)
2342 {
2343         int i = *cyp;
2344
2345         while (1)
2346         {
2347                 cptr pos;
2348
2349                 if (forward)
2350                 {
2351                         if (!lines_list[++i]) break;
2352                 }
2353                 else
2354                 {
2355                         if (--i < 0) break;
2356                 }
2357 #ifdef JP
2358                 pos = strstr_j(lines_list[i], search_str);
2359 #else
2360                 pos = strstr(lines_list[i], search_str);
2361 #endif
2362                 if (pos)
2363                 {
2364                         *cxp = (int)(pos - lines_list[i]);
2365                         *cyp = i;
2366                         return TRUE;
2367                 }
2368         }
2369
2370         return FALSE;
2371 }
2372
2373
2374 /*
2375  * Initialize auto-picker preference
2376  */
2377 void init_autopicker(void)
2378 {
2379         static const char easy_autopick_inscription[] = "(:=g";
2380         autopick_type entry;
2381         int i;
2382
2383         /* Clear old entries */
2384         for( i = 0; i < max_autopick; i++)
2385                 autopick_free_entry(&autopick_list[i]);
2386
2387         max_autopick = 0;
2388
2389         /* There is always one entry "=g" */
2390         autopick_new_entry(&entry, easy_autopick_inscription);
2391         autopick_list[max_autopick++] = entry;
2392 }
2393
2394
2395
2396 /*
2397  *  Process line for auto picker/destroyer.
2398  */
2399 errr process_pickpref_file_line(char *buf)
2400 {
2401         autopick_type entry;
2402         int i;
2403
2404         if (max_autopick == MAX_AUTOPICK)
2405                 return 1;
2406         
2407         /* Nuke illegal char */
2408         for(i = 0; buf[i]; i++)
2409         {
2410 #ifdef JP
2411                 if (iskanji(buf[i]))
2412                 {
2413                         i++;
2414                         continue;
2415                 }
2416 #endif
2417                 if (isspace(buf[i]) && buf[i] != ' ')
2418                         break;
2419         }
2420         buf[i] = 0;
2421         
2422         if (!autopick_new_entry(&entry, buf)) return 0;
2423
2424         /* Already has the same entry? */ 
2425         for(i = 0; i < max_autopick; i++)
2426                 if(!strcmp(entry.name, autopick_list[i].name)
2427                    && entry.flag[0] == autopick_list[i].flag[0]
2428                    && entry.flag[1] == autopick_list[i].flag[1]
2429                    && entry.dice == autopick_list[i].dice
2430                    && entry.bonus == autopick_list[i].bonus) return 0;
2431
2432         autopick_list[max_autopick++] = entry;
2433         return 0;
2434 }
2435
2436
2437 /*
2438  * Get a trigger key and insert ASCII string for the trigger
2439  */
2440 static bool insert_macro_line(cptr *lines_list, int cy)
2441 {
2442         char tmp[1024];
2443         char buf[1024];
2444         int i, n = 0;
2445
2446         /* Flush */
2447         flush();
2448
2449         /* Do not process macros */
2450         inkey_base = TRUE;
2451
2452         /* First key */
2453         i = inkey();
2454
2455         /* Read the pattern */
2456         while (i)
2457         {
2458                 /* Save the key */
2459                 buf[n++] = i;
2460
2461                 /* Do not process macros */
2462                 inkey_base = TRUE;
2463
2464                 /* Do not wait for keys */
2465                 inkey_scan = TRUE;
2466
2467                 /* Attempt to read a key */
2468                 i = inkey();
2469         }
2470
2471         /* Terminate */
2472         buf[n] = '\0';
2473
2474         /* Flush */
2475         flush();
2476
2477         /* Convert the trigger */
2478         ascii_to_text(tmp, buf);
2479
2480         /* Null */
2481         if(!tmp[0]) return FALSE;
2482
2483         /* Insert preference string */
2484         insert_return_code(lines_list, 0, cy);
2485         string_free(lines_list[cy]);
2486         lines_list[cy] = string_make(format("P:%s", tmp));
2487
2488         /* Insert blank action preference line */
2489         insert_return_code(lines_list, 0, cy);
2490         string_free(lines_list[cy]);
2491         lines_list[cy] = string_make("A:");
2492
2493         return TRUE;
2494 }
2495
2496
2497 /*
2498  * Get a command key and insert ASCII string for the key
2499  */
2500 static bool insert_keymap_line(cptr *lines_list, int cy)
2501 {
2502         char tmp[1024];
2503         char buf[2];
2504         int mode;
2505
2506         /* Roguelike */
2507         if (rogue_like_commands)
2508         {
2509                 mode = KEYMAP_MODE_ROGUE;
2510         }
2511
2512         /* Original */
2513         else
2514         {
2515                 mode = KEYMAP_MODE_ORIG;
2516         }
2517
2518         /* Flush */
2519         flush();
2520
2521         /* Get a key */
2522         buf[0] = inkey();
2523         buf[1] = '\0';
2524
2525         /* Flush */
2526         flush();
2527
2528         /* Convert the trigger */
2529         ascii_to_text(tmp, buf);
2530
2531         /* Null */
2532         if(!tmp[0]) return FALSE;
2533
2534         /* Insert preference string */
2535         insert_return_code(lines_list, 0, cy);
2536         string_free(lines_list[cy]);
2537         lines_list[cy] = string_make(format("C:%d:%s", mode, tmp));
2538
2539         /* Insert blank action preference line */
2540         insert_return_code(lines_list, 0, cy);
2541         string_free(lines_list[cy]);
2542         lines_list[cy] = string_make("A:");
2543
2544         return TRUE;
2545 }
2546
2547
2548 /*
2549  * Description of control commands
2550  */
2551
2552 #define WID_DESC 31
2553
2554 static cptr ctrl_command_desc[] =
2555 {
2556 #ifdef JP
2557 #define LAST_DESTROYED 6
2558         "^P ^N ^B ^F ¾å²¼º¸±¦¤Ë°ÜÆ°",
2559         "^A ^E ¹Ô¤ÎÀèƬ¡¢½ªÃ¼",
2560         "^Q ÆþÎÏ/¥³¥Þ¥ó¥É¥â¡¼¥ÉÀÚ¤êÂؤ¨",
2561         "^R Êѹ¹¤òÁ´¤Æ¼è¤ê¾Ã¤·¤Æ¸µ¤ËÌ᤹",
2562         "------------------------------------",
2563         "^I »ý¤Áʪ/ÁõÈ÷¤«¤éÁªÂò",
2564         "^L",
2565         "^K ¥«¡¼¥½¥ë¤«¤é½ªÃ¼¤Þ¤Çºï½ü",
2566         "^Y ºï½ü(^K)¤·¤¿¹Ô¤òÁÞÆþ",
2567         "^C ¼ï²¡¢¿¦¶È¤Î¾ò·ï¼°¤òÁÞÆþ",
2568         "------------------------------------",
2569         "^S Êѹ¹ (!Ç˲õ/~ÊüÃÖ/½¦¤¦)",
2570         "^G \"(\" Á´ÂΥޥåפÇɽ¼¨¤·¤Ê¤¤",
2571         "^O \"#\" ¼«Æ°¹ï¤ß",
2572         "------------------------------------",
2573         "^U Ì¤´ÕÄê/̤ȽÌÀ/´ÕÄê/*´ÕÄê*",
2574         "^W \"̵²ÁÃͤÎ\"",
2575         "^X ÌµÌÃ/¥¨¥´/¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È",
2576         "^Z \"¼ý½¸Ãæ¤Î\"",
2577         NULL
2578 #else
2579 #define LAST_DESTROYED 6
2580         "^P ^N ^B ^F Move Cursor",
2581         "^A ^E Beginning and End of Line",
2582         "^Q Toggle Insert/Command mode",
2583         "^R Revert to Original File",
2584         "------------------------------------",
2585         "^I Object in Inventry/Equipment",
2586         "^L",
2587         "^K Kill Rest of Line",
2588         "^Y Insert killed(^K) text",
2589         "^C Insert conditional expression",
2590         "------------------------------------",
2591         "^S Toggle(!Destroy/~Leave/Pick)",
2592         "^G \"(\" No display in the 'M'ap",
2593         "^O \"#\" Auto-Inscribe",
2594         "------------------------------------",
2595         "^U Toggle 'identified' state",
2596         "^W \"worthless\"",
2597         "^X Toggle nameless/ego/artifact",
2598         "^Z \"collecting\"",
2599         NULL
2600 #endif
2601 };
2602
2603
2604 #define MAX_YANK MAX_LINELEN
2605 #define DIRTY_ALL 0x01
2606 #define DIRTY_COMMAND 0x02
2607 #define DIRTY_MODE 0x04
2608 #define DIRTY_SCREEN 0x08
2609 #define DIRTY_NOT_FOUND 0x10
2610 #define DIRTY_NO_SEARCH 0x20
2611
2612 /*
2613  * In-game editor of Object Auto-picker/Destoryer
2614  */
2615 void do_cmd_edit_autopick(void)
2616 {
2617         static int cx = 0, cy = 0;
2618         static int upper = 0, left = 0;
2619
2620         object_type *search_o_ptr = NULL;
2621         cptr search_str = NULL;
2622         cptr last_destroyed = NULL;
2623         char last_destroyed_command[WID_DESC+3];
2624         char yank_buf[MAX_YANK];
2625         char classrace[80];
2626         autopick_type an_entry, *entry = &an_entry;
2627         char buf[MAX_LINELEN];
2628         cptr *lines_list;
2629         int filename_mode = PT_WITH_PNAME;
2630
2631         int i, j, k, len;
2632         cptr tmp;
2633
2634         int old_upper = -1, old_left = -1;
2635         int old_cy = -1;
2636         int key = -1, old_key;
2637         bool repeated_clearing = FALSE;
2638         bool edit_mode = FALSE;
2639
2640         byte dirty_flags = DIRTY_ALL | DIRTY_COMMAND | DIRTY_MODE;
2641         int dirty_line = -1;
2642
2643         int wid, hgt, old_wid = -1, old_hgt = -1;
2644
2645         static s32b old_autosave_turn = 0L;
2646
2647         /* Autosave */
2648         if (turn > old_autosave_turn + 100L)
2649         {
2650                 do_cmd_save_game(TRUE);
2651                 old_autosave_turn = turn;
2652         }
2653
2654         /* HACK -- Reset start_time to stop counting playtime while edit */
2655         update_playtime();
2656
2657         /* Free old entries */
2658         init_autopicker();
2659
2660         /* Command Description of the 'Last Destroyed Item' */
2661         if (autopick_last_destroyed_object.k_idx)
2662         {
2663                 autopick_entry_from_object(entry, &autopick_last_destroyed_object);
2664                 last_destroyed = autopick_line_from_entry_kill(entry);
2665
2666                 my_strcpy(last_destroyed_command, format("^L \"%s\"", last_destroyed), sizeof(last_destroyed_command));
2667         }
2668         else
2669         {
2670 #ifdef JP
2671                 strcpy(last_destroyed_command, "^L ºÇ¸å¤Ë¼«Æ°Ç˲õ¤·¤¿¥¢¥¤¥Æ¥à̾");
2672 #else
2673                 strcpy(last_destroyed_command, "^L Last destroyed object");
2674 #endif
2675         }
2676         ctrl_command_desc[LAST_DESTROYED] = last_destroyed_command;
2677
2678         /* Conditional Expression for Class and Race */
2679         sprintf(classrace, "?:[AND [EQU $RACE %s] [EQU $CLASS %s]]", 
2680 #ifdef JP
2681                 rp_ptr->E_title, cp_ptr->E_title
2682 #else
2683                 rp_ptr->title, cp_ptr->title
2684 #endif
2685                 );
2686
2687         /* Clear yank buffer */
2688         yank_buf[0] = '\0';
2689
2690         /* Read or initialize whole text */
2691         lines_list = read_pickpref_text_lines(&filename_mode);
2692
2693         /* Reset cursor position if needed */
2694         for (i = 0; i < cy; i++)
2695         {
2696                 if (!lines_list[i])
2697                 {
2698                         cy = cx = 0;
2699                         break;
2700                 }
2701         }
2702
2703         /* Save the screen */
2704         screen_save();
2705
2706         /* Process requests until done */
2707         while (1)
2708         {
2709                 /* Get size */
2710                 Term_get_size(&wid, &hgt);
2711
2712 #ifdef JP
2713                 /* Don't let cursor at second byte of kanji */
2714                 for (i = 0; lines_list[cy][i]; i++)
2715                         if (iskanji(lines_list[cy][i]))
2716                         {
2717                                 i++;
2718                                 if (i == cx)
2719                                 {
2720                                         cx--;
2721                                         break;
2722                                 }
2723                         }
2724 #endif
2725
2726                 /* Scroll if necessary */
2727                 if (cy < upper || upper + hgt - 4 <= cy)
2728                         upper = cy - (hgt-4)/2;
2729                 if (upper < 0)
2730                         upper = 0;
2731                 if ((cx < left + 10 && left > 0) || left + wid - WID_DESC - 5 <= cx)
2732                         left = cx - (wid - WID_DESC)*2/3;
2733                 if (left < 0)
2734                         left = 0;
2735
2736                 /* Redraw whole window after resize */
2737                 if (old_wid != wid || old_hgt != hgt)
2738                         dirty_flags |= DIRTY_SCREEN;
2739
2740                 /* Redraw all text after scroll */
2741                 else if (old_upper != upper || old_left != left)
2742                         dirty_flags |= DIRTY_ALL;
2743
2744
2745                 if (dirty_flags & DIRTY_SCREEN)
2746                 {
2747                         dirty_flags |= (DIRTY_ALL | DIRTY_COMMAND | DIRTY_MODE);
2748
2749                         /* Clear screen */
2750                         Term_clear();
2751                 }
2752
2753                 if (dirty_flags & DIRTY_COMMAND)
2754                 {
2755                         /* Display control command */
2756                         for (i = 0; ctrl_command_desc[i]; i++)
2757                                 Term_putstr(wid - WID_DESC, i + 1, WID_DESC, TERM_WHITE, ctrl_command_desc[i]);
2758                 }
2759
2760                 /* Redraw mode line */
2761                 if (dirty_flags & DIRTY_MODE)
2762                 {
2763                         int sepa_length = wid - WID_DESC;
2764
2765                         /* Separator */
2766                         for (i = 0; i < sepa_length; i++)
2767                                 buf[i] = '-';
2768                         buf[i] = '\0';
2769
2770                         /* Mode line */
2771                         if (edit_mode)
2772                                 strncpy(buf + sepa_length - 21, " (INSERT MODE)  ", 16);
2773                         else
2774                                 strncpy(buf + sepa_length - 21, " (COMMAND MODE) ", 16);
2775
2776                         Term_putstr(0, hgt - 3, sepa_length, (byte) (edit_mode ? TERM_YELLOW : TERM_WHITE), buf);
2777                 }
2778                 
2779                 /* Dump up to 20, or hgt-4, lines of messages */
2780                 for (i = 0; i < hgt - 4; i++)
2781                 {
2782                         int leftcol = 0;
2783                         cptr msg;
2784
2785                         /* clean or dirty? */
2786                         if (!(dirty_flags & DIRTY_ALL) && (dirty_line != upper+i))
2787                                 continue;
2788
2789                         msg = lines_list[upper+i];
2790                         if (!msg) break;
2791
2792                         /* Apply horizontal scroll */
2793                         for (j = 0; *msg; msg++, j++)
2794                         {
2795                                 if (j == left) break;
2796 #ifdef JP
2797                                 if (j > left)
2798                                 {
2799                                         leftcol = 1;
2800                                         break;
2801                                 }
2802                                 if (iskanji(*msg))
2803                                 {
2804                                         msg++;
2805                                         j++;
2806                                 }
2807 #endif
2808                         }
2809
2810                         /* Erase line */
2811                         Term_erase(0, i + 1, wid - WID_DESC);
2812
2813                         /* Dump the messages, bottom to top */
2814                         Term_putstr(leftcol, i + 1, wid - WID_DESC - 1, TERM_WHITE, msg);
2815                 }
2816
2817                 for (; i < hgt - 4; i++)
2818                 {
2819                         /* Erase line */
2820                         Term_erase(0, i + 1, wid - WID_DESC);
2821                 }
2822
2823                 /* Display header line */
2824 #ifdef JP
2825                 if (edit_mode)
2826                         prt("^Q ESC ¤Ç¥³¥Þ¥ó¥É¥â¡¼¥É¤Ø°Ü¹Ô¡¢Ä̾ï¤Îʸ»ú¤Ï¤½¤Î¤Þ¤ÞÆþÎÏ", 0, 0);
2827                 else
2828                         prt("q _ ¤Ç½ªÎ»¡¢hjkl2468 ¤Ç°ÜÆ°¡¢^Q a i ¤ÇÆþÎϥ⡼¥É¡¢/ n N ¤Ç¸¡º÷", 0, 0);
2829 #else   
2830                 if (edit_mode)
2831                         prt("Press ^Q ESC to command mode, any letters to insert", 0, 0);
2832                 else
2833                         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);
2834 #endif
2835                 /* Display current position */
2836                 prt (format("(%d,%d)", cx, cy), 0, 70);
2837
2838                 /* Display information when updated */
2839                 if (old_cy != cy || (dirty_flags & (DIRTY_ALL | DIRTY_NOT_FOUND | DIRTY_NO_SEARCH)) || dirty_line == cy)
2840                 {
2841                         /* Clear information line */
2842                         Term_erase(0, hgt - 3 + 1, wid);
2843                         Term_erase(0, hgt - 3 + 2, wid);
2844
2845                         /* Display information */
2846                         if (dirty_flags & DIRTY_NOT_FOUND)
2847                         {
2848 #ifdef JP
2849                                 prt(format("¥Ñ¥¿¡¼¥ó¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s", search_str), hgt - 3 + 1, 0);
2850 #else
2851                                 prt(format("Pattern not found: %s", search_str), hgt - 3 + 1, 0);
2852 #endif
2853                         }
2854                         else if (dirty_flags & DIRTY_NO_SEARCH)
2855                         {
2856 #ifdef JP
2857                                 prt("¸¡º÷Ãæ¤Î¥Ñ¥¿¡¼¥ó¤¬¤¢¤ê¤Þ¤»¤ó('/'¤Ç¸¡º÷)¡£", hgt - 3 + 1, 0);
2858 #else
2859                                 prt("No pattern to search. (Press '/' to search.)", hgt - 3 + 1, 0);
2860 #endif
2861                         }
2862                         else if (lines_list[cy][0] == '#')
2863                         {
2864 #ifdef JP
2865                                 prt("¤³¤Î¹Ô¤Ï¥³¥á¥ó¥È¤Ç¤¹¡£", hgt - 3 + 1, 0);
2866 #else
2867                                 prt("This line is comment.", hgt - 3 + 1, 0);
2868 #endif
2869                         }
2870                         else if (lines_list[cy][1] == ':')
2871                         {
2872                                 switch(lines_list[cy][0])
2873                                 {
2874                                 case '?':
2875 #ifdef JP
2876                                         prt("¤³¤Î¹Ô¤Ï¾ò·ïʬ´ô¼°¤Ç¤¹¡£", hgt - 3 + 1, 0);
2877 #else
2878                                         prt("This line is Conditional Expression.", hgt - 3 + 1, 0);
2879 #endif
2880                                         break;
2881                                 case 'A':
2882 #ifdef JP
2883                                         prt("¤³¤Î¹Ô¤Ï¥Þ¥¯¥í¤Î¼Â¹ÔÆâÍƤòÄêµÁ¤·¤Þ¤¹¡£", hgt - 3 + 1, 0);
2884 #else
2885                                         prt("This line defines Macro action.", hgt - 3 + 1, 0);
2886 #endif
2887                                         break;
2888                                 case 'P':
2889 #ifdef JP
2890                                         prt("¤³¤Î¹Ô¤Ï¥Þ¥¯¥í¤Î¥È¥ê¥¬¡¼¡¦¥­¡¼¤òÄêµÁ¤·¤Þ¤¹¡£", hgt - 3 + 1, 0);
2891 #else
2892                                         prt("This line defines Macro trigger key.", hgt - 3 + 1, 0);
2893 #endif
2894                                         break;
2895                                 case 'C':
2896 #ifdef JP
2897                                         prt("¤³¤Î¹Ô¤Ï¥­¡¼ÇÛÃÖ¤òÄêµÁ¤·¤Þ¤¹¡£", hgt - 3 + 1, 0);
2898 #else
2899                                         prt("This line defines Keymap.", hgt - 3 + 1, 0);
2900 #endif
2901                                         break;
2902                                 }
2903                         }
2904
2905                         /* Get description of an autopicker preference line */
2906                         else if (autopick_new_entry(entry, lines_list[cy]))
2907                         {
2908                                 char temp[1024];
2909                                 cptr t;
2910
2911                                 describe_autopick(buf, entry);
2912
2913                                 roff_to_buf(buf, 81, temp);
2914                                 t = temp;
2915                                 for (i = 0; i< 2; i++)
2916                                 {
2917                                         if(t[0] == 0)
2918                                                 break; 
2919                                         else
2920                                         {
2921                                                 prt(t, hgt - 3 + 1 + i, 0);
2922                                                 t += strlen(t) + 1;
2923                                         }
2924                                 }
2925                                 autopick_free_entry(entry);
2926                         }
2927                 }
2928
2929                 /* Place cursor */
2930                 Term_gotoxy(cx - left, cy - upper + 1);
2931
2932                 /* Now clean */
2933                 dirty_flags = 0;
2934                 dirty_line = -1;
2935
2936                 /* Save old key and location */
2937                 old_cy = cy;
2938                 old_key = key;
2939                 old_upper = upper;
2940                 old_left = left;
2941                 old_wid = wid;
2942                 old_hgt = hgt;
2943
2944                 /* Do not process macros except special keys */
2945                 inkey_special = TRUE;
2946
2947                 /* Get a command */
2948                 key = inkey();
2949
2950                 if (edit_mode)
2951                 {
2952                         if (key == ESCAPE)
2953                         {
2954                                 edit_mode = FALSE;
2955
2956                                 /* Mode line is now dirty */
2957                                 dirty_flags |= DIRTY_MODE;
2958                         }
2959
2960                         /* Insert a character */
2961                         else if (!iscntrl(key&0xff))
2962                         {
2963                                 int next;
2964
2965                                 /* Save preceding string */
2966                                 for (i = j = 0; lines_list[cy][i] && i < cx; i++)
2967                                         buf[j++] = lines_list[cy][i];
2968
2969                                 /* Add a character */
2970 #ifdef JP
2971                                 if (iskanji(key))
2972                                 {
2973                                         inkey_base = TRUE;
2974                                         next = inkey();
2975                                         if (j+2 < MAX_LINELEN)
2976                                         {
2977                                                 buf[j++] = key;
2978                                                 buf[j++] = next;
2979                                                 cx += 2;
2980                                         }
2981                                         else
2982                                                 bell();
2983                                 }
2984                                 else
2985 #endif
2986                                 {
2987                                         if (j+1 < MAX_LINELEN)
2988                                                 buf[j++] = key;
2989                                         cx++;
2990                                 }
2991
2992                                 /* Add following */
2993                                 for (; lines_list[cy][i] && j + 1 < MAX_LINELEN; i++)
2994                                         buf[j++] = lines_list[cy][i];
2995                                 buf[j] = '\0';
2996
2997                                 /* Replace current line with new line */
2998                                 string_free(lines_list[cy]);
2999                                 lines_list[cy] = string_make(buf);
3000
3001                                 /* Move to correct collumn */
3002                                 len = strlen(lines_list[cy]);
3003                                 if (len < cx) cx = len;
3004
3005                                 /* Now dirty */
3006                                 dirty_line = cy;
3007                         }
3008                 }
3009                 else
3010                 {
3011                         /* Exit on 'q' */
3012                         if (key == 'q' || key == '_') break;
3013
3014                         switch(key)
3015                         {
3016                         case 'a': case 'i':
3017                                 edit_mode = TRUE;
3018
3019                                 /* Mode line is now dirty */
3020                                 dirty_flags |= DIRTY_MODE;
3021                                 break;
3022                         case '~':
3023                                 if (!autopick_new_entry(entry, lines_list[cy]))
3024                                 {
3025                                         if (old_key != key) repeated_clearing = FALSE;
3026
3027                                         /* Next line */
3028                                         if (lines_list[cy + 1]) cy++;
3029                                         cx = 0;
3030                                         break;
3031                                 }
3032                                 string_free(lines_list[cy]);
3033
3034                                 if (old_key != key)
3035                                 {
3036                                         if (entry->action & DONT_AUTOPICK)
3037                                                 repeated_clearing = TRUE;
3038                                         else
3039                                                 repeated_clearing = FALSE;
3040                                 }
3041
3042                                 entry->action &= ~DO_AUTODESTROY;
3043                                 entry->action &= ~DO_QUERY_AUTOPICK;
3044                                 if (!repeated_clearing)
3045                                 {
3046                                         entry->action &= ~DO_AUTOPICK;
3047                                         entry->action |= DONT_AUTOPICK;
3048                                 }
3049                                 else 
3050                                 {
3051                                         entry->action &= ~DONT_AUTOPICK;
3052                                         entry->action |= DO_AUTOPICK;
3053                                 }
3054
3055                                 lines_list[cy] = autopick_line_from_entry_kill(entry);
3056
3057                                 /* Now dirty */
3058                                 dirty_line = cy;
3059
3060                                 /* Next line */
3061                                 if (lines_list[cy + 1]) cy++;
3062                                 cx = 0;
3063                                 break;
3064                         case '!':
3065                                 if (!autopick_new_entry(entry, lines_list[cy]))
3066                                 {
3067                                         if (old_key != key) repeated_clearing = FALSE;
3068
3069                                         /* Next line */
3070                                         if (lines_list[cy + 1]) cy++;
3071                                         cx = 0;
3072                                         break;
3073                                 }
3074                                 string_free(lines_list[cy]);
3075
3076                                 if (old_key != key)
3077                                 {
3078                                         if (entry->action & DO_AUTODESTROY)
3079                                                 repeated_clearing = TRUE;
3080                                         else
3081                                                 repeated_clearing = FALSE;
3082                                 }
3083
3084                                 entry->action &= ~DONT_AUTOPICK;
3085                                 entry->action &= ~DO_QUERY_AUTOPICK;
3086                                 if (!repeated_clearing)
3087                                 {
3088                                         entry->action &= ~DO_AUTOPICK;
3089                                         entry->action |= DO_AUTODESTROY;
3090                                 }
3091                                 else 
3092                                 {
3093                                         entry->action &= ~DO_AUTODESTROY;
3094                                         entry->action |= DO_AUTOPICK;
3095                                 }
3096
3097                                 lines_list[cy] = autopick_line_from_entry_kill(entry);
3098
3099                                 /* Now dirty */
3100                                 dirty_line = cy;
3101
3102                                 /* Next line */
3103                                 if (lines_list[cy + 1]) cy++;
3104                                 cx = 0;
3105                                 break;
3106                         case ';':
3107                                 if (!autopick_new_entry(entry, lines_list[cy]))
3108                                 {
3109                                         if (old_key != key) repeated_clearing = FALSE;
3110
3111                                         /* Next line */
3112                                         if (lines_list[cy + 1]) cy++;
3113                                         cx = 0;
3114                                         break;
3115                                 }
3116                                 string_free(lines_list[cy]);
3117
3118                                 if (old_key != key)
3119                                 {
3120                                         if (entry->action & DO_QUERY_AUTOPICK)
3121                                                 repeated_clearing = TRUE;
3122                                         else
3123                                                 repeated_clearing = FALSE;
3124                                 }
3125
3126                                 entry->action &= ~DO_AUTODESTROY;
3127                                 entry->action &= ~DONT_AUTOPICK;
3128                                 if (!repeated_clearing)
3129                                 {
3130                                         entry->action &= ~DO_AUTOPICK;
3131                                         entry->action |= DO_QUERY_AUTOPICK;
3132                                 }
3133                                 else 
3134                                 {
3135                                         entry->action &= ~DO_QUERY_AUTOPICK;
3136                                         entry->action |= DO_AUTOPICK;
3137                                 }
3138
3139                                 lines_list[cy] = autopick_line_from_entry_kill(entry);
3140
3141                                 /* Now dirty */
3142                                 dirty_line = cy;
3143
3144                                 /* Next line */
3145                                 if (lines_list[cy + 1]) cy++;
3146                                 cx = 0;
3147                                 break;
3148                         case '(':
3149                                 /* Toggle display on the 'M'ap */
3150                                 if (!autopick_new_entry(entry, lines_list[cy]))
3151                                 {
3152                                         if (old_key != key) repeated_clearing = FALSE;
3153
3154                                         /* Next line */
3155                                         if (lines_list[cy + 1]) cy++;
3156                                         cx = 0;
3157                                         break;
3158                                 }
3159                                 string_free(lines_list[cy]);
3160
3161                                 if (old_key != key)
3162                                 {
3163                                         if (entry->action & DO_DISPLAY)
3164                                                 repeated_clearing = TRUE;
3165                                         else
3166                                                 repeated_clearing = FALSE;
3167                                 }
3168
3169                                 if (!repeated_clearing)
3170                                         entry->action |= DO_DISPLAY;
3171                                 else
3172                                         entry->action &= ~DO_DISPLAY;
3173
3174                                 lines_list[cy] = autopick_line_from_entry_kill(entry);
3175
3176                                 /* Now dirty */
3177                                 dirty_line = cy;
3178
3179                                 /* Next line */
3180                                 if (lines_list[cy + 1]) cy++;
3181                                 cx = 0;
3182                                 break;
3183                         case '#':
3184                         case '{':
3185                                 key = KTRL('o');
3186                                 break;
3187                         case 'h': case '4':
3188                                 key = KTRL('b');
3189                                 break;
3190                         case 'l': case '6':
3191                                 key = KTRL('f');
3192                                 break;
3193                         case 'j': case '2':
3194                                 key = KTRL('n');
3195                                 break;
3196                         case 'k': case '8':
3197                                 key = KTRL('p');
3198                                 break;
3199                         case ' ':
3200                                 while (cy < upper + hgt-4 && lines_list[cy + 1])
3201                                         cy++;
3202                                 upper = cy;
3203                                 break;
3204                         case '-': case 'b':
3205                                 while (0 < cy && upper <= cy)
3206                                         cy--;
3207                                 while (0 < upper && cy + 1 < upper + hgt - 4)
3208                                         upper--;
3209                                 break;
3210
3211                         case 'g':
3212                                 cy = 0;
3213                                 break;
3214
3215                         case 'G':
3216                                 while (lines_list[cy + 1])
3217                                         cy++;
3218                                 break;
3219
3220                         case 'm':
3221                                 /* Erase line */
3222                                 Term_erase(0, cy - upper + 1, wid - WID_DESC);
3223
3224                                 /* Prompt */
3225 #ifdef JP
3226                                 Term_putstr(0, cy - upper + 1, wid - WID_DESC - 1, TERM_YELLOW, "P:<¥È¥ê¥¬¡¼¥­¡¼>: ");
3227 #else
3228                                 Term_putstr(0, cy - upper + 1, wid - WID_DESC - 1, TERM_YELLOW, "P:<Trigger key>: ");
3229 #endif
3230                                 if (insert_macro_line(lines_list, cy))
3231                                 {
3232                                         /* Prepare to input action */
3233                                         cx = 2;
3234                                         edit_mode = TRUE;
3235
3236                                         /* Now dirty */
3237                                         dirty_flags |= DIRTY_ALL;
3238                                         dirty_flags |= DIRTY_MODE;
3239                                 }
3240
3241                                 break;
3242
3243                         case 'c':
3244                                 /* Erase line */
3245                                 Term_erase(0, cy - upper + 1, wid - WID_DESC);
3246
3247                                 /* Prompt */
3248 #ifdef JP
3249                                 Term_putstr(0, cy - upper + 1, wid - WID_DESC - 1, TERM_YELLOW, format("C:%d:<¥³¥Þ¥ó¥É¥­¡¼>: ", (rogue_like_commands ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG)));
3250 #else
3251                                 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)));
3252 #endif
3253
3254                                 if (insert_keymap_line(lines_list, cy))
3255                                 {
3256                                         /* Prepare to input action */
3257                                         cx = 2;
3258                                         edit_mode = TRUE;
3259
3260                                         /* Now dirty */
3261                                         dirty_flags |= DIRTY_ALL;
3262                                         dirty_flags |= DIRTY_MODE;
3263                                 }                               
3264                                 break;
3265                         case '/':
3266                                 /* Become dirty because of item/equip menu */
3267                                 dirty_flags |= DIRTY_SCREEN;
3268
3269                                 if (!get_string_for_search(&search_o_ptr, &search_str))
3270                                         break;
3271
3272                                 /* fall through */
3273                         case 'n':
3274                                 if (search_o_ptr)
3275                                 {
3276                                         if (!search_for_object(lines_list, search_o_ptr, &cx, &cy, TRUE)) dirty_flags |= DIRTY_NOT_FOUND;
3277                                 }
3278                                 else if (search_str)
3279                                 {
3280                                         if (!search_for_string(lines_list, search_str, &cx, &cy, TRUE)) dirty_flags |= DIRTY_NOT_FOUND;
3281                                 }
3282                                 else
3283                                 {
3284                                         dirty_flags |= DIRTY_NO_SEARCH;
3285                                 }
3286                                 break;
3287                         case 'N':
3288                                 if (search_o_ptr)
3289                                 {
3290                                         if (!search_for_object(lines_list, search_o_ptr, &cx, &cy, FALSE)) dirty_flags |= DIRTY_NOT_FOUND;
3291                                 }
3292                                 else if (search_str)
3293                                 {
3294                                         if (!search_for_string(lines_list, search_str, &cx, &cy, FALSE)) dirty_flags |= DIRTY_NOT_FOUND;
3295                                 }
3296                                 else
3297                                 {
3298                                         dirty_flags |= DIRTY_NO_SEARCH;
3299                                 }
3300                                 break;
3301                         }
3302                 }
3303
3304                 switch(key)
3305                 {
3306                 case KTRL('a'):
3307                         /* Beginning of line */
3308                         cx = 0;
3309                         break;
3310                 case KTRL('b'):
3311                         /* Back */
3312                         if (0 < cx)
3313                         {
3314                                 cx--;
3315                                 len = strlen(lines_list[cy]);
3316                                 if (len < cx) cx = len;
3317                         }
3318                         else if (cy > 0)
3319                         {
3320                                 cy--;
3321                                 cx = strlen(lines_list[cy]);
3322                         }
3323                         break;
3324                 case KTRL('c'):
3325                         /* Insert a conditinal expression line */
3326                         insert_return_code(lines_list, 0, cy);
3327                         string_free(lines_list[cy]);
3328                         lines_list[cy] = string_make(classrace);
3329                         cy++;
3330                         insert_return_code(lines_list, 0, cy);
3331                         string_free(lines_list[cy]);
3332                         lines_list[cy] = string_make("?:1");
3333                         cx = 0;
3334
3335                         /* Now dirty */
3336                         dirty_flags |= DIRTY_ALL;
3337                         break;
3338                 case KTRL('e'):
3339                         /* End of line */
3340                         cx = strlen(lines_list[cy]);
3341                         break;
3342                 case KTRL('f'):
3343                         /* Forward */
3344 #ifdef JP
3345                         if (iskanji(lines_list[cy][cx])) cx++;
3346 #endif
3347                         cx++;
3348                         len = strlen(lines_list[cy]);
3349                         if (len < cx)
3350                         {
3351                                 if (lines_list[cy + 1])
3352                                 {
3353                                         cy++;
3354                                         cx = 0;
3355                                 }
3356                                 else
3357                                         cx = len;
3358                         }
3359                         break;
3360                 case KTRL('g'):
3361                         /* Toggle display on the 'M'ap */
3362                         if (!autopick_new_entry(entry, lines_list[cy]))
3363                                 break;
3364                         string_free(lines_list[cy]);
3365
3366                         if (entry->action & DO_DISPLAY)
3367                         {
3368                                 entry->action &= ~DO_DISPLAY;
3369                                 cx++;
3370                         }
3371                         else
3372                         {
3373                                 entry->action |= DO_DISPLAY;
3374                                 if (cx > 0) cx--;
3375                         }
3376
3377                         lines_list[cy] = autopick_line_from_entry_kill(entry);
3378
3379                         /* Now dirty */
3380                         dirty_line = cy;
3381                         break;
3382                 case KTRL('i'):
3383                         /* Insert choosen item name */
3384                         if (!entry_from_choosed_object(entry))
3385                         {
3386                                 /* Now dirty because of item/equip menu */
3387                                 dirty_flags |= DIRTY_SCREEN;
3388                                 break;
3389                         }
3390
3391                         insert_return_code(lines_list, 0, cy);
3392                         string_free(lines_list[cy]);
3393                         lines_list[cy] = autopick_line_from_entry_kill(entry);
3394                         cx = 0;
3395
3396                         /* Now dirty because of item/equip menu */
3397                         dirty_flags |= DIRTY_SCREEN;
3398
3399                         break;
3400                 case KTRL('l'):
3401                         /* Insert a name of last destroyed item */
3402                         if (last_destroyed)
3403                         {
3404                                 insert_return_code(lines_list, 0, cy);
3405                                 string_free(lines_list[cy]);
3406                                 lines_list[cy] = string_make(last_destroyed);
3407                                 cx = 0;
3408
3409                                 /* Now dirty */
3410                                 dirty_flags |= DIRTY_ALL;
3411                         }
3412                         break;
3413                 case '\n': case '\r':
3414                         /* Split a line or insert end of line */
3415                         insert_return_code(lines_list, cx, cy);
3416                         cy++;
3417                         cx = 0;
3418
3419                         /* Now dirty */
3420                         dirty_flags |= DIRTY_ALL;
3421                         break;
3422                 case KTRL('n'):
3423                         /* Next line */
3424                         if (lines_list[cy + 1]) cy++;
3425                         break;
3426                 case KTRL('o'):
3427                         /* Prepare to write auto-inscription text */
3428                         if (!autopick_new_entry(entry, lines_list[cy]))
3429                                 break;
3430                         string_free(lines_list[cy]);
3431
3432                         if (!entry->insc) entry->insc = string_make("");
3433
3434                         lines_list[cy] = autopick_line_from_entry_kill(entry);
3435
3436                         /* Move to collumn for auto inscription */
3437                         for (cx = 0; lines_list[cy][cx]; cx++)
3438                                 if (lines_list[cy][cx] == '#') break;
3439                         cx++;
3440                         edit_mode = TRUE;
3441
3442                         /* Now dirty */
3443                         dirty_line = cy;
3444                         dirty_flags |= DIRTY_MODE;
3445                         break;
3446                 case KTRL('p'):
3447                         /* Previous line */
3448                         if (cy > 0) cy--;
3449                         break;
3450                 case KTRL('q'):
3451                         /* Change mode */
3452                         edit_mode = !edit_mode;
3453                         
3454                         /* Mode line is now dirty */
3455                         dirty_flags |= DIRTY_MODE;
3456                         break;
3457                 case KTRL('r'):
3458                         /* Revert to original */
3459 #ifdef JP
3460                         if (!get_check("Á´¤Æ¤ÎÊѹ¹¤òÇË´þ¤·¤Æ¸µ¤Î¾õÂÖ¤ËÌᤷ¤Þ¤¹¡£¤è¤í¤·¤¤¤Ç¤¹¤«¡© "))
3461 #else
3462                         if (!get_check("Discard all change and revert to original file. Are you sure? "))
3463 #endif
3464                                 break;
3465
3466                         free_text_lines(lines_list);
3467                         lines_list = read_pickpref_text_lines(&filename_mode);
3468                         dirty_flags |= DIRTY_ALL | DIRTY_MODE;
3469                         cx = cy = 0;
3470                         edit_mode = FALSE;
3471                         break;
3472                 case KTRL('s'):
3473                         /* Rotate action; pickup/destroy/leave */
3474                         if (!autopick_new_entry(entry, lines_list[cy]))
3475                                 break;
3476                         string_free(lines_list[cy]);
3477
3478                         if (entry->action & DO_AUTOPICK)
3479                         {
3480                                 entry->action &= ~DO_AUTOPICK;
3481                                 entry->action |= DO_AUTODESTROY;
3482                         }
3483                         else if (entry->action & DO_AUTODESTROY)
3484                         {
3485                                 entry->action &= ~DO_AUTODESTROY;
3486                                 entry->action |= DONT_AUTOPICK;
3487                         }
3488                         else if (entry->action & DONT_AUTOPICK)
3489                         {
3490                                 entry->action &= ~DONT_AUTOPICK;
3491                                 entry->action |= DO_AUTOPICK;
3492                         }
3493
3494                         lines_list[cy] = autopick_line_from_entry_kill(entry);
3495
3496                         /* Now dirty */
3497                         dirty_line = cy;
3498
3499                         break;
3500                 case KTRL('t'):
3501                         /* Nothing */
3502                         break;
3503                 case KTRL('u'):
3504                         /* Rotate identify-state; identified/unidentified/... */
3505                         if (!autopick_new_entry(entry, lines_list[cy]))
3506                                 break;
3507                         string_free(lines_list[cy]);
3508
3509                         if (IS_FLG(FLG_UNIDENTIFIED)) 
3510                         {
3511                                 REM_FLG(FLG_UNIDENTIFIED);
3512                                 ADD_FLG(FLG_UNAWARE);
3513                                 REM_FLG(FLG_IDENTIFIED);
3514                                 REM_FLG(FLG_STAR_IDENTIFIED);
3515                         }
3516                         else if (IS_FLG(FLG_UNAWARE)) 
3517                         {
3518                                 REM_FLG(FLG_UNIDENTIFIED);
3519                                 REM_FLG(FLG_UNAWARE);
3520                                 ADD_FLG(FLG_IDENTIFIED);
3521                                 REM_FLG(FLG_STAR_IDENTIFIED);
3522                         }
3523                         else if (IS_FLG(FLG_STAR_IDENTIFIED)) 
3524                         {
3525                                 REM_FLG(FLG_UNIDENTIFIED);
3526                                 REM_FLG(FLG_UNAWARE);
3527                                 REM_FLG(FLG_IDENTIFIED);
3528                                 REM_FLG(FLG_STAR_IDENTIFIED);
3529                         }
3530                         else if (IS_FLG(FLG_IDENTIFIED)) 
3531                         {
3532                                 REM_FLG(FLG_UNIDENTIFIED);
3533                                 REM_FLG(FLG_UNAWARE);
3534                                 REM_FLG(FLG_IDENTIFIED);
3535                                 ADD_FLG(FLG_STAR_IDENTIFIED);
3536                         }
3537                         else
3538                         {
3539                                 ADD_FLG(FLG_UNIDENTIFIED);
3540                                 REM_FLG(FLG_UNAWARE);
3541                                 REM_FLG(FLG_IDENTIFIED);
3542                                 REM_FLG(FLG_STAR_IDENTIFIED);
3543                         }
3544
3545                         lines_list[cy] = autopick_line_from_entry_kill(entry);
3546
3547                         /* Now dirty */
3548                         dirty_line = cy;
3549                         break;
3550                 case KTRL('v'):
3551                         /* Scroll up */
3552                         while (cy < upper + hgt-4 && lines_list[cy + 1])
3553                                 cy++;
3554                         upper = cy;
3555                         break;
3556                 case KTRL('w'):
3557                         /* Toggle 'worthless' */
3558                         toggle_string(lines_list, FLG_WORTHLESS, cy);
3559                         /* Now dirty */
3560                         dirty_line = cy;
3561                         break;
3562                 case KTRL('x'):
3563                         /* Rotate within nameless, ego, artifact */
3564                         if (!autopick_new_entry(entry, lines_list[cy]))
3565                                 break;
3566                         string_free(lines_list[cy]);
3567
3568                         if (IS_FLG(FLG_NAMELESS)) 
3569                         {
3570                                 REM_FLG(FLG_NAMELESS);
3571                                 ADD_FLG(FLG_EGO);
3572                                 REM_FLG(FLG_ARTIFACT);
3573                         }
3574                         else if (IS_FLG(FLG_EGO)) 
3575                         {
3576                                 REM_FLG(FLG_NAMELESS);
3577                                 REM_FLG(FLG_EGO);
3578                                 ADD_FLG(FLG_ARTIFACT);
3579                         }
3580                         else if (IS_FLG(FLG_ARTIFACT)) 
3581                         {
3582                                 REM_FLG(FLG_NAMELESS);
3583                                 REM_FLG(FLG_EGO);
3584                                 REM_FLG(FLG_ARTIFACT);
3585                         }
3586                         else
3587                         {
3588                                 ADD_FLG(FLG_NAMELESS);
3589                                 REM_FLG(FLG_EGO);
3590                                 REM_FLG(FLG_ARTIFACT);
3591                         }
3592
3593                         lines_list[cy] = autopick_line_from_entry_kill(entry);
3594
3595                         /* Now dirty */
3596                         dirty_line = cy;
3597                         break;
3598
3599                 case KTRL('y'):
3600                         /* Paste killed text */
3601                         if (strlen(yank_buf))
3602                         {
3603                                 bool ret = FALSE;
3604
3605                                 for (j = 0; yank_buf[j]; j += strlen(yank_buf + j) + 1)
3606                                 {
3607                                         if (ret && '\n' == yank_buf[j])
3608                                         {
3609                                                 ret = FALSE;
3610                                                 continue;
3611                                         }
3612
3613                                         /* Split current line */
3614                                         insert_return_code(lines_list, cx, cy);
3615
3616                                         /* Save preceding string */
3617                                         for(i = 0; lines_list[cy][i]; i++)
3618                                                 buf[i] = lines_list[cy][i];
3619
3620                                         /* Paste yank buffer */
3621                                         if ('\n' != yank_buf[j])
3622                                         {
3623                                                 int k = j;
3624                                                 while (yank_buf[k] && i < MAX_LINELEN-1)
3625                                                         buf[i++] = yank_buf[k++];
3626                                                 ret = TRUE;
3627                                         }
3628
3629                                         buf[i] = '\0';
3630
3631                                         string_free(lines_list[cy]);
3632                                         lines_list[cy] = string_make(buf);
3633
3634                                         /* Move to the beggining of next line */
3635                                         cx = 0;
3636                                         cy++;
3637                                 }
3638
3639                                 /* Now dirty */
3640                                 dirty_flags |= DIRTY_ALL;
3641                         }
3642                         break;
3643                 case KTRL('z'):
3644                         /* Toggle 'collecting' */
3645                         toggle_string(lines_list, FLG_COLLECTING, cy);
3646                         /* Now dirty */
3647                         dirty_line = cy;
3648                         break;
3649
3650                 case KTRL('k'):
3651                         /* Kill rest of line */
3652                         if ((uint)cx > strlen(lines_list[cy]))
3653                                 cx = (int)strlen(lines_list[cy]);
3654
3655                         /* Save preceding string */
3656                         for (i = 0; lines_list[cy][i] && i < cx; i++)
3657                         {
3658 #ifdef JP
3659                                 if (iskanji(lines_list[cy][i]))
3660                                 {
3661                                         buf[i] = lines_list[cy][i];
3662                                         i++;
3663                                 }
3664 #endif
3665                                 buf[i] = lines_list[cy][i];
3666                         }
3667                         buf[i] = '\0';
3668
3669                         j = 0;
3670                         if (old_key == key)
3671                                 while (yank_buf[j])
3672                                         j += strlen(yank_buf + j) + 1;
3673
3674                         /* Copy following to yank buffer */
3675                         if (lines_list[cy][i])
3676                         {
3677                                 while (lines_list[cy][i] && j < MAX_YANK - 2)
3678                                         yank_buf[j++] = lines_list[cy][i++];
3679                                 i = TRUE;
3680                         }
3681                         else
3682                         {
3683                                 if (j < MAX_YANK - 2)
3684                                         yank_buf[j++] = '\n';
3685                                 i = FALSE;
3686                         }
3687                         yank_buf[j++] = '\0';
3688                         yank_buf[j] = '\0';
3689
3690                         /* Replace current line with 'preceding string' */
3691                         string_free(lines_list[cy]);
3692                         lines_list[cy] = string_make(buf);
3693
3694                         if (i)
3695                         {
3696                                 /* Now dirty */
3697                                 dirty_line = cy;
3698                                 break;
3699                         }
3700
3701                         /* fall through */
3702                 case KTRL('d'):
3703                 case 0x7F:
3704                         /* DELETE == go forward + BACK SPACE */
3705 #ifdef JP
3706                         if (iskanji(lines_list[cy][cx])) cx++;
3707 #endif
3708                         cx++;
3709
3710                         /* fall through */
3711
3712                 case '\010':
3713                         /* BACK SPACE */
3714                         len = strlen(lines_list[cy]);
3715                         if (len < cx)
3716                         {
3717                                 if (lines_list[cy + 1])
3718                                 {
3719                                         cy++;
3720                                         cx = 0;
3721                                 }
3722                                 else
3723                                 {
3724                                         cx = len;
3725                                         break;
3726                                 }
3727                         }
3728
3729                         if (cx == 0)
3730                         {
3731                                 /* delete a return code and union two lines */
3732                                 if (cy == 0) break;
3733                                 cx = strlen(lines_list[cy-1]);
3734                                 strcpy(buf, lines_list[cy-1]);
3735                                 strcat(buf, lines_list[cy]);
3736                                 string_free(lines_list[cy-1]);
3737                                 string_free(lines_list[cy]);
3738                                 lines_list[cy-1] = string_make(buf);
3739                                 for (i = cy; lines_list[i+1]; i++)
3740                                         lines_list[i] = lines_list[i+1];
3741                                 lines_list[i] = NULL;
3742                                 cy--;
3743
3744                                 /* Now dirty */
3745                                 dirty_flags |= DIRTY_ALL;
3746                                 break;
3747                         }
3748
3749                         for (i = j = k = 0; lines_list[cy][i] && i < cx; i++)
3750                         {
3751                                 k = j;
3752 #ifdef JP
3753                                 if (iskanji(lines_list[cy][i]))
3754                                         buf[j++] = lines_list[cy][i++];
3755 #endif
3756                                 buf[j++] = lines_list[cy][i];
3757                         }
3758                         while (j > k)
3759                         {
3760                                 cx--;
3761                                 j--;
3762                         }
3763                         for (; lines_list[cy][i]; i++)
3764                                 buf[j++] = lines_list[cy][i];
3765                         buf[j] = '\0';
3766                         string_free(lines_list[cy]);
3767                         lines_list[cy] = string_make(buf);
3768
3769                         /* Now dirty */
3770                         dirty_line = cy;
3771                         break;
3772                 }
3773
3774         } /* while (1) */
3775
3776         /* Restore the screen */
3777         screen_load();
3778
3779         switch (filename_mode)
3780         {
3781         case PT_DEFAULT:
3782 #ifdef JP
3783                 strcpy(buf, "picktype.prf");
3784 #else
3785                 strcpy(buf, "pickpref.prf");
3786 #endif
3787                 break;
3788
3789         case PT_WITH_PNAME:
3790 #ifdef JP
3791                 sprintf(buf, "picktype-%s.prf", player_name);
3792 #else
3793                 sprintf(buf, "pickpref-%s.prf", player_name);
3794 #endif
3795                 break;
3796         }
3797
3798         write_text_lines(buf, lines_list);
3799         free_text_lines(lines_list);
3800
3801         string_free(last_destroyed);
3802
3803         /* Reload autopick pref */
3804         process_pickpref_file(buf);
3805
3806         /* HACK -- reset start_time so that playtime is not increase while edit */
3807         start_time = time(NULL);
3808 }