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