OSDN Git Service

This commit was manufactured by cvs2svn to create tag
[hengbandforosx/hengbandosx.git] / src / autopick.c
index dfc5b83..b5cd20f 100644 (file)
 
 #include "angband.h"
 
+#define MAX_LINELEN 1024
+
+static object_type autopick_last_destroyed_object;
+
 /*
  * Macros for Keywords
  */
-#define FLG_ALL 0
-#define FLG_COLLECTING 1
-#define FLG_UNIDENTIFIED 2
-#define FLG_IDENTIFIED 3
+#define FLG_ALL             0
+#define FLG_COLLECTING     1
+#define FLG_UNIDENTIFIED    2
+#define FLG_IDENTIFIED     3
 #define FLG_STAR_IDENTIFIED 4
-#define FLG_NAMELESS 5
-#define FLG_UNAWARE 6
-#define FLG_WORTHLESS 7
-#define FLG_BOOSTED 8
-#define FLG_MORE_THAN 9
-#define FLG_DICE 10
-#define FLG_WANTED 11
-#define FLG_UNIQUE 12
-#define FLG_HUMAN 13
-#define FLG_UNREADABLE 14
-#define FLG_REALM1 15
-#define FLG_REALM2 16
-#define FLG_FIRST 17
-#define FLG_SECOND 18
-#define FLG_THIRD 19
-#define FLG_FOURTH 20
-#define FLG_ITEMS 21
-#define FLG_ARTIFACTS 22
-#define FLG_WEAPONS 23
-#define FLG_ARMORS 24
-#define FLG_MISSILES 25
-#define FLG_DEVICES 26
-#define FLG_LIGHTS 27
-#define FLG_JUNKS 28
-#define FLG_SPELLBOOKS 29
-#define FLG_HAFTED 30
-#define FLG_SHIELDS 31
-#define FLG_BOWS 32
-#define FLG_RINGS 33
-#define FLG_AMULETS 34
-#define FLG_SUITS 35
-#define FLG_CLOAKS 36
-#define FLG_HELMS 37
-#define FLG_GLOVES 38
-#define FLG_BOOTS 39
+#define FLG_BOOSTED        5
+#define FLG_MORE_THAN      6
+#define FLG_DICE           7
+#define FLG_MORE_BONUS     8
+#define FLG_MORE_BONUS2            9
+#define FLG_WORTHLESS      10
+#define FLG_ARTIFACT       11
+#define FLG_EGO                    12
+#define FLG_NAMELESS       13
+#define FLG_UNAWARE        14
+#define FLG_WANTED         15
+#define FLG_UNIQUE         16
+#define FLG_HUMAN          17
+#define FLG_UNREADABLE     18
+#define FLG_REALM1         19
+#define FLG_REALM2         20
+#define FLG_FIRST          21
+#define FLG_SECOND         22
+#define FLG_THIRD          23
+#define FLG_FOURTH         24
+
+#define FLG_ITEMS          30
+#define FLG_WEAPONS        31
+#define FLG_ARMORS         32
+#define FLG_MISSILES       33
+#define FLG_DEVICES        34
+#define FLG_LIGHTS         35
+#define FLG_JUNKS          36
+#define FLG_SPELLBOOKS     37
+#define FLG_HAFTED         38
+#define FLG_SHIELDS        39
+#define FLG_BOWS           40
+#define FLG_RINGS          41
+#define FLG_AMULETS        42
+#define FLG_SUITS          43
+#define FLG_CLOAKS         44
+#define FLG_HELMS          45
+#define FLG_GLOVES         46
+#define FLG_BOOTS           47
 
 #ifdef JP
 
 #define KEY_ALL "¤¹¤Ù¤Æ¤Î"
+
+#ifdef MAC_MPW
+/*
+ * MEGA HACK -- MPW¤Î¥Ð¥°½ü¤±¡£
+ * pre-processÃæ¤Ë¡Ö¼ý¡×¤Î»ú¤Î2¥Ð¥¤¥ÈÌܤ¬¾¡¼ê¤Ë¾Ã¤¨¤Æ¤·¤Þ¤¦¡£
+ */
+#define KEY_COLLECTING "\x8e\xfb½¸Ãæ¤Î"
+#else
 #define KEY_COLLECTING "¼ý½¸Ãæ¤Î"
+#endif
+
 #define KEY_UNIDENTIFIED "̤´ÕÄê¤Î"
 #define KEY_IDENTIFIED "´ÕÄêºÑ¤ß¤Î"
 #define KEY_STAR_IDENTIFIED "*´ÕÄê*ºÑ¤ß¤Î"
-#define KEY_NAMELESS "̵ÌäÎ"
-#define KEY_UNAWARE "̤ȽÌÀ¤Î"
-#define KEY_WORTHLESS "̵²ÁÃͤÎ"
 #define KEY_BOOSTED "¥À¥¤¥¹Ìܤΰ㤦"
 #define KEY_MORE_THAN  "¥À¥¤¥¹ÌÜ"
 #define KEY_DICE  "°Ê¾å¤Î"
+#define KEY_MORE_BONUS  "½¤ÀµÃÍ"
+#define KEY_MORE_BONUS2  "°Ê¾å¤Î"
+#define KEY_WORTHLESS "̵²ÁÃͤÎ"
+#define KEY_ARTIFACT "¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È"
+#define KEY_EGO "¥¨¥´"
+#define KEY_NAMELESS "̵ÌäÎ"
+#define KEY_UNAWARE "̤ȽÌÀ¤Î"
 #define KEY_WANTED "¾Þ¶â¼ó¤Î"
 #define KEY_UNIQUE "¥æ¥Ë¡¼¥¯¡¦¥â¥ó¥¹¥¿¡¼¤Î"
 #define KEY_HUMAN "¿Í´Ö¤Î"
 #define KEY_THIRD "3ºýÌܤÎ"
 #define KEY_FOURTH "4ºýÌܤÎ"
 #define KEY_ITEMS "¥¢¥¤¥Æ¥à"
-#define KEY_ARTIFACTS "¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È"
 #define KEY_WEAPONS "Éð´ï"
 #define KEY_ARMORS "Ëɶñ"
 #define KEY_MISSILES "Ìð"
 #define KEY_UNIDENTIFIED "unidentified"
 #define KEY_IDENTIFIED "identified"
 #define KEY_STAR_IDENTIFIED "*identified*"
+#define KEY_BOOSTED "dice boosted"
+#define KEY_MORE_THAN  "more than"
+#define KEY_DICE  " dice"
+#define KEY_MORE_BONUS  "more bonus than"
+#define KEY_MORE_BONUS2  ""
+#define KEY_WORTHLESS "worthless"
+#define KEY_ARTIFACT "artifact"
+#define KEY_EGO "ego"
 #define KEY_NAMELESS "nameless"
 #define KEY_UNAWARE "unaware"
-#define KEY_WORTHLESS "worthless"
-#define KEY_BOOSTED "dice boosted"
-#define KEY_MORE_THAN  "more than "
-#define KEY_DICE  " dice "
 #define KEY_WANTED "wanted"
 #define KEY_UNIQUE "unique monster's"
 #define KEY_HUMAN "human"
 #define KEY_THIRD "third"
 #define KEY_FOURTH "fourth"
 #define KEY_ITEMS "items"
-#define KEY_ARTIFACTS "artifacts"
 #define KEY_WEAPONS "weapons"
 #define KEY_ARMORS "armors"
 #define KEY_MISSILES "missiles"
 #endif /* JP */
 
 #define MATCH_KEY(KEY) (!strncmp(ptr, KEY, sizeof(KEY)-1)\
+     ? (ptr += sizeof(KEY)-1, (' '==*ptr) ? ptr++ : 0, TRUE) : FALSE)
+#define MATCH_KEY2(KEY) (!strncmp(ptr, KEY, sizeof(KEY)-1)\
      ? (prev_ptr = ptr, ptr += sizeof(KEY)-1, (' '==*ptr) ? ptr++ : 0, TRUE) : FALSE)
 
 #ifdef JP
 
 #define ADD_FLG(FLG) (entry->flag[FLG / 32] |= (1L << (FLG % 32)))
 #define REM_FLG(FLG) (entry->flag[FLG / 32] &= ~(1L << (FLG % 32)))
-#define ADD_FLG2(FLG) (entry->flag[FLG / 32] |= (1L << (FLG % 32)), prev_flg = FLG)
+#define ADD_FLG_NOUN(FLG) (ADD_FLG(FLG), prev_flg = FLG)
 #define IS_FLG(FLG) (entry->flag[FLG / 32] & (1L << (FLG % 32)))
 
 #ifdef JP
  */
 cptr autopick_line_from_entry(autopick_type *entry)
 {
-       char buf[1024];
+       char buf[MAX_LINELEN];
        char *ptr;
        bool sepa_flag = TRUE;
 
        *buf = '\0';
        if (!(entry->action & DO_DISPLAY)) strcat(buf, "(");
+       if (entry->action & DO_QUERY_AUTOPICK) strcat(buf, ";");
        if (entry->action & DO_AUTODESTROY) strcat(buf, "!");
        if (entry->action & DONT_AUTOPICK) strcat(buf, "~");
 
@@ -185,21 +212,23 @@ cptr autopick_line_from_entry(autopick_type *entry)
        if (IS_FLG(FLG_UNIDENTIFIED)) ADD_KEY(KEY_UNIDENTIFIED);
        if (IS_FLG(FLG_IDENTIFIED)) ADD_KEY(KEY_IDENTIFIED);
        if (IS_FLG(FLG_STAR_IDENTIFIED)) ADD_KEY(KEY_STAR_IDENTIFIED);
-       if (IS_FLG(FLG_NAMELESS)) ADD_KEY(KEY_NAMELESS);
        if (IS_FLG(FLG_UNAWARE)) ADD_KEY(KEY_UNAWARE);
-       if (IS_FLG(FLG_WORTHLESS)) ADD_KEY(KEY_WORTHLESS);
        if (IS_FLG(FLG_BOOSTED)) ADD_KEY(KEY_BOOSTED);
 
        if (IS_FLG(FLG_MORE_THAN))
        {
                ADD_KEY(KEY_MORE_THAN);
-               strcat(ptr, format("%2d", entry->dice));
+               strcat(ptr, format("%d", entry->dice));
                ADD_KEY(KEY_DICE);
        }
 
-       if (IS_FLG(FLG_WANTED)) ADD_KEY(KEY_WANTED);
-       if (IS_FLG(FLG_UNIQUE)) ADD_KEY(KEY_UNIQUE);
-       if (IS_FLG(FLG_HUMAN)) ADD_KEY(KEY_HUMAN);
+       if (IS_FLG(FLG_MORE_BONUS))
+       {
+               ADD_KEY(KEY_MORE_BONUS);
+               strcat(ptr, format("%d", entry->bonus));
+               ADD_KEY(KEY_MORE_BONUS2);
+       }
+
        if (IS_FLG(FLG_UNREADABLE)) ADD_KEY(KEY_UNREADABLE);
        if (IS_FLG(FLG_REALM1)) ADD_KEY(KEY_REALM1);
        if (IS_FLG(FLG_REALM2)) ADD_KEY(KEY_REALM2);
@@ -207,9 +236,16 @@ cptr autopick_line_from_entry(autopick_type *entry)
        if (IS_FLG(FLG_SECOND)) ADD_KEY(KEY_SECOND);
        if (IS_FLG(FLG_THIRD)) ADD_KEY(KEY_THIRD);
        if (IS_FLG(FLG_FOURTH)) ADD_KEY(KEY_FOURTH);
+       if (IS_FLG(FLG_WANTED)) ADD_KEY(KEY_WANTED);
+       if (IS_FLG(FLG_UNIQUE)) ADD_KEY(KEY_UNIQUE);
+       if (IS_FLG(FLG_HUMAN)) ADD_KEY(KEY_HUMAN);
+       if (IS_FLG(FLG_WORTHLESS)) ADD_KEY(KEY_WORTHLESS);
+       if (IS_FLG(FLG_NAMELESS)) ADD_KEY(KEY_NAMELESS);
+       if (IS_FLG(FLG_EGO)) ADD_KEY(KEY_EGO);
+
+       if (IS_FLG(FLG_ARTIFACT)) ADD_KEY(KEY_ARTIFACT);
 
        if (IS_FLG(FLG_ITEMS)) ADD_KEY2(KEY_ITEMS);
-       else if (IS_FLG(FLG_ARTIFACTS)) ADD_KEY2(KEY_ARTIFACTS);
        else if (IS_FLG(FLG_WEAPONS)) ADD_KEY2(KEY_WEAPONS);
        else if (IS_FLG(FLG_ARMORS)) ADD_KEY2(KEY_ARMORS);
        else if (IS_FLG(FLG_MISSILES)) ADD_KEY2(KEY_MISSILES);
@@ -227,30 +263,65 @@ cptr autopick_line_from_entry(autopick_type *entry)
        else if (IS_FLG(FLG_HELMS)) ADD_KEY2(KEY_HELMS);
        else if (IS_FLG(FLG_GLOVES)) ADD_KEY2(KEY_GLOVES);
        else if (IS_FLG(FLG_BOOTS)) ADD_KEY2(KEY_BOOTS);
-       else
+
+       /* You don't need sepalator after adjective */
+       /* 'artifact' is not true adjective */
+       else if (!IS_FLG(FLG_ARTIFACT))
                sepa_flag = FALSE;
 
-       if (entry->name && *entry->name)
-       {
-               if (sepa_flag)
-                       strcat(buf, ":");
-               strcat(buf, entry->name);
-       }
-       else
+       if (entry->name && entry->name[0])
        {
-               if (entry->flag[0] == 0L && entry->flag[0] == 0L)
-                       return NULL;
+               int i, j = 0;
+
+               if (sepa_flag) strcat(buf, ":");
+
+               i = strlen(buf);
+               while (entry->name[j] && i < MAX_LINELEN - 2 - 1)
+               {
+#ifdef JP
+                       if (iskanji(entry->name[j]))
+                               buf[i++] = entry->name[j++];
+#endif
+                       buf[i++] = entry->name[j++];
+               }
+               buf[i] = '\0';
        }
 
        if (entry->insc)
        {
+               int i, j = 0;
                strcat(buf, "#");
-               strcat(buf, entry->insc);
+               i = strlen(buf);
+
+               while (entry->insc[j] && i < MAX_LINELEN - 2)
+               {
+#ifdef JP
+                       if (iskanji(entry->insc[j]))
+                               buf[i++] = entry->insc[j++];
+#endif
+                       buf[i++] = entry->insc[j++];
+               }
+               buf[i] = '\0';
        }
 
        return string_make(buf);
 }
 
+
+/*
+ * Reconstruct preference line from entry and kill entry
+ */
+static cptr autopick_line_from_entry_kill(autopick_type *entry)
+{
+       cptr ptr = autopick_line_from_entry(entry);
+
+       /* Free memory for original entry */
+       autopick_free_entry(entry);
+
+       return ptr;
+}
+
+
 /*
  * A function to create new entry
  */
@@ -259,8 +330,8 @@ bool autopick_new_entry(autopick_type *entry, cptr str)
        cptr insc;
        int i;
        byte act = 0;
-       char buf[1024];
-       cptr prev_ptr, ptr;
+       char buf[MAX_LINELEN];
+       cptr prev_ptr, ptr, old_ptr;
        int prev_flg;
 
        if (str[1] == ':') switch (str[0])
@@ -276,19 +347,25 @@ bool autopick_new_entry(autopick_type *entry, cptr str)
        act = DO_AUTOPICK | DO_DISPLAY;
        while (1)
        {
-               if (*str == '!')
+               if ((act & DO_AUTOPICK) && *str == '!')
                {
                        act &= ~DO_AUTOPICK;
                        act |= DO_AUTODESTROY;
                        str++;
                }
-               else if (*str == '~')
+               else if ((act & DO_AUTOPICK) && *str == '~')
                {
                        act &= ~DO_AUTOPICK;
                        act |= DONT_AUTOPICK;
                        str++;
                }
-               else if (*str == '(')
+               else if ((act & DO_AUTOPICK) && *str == ';')
+               {
+                       act &= ~DO_AUTOPICK;
+                       act |= DO_QUERY_AUTOPICK;
+                       str++;
+               }
+               else if ((act & DO_DISPLAY) && *str == '(')
                {
                        act &= ~DO_DISPLAY;
                        str++;
@@ -327,82 +404,134 @@ bool autopick_new_entry(autopick_type *entry, cptr str)
        /* Skip empty line */
        if (*buf == 0) return FALSE;
 
-       /* Found flags */
-       prev_ptr = ptr = buf;
-       prev_flg = -1;
-       if (MATCH_KEY(KEY_ALL)) ADD_FLG(FLG_ALL);
-       if (MATCH_KEY(KEY_COLLECTING)) ADD_FLG(FLG_COLLECTING);
-       if (MATCH_KEY(KEY_UNIDENTIFIED)) ADD_FLG(FLG_UNIDENTIFIED);
-       if (MATCH_KEY(KEY_IDENTIFIED)) ADD_FLG(FLG_IDENTIFIED);
-       if (MATCH_KEY(KEY_STAR_IDENTIFIED)) ADD_FLG(FLG_STAR_IDENTIFIED);
-       if (MATCH_KEY(KEY_NAMELESS)) ADD_FLG(FLG_NAMELESS);
-       if (MATCH_KEY(KEY_UNAWARE)) ADD_FLG(FLG_UNAWARE);
-       if (MATCH_KEY(KEY_WORTHLESS)) ADD_FLG(FLG_WORTHLESS);
-       if (MATCH_KEY(KEY_BOOSTED)) ADD_FLG(FLG_BOOSTED);
+       ptr = prev_ptr = buf;
+       old_ptr = NULL;
 
-       /*** Weapons whic dd*ds is more than nn ***/
-       if (MATCH_KEY(KEY_MORE_THAN))
+       while (old_ptr != ptr)
        {
-               if (isdigit(ptr[0]) && isdigit(ptr[1]))
+               /* Save current location */
+               old_ptr = ptr;
+
+               if (MATCH_KEY(KEY_ALL)) ADD_FLG(FLG_ALL);
+               if (MATCH_KEY(KEY_COLLECTING)) ADD_FLG(FLG_COLLECTING);
+               if (MATCH_KEY(KEY_UNIDENTIFIED)) ADD_FLG(FLG_UNIDENTIFIED);
+               if (MATCH_KEY(KEY_IDENTIFIED)) ADD_FLG(FLG_IDENTIFIED);
+               if (MATCH_KEY(KEY_STAR_IDENTIFIED)) ADD_FLG(FLG_STAR_IDENTIFIED);
+               if (MATCH_KEY(KEY_BOOSTED)) ADD_FLG(FLG_BOOSTED);
+
+               /*** Weapons whose dd*ds is more than nn ***/
+               if (MATCH_KEY2(KEY_MORE_THAN))
                {
-                       entry->dice = (ptr[0] - '0') * 10 + (ptr[1] - '0');
-                       ptr += 2;
-                       (void)MATCH_KEY(KEY_DICE);
-                       ADD_FLG(FLG_MORE_THAN);
+                       int k = 0;
+                       entry->dice = 0;
+
+                       /* Drop leading spaces */
+                       while (' ' == *ptr) ptr++;
+
+                       /* Read number */
+                       while ('0' <= *ptr && *ptr <= '9')
+                       {
+                               entry->dice = 10 * entry->dice + (*ptr - '0');
+                               ptr++;
+                               k++;
+                       }
+
+                       if (k > 0 && k <= 2)
+                       {
+                               (void)MATCH_KEY(KEY_DICE);
+                               ADD_FLG(FLG_MORE_THAN);
+                       }
+                       else
+                               ptr = prev_ptr;
                }
-               else
-                       ptr = prev_ptr;
-       }
 
-       if (MATCH_KEY(KEY_WANTED)) ADD_FLG(FLG_WANTED);
-       if (MATCH_KEY(KEY_UNIQUE)) ADD_FLG(FLG_UNIQUE);
-       if (MATCH_KEY(KEY_HUMAN)) ADD_FLG(FLG_HUMAN);
-       if (MATCH_KEY(KEY_UNREADABLE)) ADD_FLG(FLG_UNREADABLE);
-       if (MATCH_KEY(KEY_REALM1)) ADD_FLG(FLG_REALM1);
-       if (MATCH_KEY(KEY_REALM2)) ADD_FLG(FLG_REALM2);
-       if (MATCH_KEY(KEY_FIRST)) ADD_FLG(FLG_FIRST);
-       if (MATCH_KEY(KEY_SECOND)) ADD_FLG(FLG_SECOND);
-       if (MATCH_KEY(KEY_THIRD)) ADD_FLG(FLG_THIRD);
-       if (MATCH_KEY(KEY_FOURTH)) ADD_FLG(FLG_FOURTH);
-
-       /* Reset previous word location */
-       prev_ptr = ptr;
-
-       if (MATCH_KEY(KEY_ITEMS)) ADD_FLG2(FLG_ITEMS);
-       else if (MATCH_KEY(KEY_ARTIFACTS)) ADD_FLG2(FLG_ARTIFACTS);
-       else if (MATCH_KEY(KEY_WEAPONS)) ADD_FLG2(FLG_WEAPONS);
-       else if (MATCH_KEY(KEY_ARMORS)) ADD_FLG2(FLG_ARMORS);
-       else if (MATCH_KEY(KEY_MISSILES)) ADD_FLG2(FLG_MISSILES);
-       else if (MATCH_KEY(KEY_DEVICES)) ADD_FLG2(FLG_DEVICES);
-       else if (MATCH_KEY(KEY_LIGHTS)) ADD_FLG2(FLG_LIGHTS);
-       else if (MATCH_KEY(KEY_JUNKS)) ADD_FLG2(FLG_JUNKS);
-       else if (MATCH_KEY(KEY_SPELLBOOKS)) ADD_FLG2(FLG_SPELLBOOKS);
-       else if (MATCH_KEY(KEY_HAFTED)) ADD_FLG2(FLG_HAFTED);
-       else if (MATCH_KEY(KEY_SHIELDS)) ADD_FLG2(FLG_SHIELDS);
-       else if (MATCH_KEY(KEY_BOWS)) ADD_FLG2(FLG_BOWS);
-       else if (MATCH_KEY(KEY_RINGS)) ADD_FLG2(FLG_RINGS);
-       else if (MATCH_KEY(KEY_AMULETS)) ADD_FLG2(FLG_AMULETS);
-       else if (MATCH_KEY(KEY_SUITS)) ADD_FLG2(FLG_SUITS);
-       else if (MATCH_KEY(KEY_CLOAKS)) ADD_FLG2(FLG_CLOAKS);
-       else if (MATCH_KEY(KEY_HELMS)) ADD_FLG2(FLG_HELMS);
-       else if (MATCH_KEY(KEY_GLOVES)) ADD_FLG2(FLG_GLOVES);
-       else if (MATCH_KEY(KEY_BOOTS)) ADD_FLG2(FLG_BOOTS);
+               /*** Items whose magical bonus is more than n ***/
+               if (MATCH_KEY2(KEY_MORE_BONUS))
+               {
+                       int k = 0;
+                       entry->bonus = 0;
+
+                       /* Drop leading spaces */
+                       while (' ' == *ptr) ptr++;
+
+                       /* Read number */
+                       while ('0' <= *ptr && *ptr <= '9')
+                       {
+                               entry->bonus = 10 * entry->bonus + (*ptr - '0');
+                               ptr++;
+                               k++;
+                       }
+
+                       if (k > 0 && k <= 2)
+                       {
+                               (void)MATCH_KEY(KEY_MORE_BONUS2);
+                               ADD_FLG(FLG_MORE_BONUS);
+                       }
+                       else
+                               ptr = prev_ptr;
+               }
+
+               if (MATCH_KEY(KEY_WORTHLESS)) ADD_FLG(FLG_WORTHLESS);
+               if (MATCH_KEY(KEY_EGO)) ADD_FLG(FLG_EGO);
+               if (MATCH_KEY(KEY_NAMELESS)) ADD_FLG(FLG_NAMELESS);
+               if (MATCH_KEY(KEY_UNAWARE)) ADD_FLG(FLG_UNAWARE);
+               if (MATCH_KEY(KEY_WANTED)) ADD_FLG(FLG_WANTED);
+               if (MATCH_KEY(KEY_UNIQUE)) ADD_FLG(FLG_UNIQUE);
+               if (MATCH_KEY(KEY_HUMAN)) ADD_FLG(FLG_HUMAN);
+               if (MATCH_KEY(KEY_UNREADABLE)) ADD_FLG(FLG_UNREADABLE);
+               if (MATCH_KEY(KEY_REALM1)) ADD_FLG(FLG_REALM1);
+               if (MATCH_KEY(KEY_REALM2)) ADD_FLG(FLG_REALM2);
+               if (MATCH_KEY(KEY_FIRST)) ADD_FLG(FLG_FIRST);
+               if (MATCH_KEY(KEY_SECOND)) ADD_FLG(FLG_SECOND);
+               if (MATCH_KEY(KEY_THIRD)) ADD_FLG(FLG_THIRD);
+               if (MATCH_KEY(KEY_FOURTH)) ADD_FLG(FLG_FOURTH);
+       }
+
+       /* Not yet found any noun */
+       prev_flg = -1;
+
+       if (MATCH_KEY2(KEY_ARTIFACT)) ADD_FLG_NOUN(FLG_ARTIFACT);
+
+       if (MATCH_KEY2(KEY_ITEMS)) ADD_FLG_NOUN(FLG_ITEMS);
+       else if (MATCH_KEY2(KEY_WEAPONS)) ADD_FLG_NOUN(FLG_WEAPONS);
+       else if (MATCH_KEY2(KEY_ARMORS)) ADD_FLG_NOUN(FLG_ARMORS);
+       else if (MATCH_KEY2(KEY_MISSILES)) ADD_FLG_NOUN(FLG_MISSILES);
+       else if (MATCH_KEY2(KEY_DEVICES)) ADD_FLG_NOUN(FLG_DEVICES);
+       else if (MATCH_KEY2(KEY_LIGHTS)) ADD_FLG_NOUN(FLG_LIGHTS);
+       else if (MATCH_KEY2(KEY_JUNKS)) ADD_FLG_NOUN(FLG_JUNKS);
+       else if (MATCH_KEY2(KEY_SPELLBOOKS)) ADD_FLG_NOUN(FLG_SPELLBOOKS);
+       else if (MATCH_KEY2(KEY_HAFTED)) ADD_FLG_NOUN(FLG_HAFTED);
+       else if (MATCH_KEY2(KEY_SHIELDS)) ADD_FLG_NOUN(FLG_SHIELDS);
+       else if (MATCH_KEY2(KEY_BOWS)) ADD_FLG_NOUN(FLG_BOWS);
+       else if (MATCH_KEY2(KEY_RINGS)) ADD_FLG_NOUN(FLG_RINGS);
+       else if (MATCH_KEY2(KEY_AMULETS)) ADD_FLG_NOUN(FLG_AMULETS);
+       else if (MATCH_KEY2(KEY_SUITS)) ADD_FLG_NOUN(FLG_SUITS);
+       else if (MATCH_KEY2(KEY_CLOAKS)) ADD_FLG_NOUN(FLG_CLOAKS);
+       else if (MATCH_KEY2(KEY_HELMS)) ADD_FLG_NOUN(FLG_HELMS);
+       else if (MATCH_KEY2(KEY_GLOVES)) ADD_FLG_NOUN(FLG_GLOVES);
+       else if (MATCH_KEY2(KEY_BOOTS)) ADD_FLG_NOUN(FLG_BOOTS);
 
        /* Last 'keyword' must be at the correct location */
        if (*ptr == ':')
                ptr++;
-       else if (*ptr == '\0')
-               ; /* nothing to do */
 #ifdef JP
        else if (ptr[0] == kanji_colon[0] && ptr[1] == kanji_colon[1])
                ptr += 2;
 #endif
+       else if (*ptr == '\0')
+               ; /* nothing to do */
        else
        {
+               /* Noun type? */
                if (prev_flg != -1)
+               {
+                       /* A noun type keyword didn't end correctly */
                        entry->flag[prev_flg/32] &= ~(1L<< (prev_flg%32));
-               ptr = prev_ptr;
+                       ptr = prev_ptr;
+               }
        }
+
+       /* Save this auto-picker entry line */
        entry->name = string_make(ptr);
        entry->action = act;
        entry->insc = string_make(insc);
@@ -419,321 +548,359 @@ void autopick_free_entry(autopick_type *entry)
        string_free(entry->insc);
 }
 
+
 /*
  * A function for Auto-picker/destroyer
- * Examine whether the object matches to the list of keywords or not.
+ * Examine whether the object matches to the entry
  */
-int is_autopick(object_type *o_ptr)
+static bool is_autopick_aux(object_type *o_ptr, autopick_type *entry, cptr o_name)
 {
-       int i;
-       char o_name[MAX_NLEN];
+       int j;
+       cptr ptr = entry->name;
 
-       if (o_ptr->tval == TV_GOLD) return -1;
-       
-       object_desc(o_name, o_ptr, FALSE, 3);
-
-       /* Force to be lower case string */
-       for (i = 0; o_name[i]; i++)
-       {
-#ifdef JP
-               if (iskanji(o_name[i]))
-                       i++;
-               else
-#endif
-               if (isupper(o_name[i]))
-                       o_name[i] = tolower(o_name[i]);
-       }
-       
-       for (i=0; i < max_autopick; i++)
-       {
-               autopick_type *entry = &autopick_list[i];
-               bool flag = FALSE;
-               cptr ptr = autopick_list[i].name;
-
-               /*** Unidentified ***/
-               if (IS_FLG(FLG_UNIDENTIFIED)
-                   && (object_known_p(o_ptr) || (o_ptr->ident & IDENT_SENSE)))
-                       continue;
+       /*** Unidentified ***/
+       if (IS_FLG(FLG_UNIDENTIFIED)
+           && (object_known_p(o_ptr) || (o_ptr->ident & IDENT_SENSE)))
+               return FALSE;
 
-               /*** Identified ***/
-               if (IS_FLG(FLG_IDENTIFIED) && !object_known_p(o_ptr))
-                       continue;
+       /*** Identified ***/
+       if (IS_FLG(FLG_IDENTIFIED) && !object_known_p(o_ptr))
+               return FALSE;
 
-               /*** *Identified* ***/
-               if (IS_FLG(FLG_STAR_IDENTIFIED) &&
-                   (!object_known_p(o_ptr) || !(o_ptr->ident & IDENT_MENTAL)))
-                       continue;
+       /*** *Identified* ***/
+       if (IS_FLG(FLG_STAR_IDENTIFIED) &&
+           (!object_known_p(o_ptr) || !(o_ptr->ident & IDENT_MENTAL)))
+               return FALSE;
 
-               /*** Nameless ***/
-               if (IS_FLG(FLG_NAMELESS))
+       /*** Dice boosted (weapon of slaying) ***/
+       if (IS_FLG(FLG_BOOSTED))
+       {
+               object_kind *k_ptr = &k_info[o_ptr->k_idx];
+                       
+               switch( o_ptr->tval )
                {
-                       switch (o_ptr->tval)
-                       {
-                       case TV_WHISTLE:
-                       case TV_SHOT: case TV_ARROW: case TV_BOLT: case TV_BOW:
-                       case TV_DIGGING: case TV_HAFTED: case TV_POLEARM: case TV_SWORD: 
-                       case TV_BOOTS: case TV_GLOVES: case TV_HELM: case TV_CROWN:
-                       case TV_SHIELD: case TV_CLOAK:
-                       case TV_SOFT_ARMOR: case TV_HARD_ARMOR: case TV_DRAG_ARMOR:
-                       case TV_LITE: case TV_AMULET: case TV_RING: case TV_CARD:
-                               if ((!object_known_p(o_ptr) || o_ptr->inscription
-                                    || o_ptr->name1 || o_ptr->name2 || o_ptr->art_name))
-                                       continue;
+               case TV_HAFTED:
+               case TV_POLEARM:
+               case TV_SWORD:
+               case TV_DIGGING:
+                       if ((o_ptr->dd != k_ptr->dd) || (o_ptr->ds != k_ptr->ds))
                                break;
-                       default:
-                               /* don't match */
-                               continue;
-                       }
+                       else
+                               return FALSE;
+               default:
+                       return FALSE;
                }
+       }
 
-               /*** Unaware items ***/
-               if (IS_FLG(FLG_UNAWARE) && object_aware_p(o_ptr))
-                       continue;
-
-               /*** Worthless items ***/
-               if (IS_FLG(FLG_WORTHLESS) && object_value(o_ptr) > 0)
-                       continue;
+       /*** Weapons which dd*ds is more than nn ***/
+       if (IS_FLG(FLG_MORE_THAN))
+       {
+               if (o_ptr->dd * o_ptr->ds < entry->dice)
+                       return FALSE;
+       }
+                               
+       /*** Weapons whic dd*ds is more than nn ***/
+       if (IS_FLG(FLG_MORE_BONUS))
+       {
+               if (!object_known_p(o_ptr)) return FALSE;
 
-               /*** Dice boosted (weapon of slaying) ***/
-               if (IS_FLG(FLG_BOOSTED))
+               if (o_ptr->pval)
                {
-                       object_kind *k_ptr = &k_info[o_ptr->k_idx];
-                       
-                       switch( o_ptr->tval )
-                       {
-                       case TV_HAFTED:
-                       case TV_POLEARM:
-                       case TV_SWORD:
-                       case TV_DIGGING:
-                               if ((o_ptr->dd != k_ptr->dd) || (o_ptr->ds != k_ptr->ds))
-                                       break;
-                               else
-                                       continue;
-                       default:
-                               continue;
-                       }
+                       if (o_ptr->pval < entry->bonus) return FALSE;
                }
-
-               /*** Weapons whic dd*ds is more than nn ***/
-               if (IS_FLG(FLG_MORE_THAN))
+               else
                {
-                       if (o_ptr->dd * o_ptr->ds < entry->dice)
-                               continue;
+                       if (o_ptr->to_h < entry->bonus &&
+                           o_ptr->to_d < entry->bonus &&
+                           o_ptr->to_a < entry->bonus &&
+                           o_ptr->pval < entry->bonus)
+                               return FALSE;
                }
+       }
                                
-               /*** Wanted monster's corpse/skeletons ***/
-               if (IS_FLG(FLG_WANTED) &&
-                   (o_ptr->tval != TV_CORPSE || !object_is_shoukinkubi(o_ptr)))
-                       continue;
+       /*** Worthless items ***/
+       if (IS_FLG(FLG_WORTHLESS) && object_value(o_ptr) > 0)
+               return FALSE;
 
-               /*** Unique monster's corpse/skeletons/statues ***/
-               if (IS_FLG(FLG_UNIQUE) &&
-                   ((o_ptr->tval != TV_CORPSE && o_ptr->tval != TV_STATUE) ||
-                   !(r_info[o_ptr->pval].flags1 & RF1_UNIQUE)))
-                       continue;
+       /*** Artifact object ***/
+       if (IS_FLG(FLG_ARTIFACT))
+       {
+               if (!object_known_p(o_ptr) || (!o_ptr->name1 && !o_ptr->art_name))
+                       return FALSE;
+       }
 
-               /*** Human corpse/skeletons (for Daemon magic) ***/
-               if (IS_FLG(FLG_HUMAN) &&
-                   (o_ptr->tval != TV_CORPSE ||
-                   !strchr("pht", r_info[o_ptr->pval].d_char)))
-                       continue;
+       /*** Ego object ***/
+       if (IS_FLG(FLG_EGO))
+       {
+               if (!object_known_p(o_ptr) || !o_ptr->name2)
+                       return FALSE;
+       }
 
-               /*** Unreadable spellbooks ***/
-               if (IS_FLG(FLG_UNREADABLE) &&
-                   (o_ptr->tval < TV_LIFE_BOOK ||
-                   check_book_realm(o_ptr->tval, o_ptr->sval)))
-                       continue;
+       /*** Nameless ***/
+       if (IS_FLG(FLG_NAMELESS))
+       {
+               switch (o_ptr->tval)
+               {
+               case TV_WHISTLE:
+               case TV_SHOT: case TV_ARROW: case TV_BOLT: case TV_BOW:
+               case TV_DIGGING: case TV_HAFTED: case TV_POLEARM: case TV_SWORD: 
+               case TV_BOOTS: case TV_GLOVES: case TV_HELM: case TV_CROWN:
+               case TV_SHIELD: case TV_CLOAK:
+               case TV_SOFT_ARMOR: case TV_HARD_ARMOR: case TV_DRAG_ARMOR:
+               case TV_LITE: case TV_AMULET: case TV_RING: case TV_CARD:
+                       if ((!object_known_p(o_ptr) || o_ptr->inscription
+                            || o_ptr->name1 || o_ptr->name2 || o_ptr->art_name))
+                               return FALSE;
+                       break;
+               default:
+                       /* don't match */
+                       return FALSE;
+               }
+       }
 
-               /*** First realm spellbooks ***/
-               if (IS_FLG(FLG_REALM1) && 
-                   (REALM1_BOOK != o_ptr->tval ||
-                   p_ptr->pclass == CLASS_SORCERER ||
-                   p_ptr->pclass == CLASS_RED_MAGE))
-                       continue;
+       /*** Unaware items ***/
+       if (IS_FLG(FLG_UNAWARE) && object_aware_p(o_ptr))
+               return FALSE;
 
-               /*** Second realm spellbooks ***/
-               if (IS_FLG(FLG_REALM2) &&
-                   (REALM2_BOOK != o_ptr->tval ||
-                   p_ptr->pclass == CLASS_SORCERER ||
-                   p_ptr->pclass == CLASS_RED_MAGE))
-                       continue;
+       /*** Wanted monster's corpse/skeletons ***/
+       if (IS_FLG(FLG_WANTED) &&
+           (o_ptr->tval != TV_CORPSE || !object_is_shoukinkubi(o_ptr)))
+               return FALSE;
 
-               /*** First rank spellbooks ***/
-               if (IS_FLG(FLG_FIRST) &&
-                   (o_ptr->tval < TV_LIFE_BOOK || 0 != o_ptr->sval))
-                       continue;
+       /*** Unique monster's corpse/skeletons/statues ***/
+       if (IS_FLG(FLG_UNIQUE) &&
+           ((o_ptr->tval != TV_CORPSE && o_ptr->tval != TV_STATUE) ||
+            !(r_info[o_ptr->pval].flags1 & RF1_UNIQUE)))
+               return FALSE;
 
-               /*** Second rank spellbooks ***/
-               if (IS_FLG(FLG_SECOND) &&
-                   (o_ptr->tval < TV_LIFE_BOOK || 1 != o_ptr->sval))
-                       continue;
+       /*** Human corpse/skeletons (for Daemon magic) ***/
+       if (IS_FLG(FLG_HUMAN) &&
+           (o_ptr->tval != TV_CORPSE ||
+            !strchr("pht", r_info[o_ptr->pval].d_char)))
+               return FALSE;
 
-               /*** Third rank spellbooks ***/
-               if (IS_FLG(FLG_THIRD) && 
-                   (o_ptr->tval < TV_LIFE_BOOK || 2 != o_ptr->sval))
-                       continue;
+       /*** Unreadable spellbooks ***/
+       if (IS_FLG(FLG_UNREADABLE) &&
+           (o_ptr->tval < TV_LIFE_BOOK ||
+            check_book_realm(o_ptr->tval, o_ptr->sval)))
+               return FALSE;
 
-               /*** Fourth rank spellbooks ***/
-               if (IS_FLG(FLG_FOURTH) &&
-                   (o_ptr->tval < TV_LIFE_BOOK || 3 != o_ptr->sval))
-                       continue;
+       /*** First realm spellbooks ***/
+       if (IS_FLG(FLG_REALM1) && 
+           (REALM1_BOOK != o_ptr->tval ||
+            p_ptr->pclass == CLASS_SORCERER ||
+            p_ptr->pclass == CLASS_RED_MAGE))
+               return FALSE;
 
-               /*** Items ***/
-               if (IS_FLG(FLG_ARTIFACTS))
-               {
-                       if (!(object_known_p(o_ptr)
-                             && (artifact_p(o_ptr) || o_ptr->art_name)))
-                               continue;
-               }
-               else if (IS_FLG(FLG_WEAPONS))
-               {
-                       switch(o_ptr->tval)
-                       {
-                       case TV_BOW: case TV_HAFTED: case TV_POLEARM:
-                       case TV_SWORD: case TV_DIGGING:
-                               break;
-                       default: continue;
-                       }
-               }
-               else if (IS_FLG(FLG_ARMORS))
-               {
-                       switch(o_ptr->tval)
-                       {
-                       case TV_BOOTS: case TV_GLOVES: case TV_CLOAK: case TV_CROWN:
-                       case TV_HELM: case TV_SHIELD: case TV_SOFT_ARMOR:
-                       case TV_HARD_ARMOR: case TV_DRAG_ARMOR:
-                               break;
-                       default: continue;
-                       }
-               }
-               else if (IS_FLG(FLG_MISSILES))
-               {
-                       switch(o_ptr->tval)
-                       {
-                       case TV_SHOT: case TV_BOLT: case TV_ARROW:
-                               break;
-                       default: continue;
-                       }
-               }
-               else if (IS_FLG(FLG_DEVICES))
-               {
-                       switch(o_ptr->tval)
-                       {
-                       case TV_SCROLL: case TV_STAFF: case TV_WAND: case TV_ROD:
-                               break;
-                       default: continue;
-                       }
-               }
-               else if (IS_FLG(FLG_LIGHTS))
-               {
-                       if (!(o_ptr->tval == TV_LITE))
-                               continue;
-               }
-               else if (IS_FLG(FLG_JUNKS))
-               {
-                       switch(o_ptr->tval)
-                       {
-                       case TV_SKELETON: case TV_BOTTLE:
-                       case TV_JUNK: case TV_STATUE:
-                               break;
-                       default: continue;
-                       }
-               }
-               else if (IS_FLG(FLG_SPELLBOOKS))
-               {
-                       if (!(o_ptr->tval >= TV_LIFE_BOOK))
-                               continue;
-               }
-               else if (IS_FLG(FLG_HAFTED))
-               {
-                       if (!(o_ptr->tval == TV_HAFTED))
-                               continue;
-               }
-               else if (IS_FLG(FLG_SHIELDS))
-               {
-                       if (!(o_ptr->tval == TV_SHIELD))
-                               continue;
-               }
-               else if (IS_FLG(FLG_BOWS))
-               {
-                       if (!(o_ptr->tval == TV_BOW))
-                               continue;
-               }
-               else if (IS_FLG(FLG_RINGS))
-               {
-                       if (!(o_ptr->tval == TV_RING))
-                               continue;
-               }
-               else if (IS_FLG(FLG_AMULETS))
-               {
-                       if (!(o_ptr->tval == TV_AMULET))
-                               continue;
-               }
-               else if (IS_FLG(FLG_SUITS))
-               {
-                       if (!(o_ptr->tval == TV_DRAG_ARMOR ||
-                             o_ptr->tval == TV_HARD_ARMOR ||
-                             o_ptr->tval == TV_SOFT_ARMOR))
-                               continue;
-               }
-               else if (IS_FLG(FLG_CLOAKS))
+       /*** Second realm spellbooks ***/
+       if (IS_FLG(FLG_REALM2) &&
+           (REALM2_BOOK != o_ptr->tval ||
+            p_ptr->pclass == CLASS_SORCERER ||
+            p_ptr->pclass == CLASS_RED_MAGE))
+               return FALSE;
+
+       /*** First rank spellbooks ***/
+       if (IS_FLG(FLG_FIRST) &&
+           (o_ptr->tval < TV_LIFE_BOOK || 0 != o_ptr->sval))
+               return FALSE;
+
+       /*** Second rank spellbooks ***/
+       if (IS_FLG(FLG_SECOND) &&
+           (o_ptr->tval < TV_LIFE_BOOK || 1 != o_ptr->sval))
+               return FALSE;
+
+       /*** Third rank spellbooks ***/
+       if (IS_FLG(FLG_THIRD) && 
+           (o_ptr->tval < TV_LIFE_BOOK || 2 != o_ptr->sval))
+               return FALSE;
+
+       /*** Fourth rank spellbooks ***/
+       if (IS_FLG(FLG_FOURTH) &&
+           (o_ptr->tval < TV_LIFE_BOOK || 3 != o_ptr->sval))
+               return FALSE;
+
+       /*** Items ***/
+       if (IS_FLG(FLG_WEAPONS))
+       {
+               switch(o_ptr->tval)
                {
-                       if (!(o_ptr->tval == TV_CLOAK))
-                               continue;
+               case TV_BOW: case TV_HAFTED: case TV_POLEARM:
+               case TV_SWORD: case TV_DIGGING:
+                       break;
+               default: return FALSE;
                }
-               else if (IS_FLG(FLG_HELMS))
+       }
+       else if (IS_FLG(FLG_ARMORS))
+       {
+               switch(o_ptr->tval)
                {
-                       if (!(o_ptr->tval == TV_CROWN || o_ptr->tval == TV_HELM))
-                               continue;
+               case TV_BOOTS: case TV_GLOVES: case TV_CLOAK: case TV_CROWN:
+               case TV_HELM: case TV_SHIELD: case TV_SOFT_ARMOR:
+               case TV_HARD_ARMOR: case TV_DRAG_ARMOR:
+                       break;
+               default: return FALSE;
                }
-               else if (IS_FLG(FLG_GLOVES))
+       }
+       else if (IS_FLG(FLG_MISSILES))
+       {
+               switch(o_ptr->tval)
                {
-                       if (!(o_ptr->tval == TV_GLOVES))
-                               continue;
+               case TV_SHOT: case TV_BOLT: case TV_ARROW:
+                       break;
+               default: return FALSE;
                }
-               else if (IS_FLG(FLG_BOOTS))
+       }
+       else if (IS_FLG(FLG_DEVICES))
+       {
+               switch(o_ptr->tval)
                {
-                       if (!(o_ptr->tval == TV_BOOTS))
-                               continue;
+               case TV_SCROLL: case TV_STAFF: case TV_WAND: case TV_ROD:
+                       break;
+               default: return FALSE;
                }
-
-
-               if (*ptr == '^')
+       }
+       else if (IS_FLG(FLG_LIGHTS))
+       {
+               if (!(o_ptr->tval == TV_LITE))
+                       return FALSE;
+       }
+       else if (IS_FLG(FLG_JUNKS))
+       {
+               switch(o_ptr->tval)
                {
-                       ptr++;
-                       if (!strncmp(o_name, ptr, strlen(ptr)))
-                               flag = TRUE;
+               case TV_SKELETON: case TV_BOTTLE:
+               case TV_JUNK: case TV_STATUE:
+                       break;
+               default: return FALSE;
                }
-               else
+       }
+       else if (IS_FLG(FLG_SPELLBOOKS))
+       {
+               if (!(o_ptr->tval >= TV_LIFE_BOOK))
+                       return FALSE;
+       }
+       else if (IS_FLG(FLG_HAFTED))
+       {
+               if (!(o_ptr->tval == TV_HAFTED))
+                       return FALSE;
+       }
+       else if (IS_FLG(FLG_SHIELDS))
+       {
+               if (!(o_ptr->tval == TV_SHIELD))
+                       return FALSE;
+       }
+       else if (IS_FLG(FLG_BOWS))
+       {
+               if (!(o_ptr->tval == TV_BOW))
+                       return FALSE;
+       }
+       else if (IS_FLG(FLG_RINGS))
+       {
+               if (!(o_ptr->tval == TV_RING))
+                       return FALSE;
+       }
+       else if (IS_FLG(FLG_AMULETS))
+       {
+               if (!(o_ptr->tval == TV_AMULET))
+                       return FALSE;
+       }
+       else if (IS_FLG(FLG_SUITS))
+       {
+               if (!(o_ptr->tval == TV_DRAG_ARMOR ||
+                     o_ptr->tval == TV_HARD_ARMOR ||
+                     o_ptr->tval == TV_SOFT_ARMOR))
+                       return FALSE;
+       }
+       else if (IS_FLG(FLG_CLOAKS))
+       {
+               if (!(o_ptr->tval == TV_CLOAK))
+                       return FALSE;
+       }
+       else if (IS_FLG(FLG_HELMS))
+       {
+               if (!(o_ptr->tval == TV_CROWN || o_ptr->tval == TV_HELM))
+                       return FALSE;
+       }
+       else if (IS_FLG(FLG_GLOVES))
+       {
+               if (!(o_ptr->tval == TV_GLOVES))
+                       return FALSE;
+       }
+       else if (IS_FLG(FLG_BOOTS))
+       {
+               if (!(o_ptr->tval == TV_BOOTS))
+                       return FALSE;
+       }
+
+       /* Keyword don't match */
+       if (*ptr == '^')
+       {
+               ptr++;
+               if (strncmp(o_name, ptr, strlen(ptr))) return FALSE;
+       }
+       else
+       {
 #ifdef JP
-                       if (strstr_j(o_name, ptr))
+               if (!strstr_j(o_name, ptr)) return FALSE;
 #else
-                       if (strstr(o_name, ptr))
+               if (!strstr(o_name, ptr)) return FALSE;
 #endif
-               {
-                       flag = TRUE;
-               }
+       }
 
-               if (flag)
-               {
-                       int j;
-                       if (!IS_FLG(FLG_COLLECTING))
-                               return i;
-                       /* Check if there is a same item */
-                       for (j = 0; j < INVEN_PACK; j++)
-                       {
-                               /*
-                                * 'Collecting' means the item must be absorbed 
-                                * into an inventory slot.
-                                * But an item can not be absorbed into itself!
-                                */
-                               if ((&inventory[j] != o_ptr) &&
-                                   object_similar(&inventory[j], o_ptr))
-                                       return i;
-                       }
-               }
-       }/* for */
+       /* TRUE when it need not to be 'collecting' */
+       if (!IS_FLG(FLG_COLLECTING)) return TRUE;
+
+       /* Check if there is a same item */
+       for (j = 0; j < INVEN_PACK; j++)
+       {
+               /*
+                * 'Collecting' means the item must be absorbed 
+                * into an inventory slot.
+                * But an item can not be absorbed into itself!
+                */
+               if ((&inventory[j] != o_ptr) &&
+                   object_similar(&inventory[j], o_ptr))
+                       return TRUE;
+       }
+
+       /* Not collecting */
+       return FALSE;
+}
+
+
+/*
+ * A function for Auto-picker/destroyer
+ * Examine whether the object matches to the list of keywords or not.
+ */
+int is_autopick(object_type *o_ptr)
+{
+       int i;
+       char o_name[MAX_NLEN];
+
+       if (o_ptr->tval == TV_GOLD) return -1;
+       
+       object_desc(o_name, o_ptr, FALSE, 3);
+
+       /* Force to be lower case string */
+       for (i = 0; o_name[i]; i++)
+       {
+#ifdef JP
+               if (iskanji(o_name[i]))
+                       i++;
+               else
+#endif
+               if (isupper(o_name[i]))
+                       o_name[i] = tolower(o_name[i]);
+       }
+       
+       for (i=0; i < max_autopick; i++)
+       {
+               autopick_type *entry = &autopick_list[i];
+
+               if (is_autopick_aux(o_ptr, entry, o_name)) return i;
+       }
 
+       /* No matching entry */
        return -1;
 }
 
@@ -766,6 +933,39 @@ static bool is_opt_confirm_destroy(object_type *o_ptr)
        
        if (leave_junk)
                if ((o_ptr->tval == TV_SKELETON) || (o_ptr->tval == TV_BOTTLE) || (o_ptr->tval == TV_JUNK) || (o_ptr->tval == TV_STATUE)) return FALSE;
+
+       if (leave_special)
+       {
+#if 0
+               if (p_ptr->prace == RACE_SKELETON)
+               {
+                       if (o_ptr->tval == TV_SKELETON ||
+                           (o_ptr->tval == TV_CORPSE && o_ptr->sval == SV_SKELETON))
+                               return FALSE;
+               }
+               else 
+#endif
+               if (p_ptr->prace == RACE_DEMON)
+               {
+                       if (o_ptr->tval == TV_CORPSE &&
+                           o_ptr->sval == SV_CORPSE &&
+                           strchr("pht", r_info[o_ptr->pval].d_char))
+                               return FALSE;
+               }
+
+               if (p_ptr->pclass == CLASS_ARCHER)
+               {
+                       if (o_ptr->tval == TV_SKELETON ||
+                           (o_ptr->tval == TV_CORPSE && o_ptr->sval == SV_SKELETON))
+                               return FALSE;
+               }
+               else if (p_ptr->pclass == CLASS_NINJA)
+               {
+                       if (o_ptr->tval == TV_LITE &&
+                           o_ptr->name2 == EGO_LITE_DARKNESS)
+                               return FALSE;
+               }
+       }
        
        if (o_ptr->tval == TV_GOLD) return FALSE;
        
@@ -786,23 +986,25 @@ void auto_inscribe_item(int item, int idx)
        /* Get the item (on the floor) */
        else o_ptr = &o_list[0 - item];
 
-       if (idx >= 0 && autopick_list[idx].insc && !o_ptr->inscription)
-       {
-               o_ptr->inscription = inscribe_flags(o_ptr, autopick_list[idx].insc);
+       /* Auto-inscription or Re-inscribe for resistances {%} */
+       if ((idx < 0 || !autopick_list[idx].insc) && !o_ptr->inscription)
+               return;
 
-               if (item >= INVEN_RARM)
-               {
-                       /* Redraw inscription */
-                       p_ptr->window |= (PW_EQUIP);
+       if (!o_ptr->inscription)
+               o_ptr->inscription = quark_add(autopick_list[idx].insc);
 
-                       /* {.} and {$} effect p_ptr->warning and TRC_TELEPORT_SELF */
-                       p_ptr->update |= (PU_BONUS);
-               }
-               else if (item >= 0)
-               {
-                       /* Redraw inscription */
-                       p_ptr->window |= (PW_INVEN);
-               }
+       if (item > INVEN_PACK)
+       {
+               /* Redraw inscription */
+               p_ptr->window |= (PW_EQUIP);
+
+               /* {.} and {$} effect p_ptr->warning and TRC_TELEPORT_SELF */
+               p_ptr->update |= (PU_BONUS);
+       }
+       else if (item >= 0)
+       {
+               /* Redraw inscription */
+               p_ptr->window |= (PW_INVEN);
        }
 }
 
@@ -812,40 +1014,90 @@ void auto_inscribe_item(int item, int idx)
  */
 bool auto_destroy_item(int item, int autopick_idx)
 {
-       char o_name[MAX_NLEN];
+       bool destroy = FALSE;
        object_type *o_ptr;
 
+       /* Don't destroy equipped items */
+       if (item > INVEN_PACK) return FALSE;
+
        /* Get the item (in the pack) */
        if (item >= 0) o_ptr = &inventory[item];
 
        /* Get the item (on the floor) */
        else o_ptr = &o_list[0 - item];
 
-       if ((autopick_idx == -1 && is_opt_confirm_destroy(o_ptr)) ||
-           (autopick_idx >= 0 && (autopick_list[autopick_idx].action & DO_AUTODESTROY)))
+       /* Easy-Auto-Destroyer */
+       if (is_opt_confirm_destroy(o_ptr)) destroy = TRUE;
+
+       /* Protected by auto-picker */
+       if (autopick_idx >= 0 &&
+           !(autopick_list[autopick_idx].action & DO_AUTODESTROY))
+               destroy = FALSE;
+
+       if (!always_pickup)
+       {
+               /* Auto-picker/destroyer */
+               if (autopick_idx >= 0 &&
+                   (autopick_list[autopick_idx].action & DO_AUTODESTROY))
+                       destroy = TRUE;
+       }
+
+       /* Not to be destroyed */
+       if (!destroy) return FALSE;
+
+       /* Now decided to destroy */
+
+       disturb(0,0);
+
+       /* Artifact? */
+       if (!can_player_destroy_object(o_ptr))
        {
-               disturb(0,0);
+               char o_name[MAX_NLEN];
 
                /* Describe the object (with {terrible/special}) */
                object_desc(o_name, o_ptr, TRUE, 3);
 
-               /* Artifact? */
-               if (!can_player_destroy_object(o_ptr))
-               {
-                       /* Message */
+               /* Message */
 #ifdef JP
-                       msg_format("%s¤ÏÇ˲õÉÔǽ¤À¡£", o_name);
+               msg_format("%s¤ÏÇ˲õÉÔǽ¤À¡£", o_name);
 #else
-                       msg_format("You cannot auto-destroy %s.", o_name);
+               msg_format("You cannot auto-destroy %s.", o_name);
 #endif
 
-                       /* Done */
-                       return TRUE;
-               }
+               /* Done */
+               return TRUE;
+       }
+
+       /* Record name of destroyed item */
+       COPY(&autopick_last_destroyed_object, o_ptr, object_type);
 
-               /* Record name of destroyed item */
-               autopick_free_entry(&autopick_entry_last_destroyed);
-               autopick_entry_from_object(&autopick_entry_last_destroyed, o_ptr);
+       /* Destroy Later */
+       o_ptr->marked |= OM_AUTODESTROY;
+       p_ptr->notice |= PN_AUTODESTROY;
+
+       return TRUE;
+}
+
+
+/*
+ *  Auto-destroy marked item
+ */
+static void delayed_auto_destroy_aux(int item)
+{
+       object_type *o_ptr;
+
+       /* Get the item (in the pack) */
+       if (item >= 0) o_ptr = &inventory[item];
+
+       /* Get the item (on the floor) */
+       else o_ptr = &o_list[0 - item];
+
+       if (o_ptr->k_idx && o_ptr->marked & OM_AUTODESTROY)
+       {
+               char o_name[MAX_NLEN];
+
+               /* Describe the object (with {terrible/special}) */
+               object_desc(o_name, o_ptr, TRUE, 3);
 
                /* Eliminate the item (from the pack) */
                if (item >= 0)
@@ -866,11 +1118,32 @@ bool auto_destroy_item(int item, int autopick_idx)
 #else
                msg_format("Auto-destroying %s.", o_name);
 #endif
-                       
-               return TRUE;
        }
+}
 
-       return FALSE;
+
+/*
+ *  Auto-destroy marked item in inventry and on floor
+ */
+void delayed_auto_destroy(void)
+{
+       int item;
+
+       /* 
+        * Scan inventry in reverse order to prevent
+        * skipping after inven_item_optimize()
+        */
+       for (item = INVEN_TOTAL - 1; item >= 0 ; item--)
+               delayed_auto_destroy_aux(item);
+
+       /* Scan the pile of objects */
+       item = cave[py][px].o_idx;
+       while (item)
+       {
+               int next = o_list[item].next_o_idx;
+               delayed_auto_destroy_aux(-item);
+               item = next;
+       }
 }
 
 
@@ -897,7 +1170,8 @@ void auto_pickup_items(cave_type *c_ptr)
                /* Item index for floor -1,-2,-3,...  */
                auto_inscribe_item((-this_o_idx), idx);
 
-               if (idx >= 0 && (autopick_list[idx].action & DO_AUTOPICK))
+               if (idx >= 0 &&
+                       (autopick_list[idx].action & (DO_AUTOPICK | DO_QUERY_AUTOPICK)))
                {
                        disturb(0,0);
 
@@ -914,8 +1188,39 @@ void auto_pickup_items(cave_type *c_ptr)
 #else
                                msg_format("You have no room for %s.", o_name);
 #endif
+                               /* Hack - remember that the item has given a message here. */
+                               o_ptr->marked |= OM_NOMSG;
+
                                continue;
                        }
+                       else if (autopick_list[idx].action & DO_QUERY_AUTOPICK)
+                       {
+                               char out_val[MAX_NLEN+20];
+                               char o_name[MAX_NLEN];
+
+                               if (o_ptr->marked & OM_NO_QUERY)
+                               {
+                                       /* Already answered as 'No' */
+                                       continue;
+                               }
+
+                               /* Describe the object */
+                               object_desc(o_name, o_ptr, TRUE, 3);
+
+#ifdef JP
+                               sprintf(out_val, "%s¤ò½¦¤¤¤Þ¤¹¤«? ", o_name);
+#else
+                               sprintf(out_val, "Pick up %s? ", o_name);
+#endif
+
+                               if (!get_check(out_val))
+                               {
+                                       /* Hack - remember that the item has given a message here. */
+                                       o_ptr->marked |= (OM_NOMSG | OM_NO_QUERY);
+                                       continue;
+                               }
+
+                       }
                        py_pickup_aux(this_o_idx);
 
                        continue;
@@ -929,7 +1234,7 @@ void auto_pickup_items(cave_type *c_ptr)
                 */
                else
                {
-                       if (auto_destroy_item((-this_o_idx), (!always_pickup ? idx : -2)))
+                       if (auto_destroy_item((-this_o_idx), idx))
                                continue;
                }
        }
@@ -949,7 +1254,7 @@ static void describe_autopick(char *buff, autopick_type *entry)
        bool top = FALSE;
 
 #ifdef JP
-       cptr before_str[20], body_str;
+       cptr before_str[100], body_str;
        int before_n = 0;
 
        body_str = "¥¢¥¤¥Æ¥à";
@@ -971,21 +1276,6 @@ static void describe_autopick(char *buff, autopick_type *entry)
        if (IS_FLG(FLG_STAR_IDENTIFIED))
                before_str[before_n++] = "´°Á´¤Ë´ÕÄêºÑ¤ß¤Î";
 
-       /*** Nameless ***/
-       if (IS_FLG(FLG_NAMELESS))
-       {
-               before_str[before_n++] = "¥¨¥´¤Ç¤â¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È¤Ç¤â¤Ê¤¤";
-               body_str = "ÁõÈ÷";
-       }
-
-       /*** Unaware items ***/
-       if (IS_FLG(FLG_UNAWARE))
-               before_str[before_n++] = "̤´ÕÄê¤Ç¤½¤Î¸ú²Ì¤âȽÌÀ¤·¤Æ¤¤¤Ê¤¤";
-
-       /*** Worthless items ***/
-       if (IS_FLG(FLG_WORTHLESS))
-               before_str[before_n++] = "Ź¤Ç̵²ÁÃͤÈȽÄꤵ¤ì¤ë";
-
        /*** Dice boosted (weapon of slaying) ***/
        if (IS_FLG(FLG_BOOSTED))
        {
@@ -1000,11 +1290,51 @@ static void describe_autopick(char *buff, autopick_type *entry)
                before_str[before_n++] = "¥À¥á¡¼¥¸¥À¥¤¥¹¤ÎºÇÂçÃͤ¬";
                body_str = "Éð´ï";
                        
-               sprintf(more_than_desc_str,"%2d", entry->dice);
+               sprintf(more_than_desc_str,"%d", entry->dice);
                before_str[before_n++] = more_than_desc_str;
                before_str[before_n++] = "°Ê¾å¤Î";
        }
 
+       /*** Items whose magical bonus is more than nn ***/
+       if (IS_FLG(FLG_MORE_BONUS))
+       {
+               static char more_bonus_desc_str[] = "___";
+               before_str[before_n++] = "½¤ÀµÃͤ¬(+";
+                       
+               sprintf(more_bonus_desc_str,"%d", entry->bonus);
+               before_str[before_n++] = more_bonus_desc_str;
+               before_str[before_n++] = ")°Ê¾å¤Î";
+       }
+
+       /*** Worthless items ***/
+       if (IS_FLG(FLG_WORTHLESS))
+               before_str[before_n++] = "Ź¤Ç̵²ÁÃͤÈȽÄꤵ¤ì¤ë";
+
+       /*** Artifact ***/
+       if (IS_FLG(FLG_ARTIFACT))
+       {
+               before_str[before_n++] = "¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È¤Î";
+               body_str = "ÁõÈ÷";
+       }
+
+       /*** Ego ***/
+       if (IS_FLG(FLG_EGO))
+       {
+               before_str[before_n++] = "¥¨¥´¥¢¥¤¥Æ¥à¤Î";
+               body_str = "ÁõÈ÷";
+       }
+
+       /*** Nameless ***/
+       if (IS_FLG(FLG_NAMELESS))
+       {
+               before_str[before_n++] = "¥¨¥´¤Ç¤â¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È¤Ç¤â¤Ê¤¤";
+               body_str = "ÁõÈ÷";
+       }
+
+       /*** Unaware items ***/
+       if (IS_FLG(FLG_UNAWARE))
+               before_str[before_n++] = "̤´ÕÄê¤Ç¤½¤Î¸ú²Ì¤âȽÌÀ¤·¤Æ¤¤¤Ê¤¤";
+
        /*** Wanted monster's corpse/skeletons ***/
        if (IS_FLG(FLG_WANTED))
        {
@@ -1029,7 +1359,7 @@ static void describe_autopick(char *buff, autopick_type *entry)
        /*** Unreadable spellbooks ***/
        if (IS_FLG(FLG_UNREADABLE))
        {
-               before_str[before_n++] = "Îΰ褬°Û¤Ê¤ë°Ù¤Ë¤¢¤Ê¤¿¤Ë¤ÏÆɤá¤Ê¤¤";
+               before_str[before_n++] = "¤¢¤Ê¤¿¤¬Æɤá¤Ê¤¤Îΰè¤Î";
                body_str = "ËâË¡½ñ";
        }
 
@@ -1078,8 +1408,6 @@ static void describe_autopick(char *buff, autopick_type *entry)
        /*** Items ***/
        if (IS_FLG(FLG_ITEMS))
                ; /* Nothing to do */
-       else if (IS_FLG(FLG_ARTIFACTS))
-               body_str = "¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È";
        else if (IS_FLG(FLG_WEAPONS))
                body_str = "Éð´ï";
        else if (IS_FLG(FLG_ARMORS))
@@ -1111,7 +1439,7 @@ static void describe_autopick(char *buff, autopick_type *entry)
        else if (IS_FLG(FLG_HELMS))
                body_str = "¥Ø¥ë¥á¥Ã¥È¤ä´§";
        else if (IS_FLG(FLG_GLOVES))
-               body_str = "¾®¼ê";
+               body_str = "äƼê";
        else if (IS_FLG(FLG_BOOTS))
                body_str = "¥Ö¡¼¥Ä";
 
@@ -1140,7 +1468,20 @@ static void describe_autopick(char *buff, autopick_type *entry)
        }
 
        if (insc)
-               strncat(buff, format("¤Ë¡Ö%s¡×¤È¹ï¤ó¤Ç", insc), 80);
+       {
+               strncat(buff, format("¤Ë¡Ö%s¡×", insc), 80);
+
+               if (strstr(insc, "%%all"))
+                       strcat(buff, "(%%all¤ÏÁ´Ç½ÎϤòɽ¤¹±Ñ»ú¤Îµ­¹æ¤ÇÃÖ´¹)");
+               else if (strstr(insc, "%all"))
+                       strcat(buff, "(%all¤ÏÁ´Ç½ÎϤòɽ¤¹µ­¹æ¤ÇÃÖ´¹)");
+               else if (strstr(insc, "%%"))
+                       strcat(buff, "(%%¤ÏÄɲÃǽÎϤòɽ¤¹±Ñ»ú¤Îµ­¹æ¤ÇÃÖ´¹)");
+               else if (strstr(insc, "%"))
+                       strcat(buff, "(%¤ÏÄɲÃǽÎϤòɽ¤¹µ­¹æ¤ÇÃÖ´¹)");
+
+               strcat(buff, "¤È¹ï¤ó¤Ç");
+       }
        else
                strcat(buff, "¤ò");
 
@@ -1148,6 +1489,8 @@ static void describe_autopick(char *buff, autopick_type *entry)
                strcat(buff, "ÊüÃÖ¤¹¤ë¡£");
        else if (act & DO_AUTODESTROY)
                strcat(buff, "Ç˲õ¤¹¤ë¡£");
+       else if (act & DO_QUERY_AUTOPICK)
+               strcat(buff, "³Îǧ¤Î¸å¤Ë½¦¤¦¡£");
        else
                strcat(buff, "½¦¤¦¡£");
 
@@ -1187,6 +1530,25 @@ static void describe_autopick(char *buff, autopick_type *entry)
        if (IS_FLG(FLG_STAR_IDENTIFIED))
                before_str[before_n++] = "fully identified";
 
+       /*** Worthless items ***/
+       if (IS_FLG(FLG_WORTHLESS))
+       {
+               before_str[before_n++] = "worthless";
+               which_str[which_n++] = "can not be sold at stores";
+       }
+
+       /*** Artifacto ***/
+       if (IS_FLG(FLG_ARTIFACT))
+       {
+               before_str[before_n++] = "artifact";
+       }
+
+       /*** Ego ***/
+       if (IS_FLG(FLG_EGO))
+       {
+               before_str[before_n++] = "ego";
+       }
+
        /*** Nameless ***/
        if (IS_FLG(FLG_NAMELESS))
        {
@@ -1201,13 +1563,6 @@ static void describe_autopick(char *buff, autopick_type *entry)
                whose_str[whose_n++] = "basic abilities are not known";
        }
 
-       /*** Worthless items ***/
-       if (IS_FLG(FLG_WORTHLESS))
-       {
-               before_str[before_n++] = "worthless";
-               which_str[which_n++] = "can not be sold at stores";
-       }
-
        /*** Dice boosted (weapon of slaying) ***/
        if (IS_FLG(FLG_BOOSTED))
        {
@@ -1215,7 +1570,7 @@ static void describe_autopick(char *buff, autopick_type *entry)
                whose_str[whose_n++] = "damage dice is bigger than normal";
        }
 
-       /*** Weapons whic dd*ds is more than nn ***/
+       /*** Weapons whose dd*ds is more than nn ***/
        if (IS_FLG(FLG_MORE_THAN))
        {
                static char more_than_desc_str[] =
@@ -1223,10 +1578,21 @@ static void describe_autopick(char *buff, autopick_type *entry)
                body_str = "weapons";
                        
                sprintf(more_than_desc_str + sizeof(more_than_desc_str) - 3,
-                       "%2d", entry->dice);
+                       "%d", entry->dice);
                whose_str[whose_n++] = more_than_desc_str;
        }
 
+       /*** Items whose magical bonus is more than nn ***/
+       if (IS_FLG(FLG_MORE_BONUS))
+       {
+               static char more_bonus_desc_str[] =
+                       "magical bonus is bigger than (+__)";
+                       
+               sprintf(more_bonus_desc_str + sizeof(more_bonus_desc_str) - 4,
+                       "%d)", entry->bonus);
+               whose_str[whose_n++] = more_bonus_desc_str;
+       }
+
        /*** Wanted monster's corpse/skeletons ***/
        if (IS_FLG(FLG_WANTED))
        {
@@ -1355,12 +1721,23 @@ static void describe_autopick(char *buff, autopick_type *entry)
                strcpy(buff, "Leave on floor ");
        else if (act & DO_AUTODESTROY)
                strcpy(buff, "Destroy ");
+       else if (act & DO_QUERY_AUTOPICK)
+               strcpy(buff, "Ask to pick up ");
        else
                strcpy(buff, "Pickup ");
 
        /* Auto-insctiption */
        if (insc)
-               strncat(buff, format("and inscribe \"%s\" on ", insc), 80);
+       {
+               strncat(buff, format("and inscribe \"%s\"", insc), 80);
+
+               if (strstr(insc, "%all"))
+                       strcat(buff, ", replacing %all with code string representing all abilities,");
+               else if (strstr(insc, "%"))
+                       strcat(buff, ", replacing % with code string representing extra random abilities,");
+
+               strcat(buff, " on ");
+       }
 
        /* Adjective */
        if (!before_n) 
@@ -1426,11 +1803,11 @@ static void describe_autopick(char *buff, autopick_type *entry)
        if (act & DO_DISPLAY)
        {
                if (act & DONT_AUTOPICK)
-                       strcat(buff, "  Display these items when you press 'N' in the full map('M').");
+                       strcat(buff, "  Display these items when you press the N key in the full 'M'ap.");
                else if (act & DO_AUTODESTROY)
-                       strcat(buff, "  Display these items when you press 'K' in the full map('M').");
+                       strcat(buff, "  Display these items when you press the K key in the full 'M'ap.");
                else
-                       strcat(buff, "  Display these items when you press 'M' in the full map('M').");
+                       strcat(buff, "  Display these items when you press the M key in the full 'M'ap.");
        }
        else
                strcat(buff, " Not displayed in the full map.");
@@ -1454,13 +1831,11 @@ static cptr *read_text_lines(cptr filename, bool user)
 
        if (user)
        {
-               /* Hack -- drop permissions */
-               safe_setuid_drop();
-               path_build(buf, 1024, ANGBAND_DIR_USER, filename);
+               path_build(buf, sizeof(buf), ANGBAND_DIR_USER, filename);
        }
        else
        {
-               path_build(buf, 1024, ANGBAND_DIR_PREF, filename);
+               path_build(buf, sizeof(buf), ANGBAND_DIR_PREF, filename);
        }
        
        /* Open the file */
@@ -1472,7 +1847,7 @@ static cptr *read_text_lines(cptr filename, bool user)
                C_MAKE(lines_list, MAX_LINES, cptr);
 
                /* Parse it */
-               while (0 == my_fgets(fff, buf, 1024))
+               while (0 == my_fgets(fff, buf, sizeof(buf)))
                {
                        lines_list[lines++] = string_make(buf);
                        if (lines >= MAX_LINES - 1) break;
@@ -1483,14 +1858,15 @@ static cptr *read_text_lines(cptr filename, bool user)
                my_fclose(fff);
        }
 
-       /* Grab priv's */
-       safe_setuid_grab();
-
        if (!fff) return NULL;
        return lines_list;
 }
 
-static cptr *read_pickpref_text_lines()
+
+#define PT_DEFAULT 0
+#define PT_WITH_PNAME 1
+
+static cptr *read_pickpref_text_lines(int *filename_mode_p)
 {
        char buf[1024];
        cptr *lines_list;
@@ -1509,6 +1885,7 @@ static cptr *read_pickpref_text_lines()
 #else
                lines_list = read_text_lines("pickpref.prf", TRUE);
 #endif
+               *filename_mode_p = PT_DEFAULT;
        }
 
        if (!lines_list)
@@ -1518,6 +1895,7 @@ static cptr *read_pickpref_text_lines()
 #else
                lines_list = read_text_lines("pickpref.prf", FALSE);
 #endif
+               *filename_mode_p = PT_WITH_PNAME;
        }
 
        if (!lines_list)
@@ -1525,6 +1903,7 @@ static cptr *read_pickpref_text_lines()
                /* Allocate list of pointers */
                C_MAKE(lines_list, MAX_LINES, cptr);
                lines_list[0] = string_make("");
+               *filename_mode_p = PT_WITH_PNAME;
        }
        return lines_list;
 }
@@ -1539,11 +1918,8 @@ static bool write_text_lines(cptr filename, cptr *lines_list)
        int lines = 0;
        char buf[1024];
 
-       /* Hack -- drop permissions */
-       safe_setuid_drop();
-
        /* Build the filename */
-       path_build(buf, 1024, ANGBAND_DIR_USER, filename);
+       path_build(buf, sizeof(buf), ANGBAND_DIR_USER, filename);
        
        /* Open the file */
        fff = my_fopen(buf, "w");
@@ -1555,9 +1931,6 @@ static bool write_text_lines(cptr filename, cptr *lines_list)
                my_fclose(fff);
        }
 
-       /* Grab priv's */
-       safe_setuid_grab();
-
        if (!fff) return FALSE;
        return TRUE;
 }
@@ -1579,55 +1952,9 @@ static void free_text_lines(cptr *lines_list)
 
 
 /*
- * Insert string
- */
-static void insert_string(cptr *lines_list, cptr str, int x, int y)
-{
-       char buf[1024];
-       int i, j;
-
-       for (i = j = 0; lines_list[y][i] && i < x; i++)
-               buf[j++] = lines_list[y][i];
-
-       while (*str) buf[j++] = *str++;
-
-       for (; lines_list[y][i]; i++)
-               buf[j++] = lines_list[y][i];
-       buf[j] = '\0';
-       string_free(lines_list[y]);
-       lines_list[y] = string_make(buf);
-}
-
-/*
- * Delete n letters
- */
-static void delete_string(cptr *lines_list, int n, int x, int y)
-{
-       int i, j;
-       char buf[1024];
-
-       for (i = j = 0; lines_list[y][i] && i < x; i++)
-       {
-#ifdef JP
-               if (iskanji(lines_list[y][i]))
-                       buf[j++] = lines_list[y][i++];
-#endif
-               buf[j++] = lines_list[y][i];
-       }
-       i += n;
-
-       for (; lines_list[y][i]; i++)
-               buf[j++] = lines_list[y][i];
-       buf[j] = '\0';
-       string_free(lines_list[y]);
-       lines_list[y] = string_make(buf);
-}
-
-
-/*
  * Delete or insert string
  */
-void toggle_string(cptr *lines_list, int flg, int y)
+static void toggle_string(cptr *lines_list, int flg, int y)
 {
        autopick_type an_entry, *entry = &an_entry;
 
@@ -1640,7 +1967,7 @@ void toggle_string(cptr *lines_list, int flg, int y)
        else
                ADD_FLG(flg);
 
-       lines_list[y] = autopick_line_from_entry(entry);
+       lines_list[y] = autopick_line_from_entry_kill(entry);
 }
 
 /*
@@ -1648,7 +1975,7 @@ void toggle_string(cptr *lines_list, int flg, int y)
  */
 static bool insert_return_code(cptr *lines_list, int cx, int cy)
 {
-       char buf[1024];
+       char buf[MAX_LINELEN];
        int i, j, k;
 
        for (k = 0; lines_list[k]; k++)
@@ -1697,6 +2024,14 @@ void autopick_entry_from_object(autopick_type *entry, object_type *o_ptr)
        if (object_value(o_ptr) <= 0)
                ADD_FLG(FLG_WORTHLESS);
 
+       if (object_known_p(o_ptr))
+       {
+               if (o_ptr->name2)
+                       ADD_FLG(FLG_EGO);
+               else if (o_ptr->name1 || o_ptr->art_name)
+                       ADD_FLG(FLG_ARTIFACT);
+       }
+
        switch(o_ptr->tval)
        {
                object_kind *k_ptr; 
@@ -1748,10 +2083,7 @@ void autopick_entry_from_object(autopick_type *entry, object_type *o_ptr)
        if (o_ptr->tval >= TV_LIFE_BOOK && 3 == o_ptr->sval)
                ADD_FLG(FLG_FOURTH);
 
-       if (object_known_p(o_ptr) && (artifact_p(o_ptr) || o_ptr->art_name))
-               ADD_FLG(FLG_ARTIFACTS);
-       
-       else if (o_ptr->tval == TV_SHOT || o_ptr->tval == TV_BOLT
+       if (o_ptr->tval == TV_SHOT || o_ptr->tval == TV_BOLT
                 || o_ptr->tval == TV_ARROW)
                ADD_FLG(FLG_MISSILES);
        else if (o_ptr->tval == TV_SCROLL || o_ptr->tval == TV_STAFF
@@ -1792,12 +2124,29 @@ void autopick_entry_from_object(autopick_type *entry, object_type *o_ptr)
        return;
 }
 
+
 /*
  * Choose an item and get auto-picker entry from it.
  */
-static bool entry_from_object(autopick_type *entry)
+static object_type *choose_object(cptr q, cptr s)
 {
        int item;
+
+       if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EQUIP))) return NULL;
+
+       /* Get the item (in the pack) */
+       if (item >= 0) return &inventory[item];
+
+       /* Get the item (on the floor) */
+       else return &o_list[0 - item];
+}
+
+
+/*
+ * Choose an item and get auto-picker entry from it.
+ */
+static bool entry_from_choosed_object(autopick_type *entry)
+{
        object_type *o_ptr;
        cptr q, s;
 
@@ -1806,25 +2155,239 @@ static bool entry_from_object(autopick_type *entry)
        q = "¤É¤Î¥¢¥¤¥Æ¥à¤òÅÐÏ¿¤·¤Þ¤¹¤«? ";
        s = "¥¢¥¤¥Æ¥à¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¡£";
 #else
-       q = "Entry which item? ";
-       s = "You have nothing to entry.";
+       q = "Enter which item? ";
+       s = "You have nothing to enter.";
 #endif
-       if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR | USE_EQUIP))) return FALSE;
+       o_ptr = choose_object(q, s);
+       if (!o_ptr) return FALSE;
 
-       /* Get the item (in the pack) */
-       if (item >= 0)
+       autopick_entry_from_object(entry, o_ptr);
+       return TRUE;
+}
+
+
+/*
+ * Choose an item or string for search
+ */
+static bool get_string_for_search(object_type **o_handle, cptr *search_strp)
+{
+       int pos = 0;
+       cptr q, s;
+       char buf[MAX_NLEN+20];
+
+#ifdef JP
+       int k_flag[MAX_NLEN+20];
+       char prompt[] = "¸¡º÷(^I:»ý¤Áʪ ^L:Ç˲õ¤µ¤ì¤¿Êª): ";
+#else
+       char prompt[] = "Search key(^I:inven ^L:destroyed): ";
+#endif
+       int col = sizeof(prompt) - 1;
+
+       if (*search_strp) strcpy(buf, *search_strp);
+       else buf[0] = '\0';
+
+       /* Display prompt */
+       prt(prompt, 0, 0);
+
+       /* Display the default answer */
+       Term_erase(col, 0, 255);
+       Term_putstr(col, 0, -1, TERM_YELLOW, buf);
+
+       /* Process input */
+       while (1)
        {
-               o_ptr = &inventory[item];
+               object_type *o_ptr;
+               int i;
+
+               /* Place cursor */
+               Term_gotoxy(col + pos, 0);
+
+               /* Do not process macros except special keys */
+               inkey_special = TRUE;
+
+               /* Get a key */
+               i = inkey();
+
+               /* Analyze the key */
+               switch (i)
+               {
+               case ESCAPE:
+                       pos = 0;
+                       return FALSE;
+
+               case '\n':
+               case '\r':
+                       if (!pos && *o_handle) return TRUE;
+                       string_free(*search_strp);
+                       *search_strp = string_make(buf);
+                       *o_handle = NULL;
+                       return TRUE;
+
+               case KTRL('i'):
+                       /* Get an item */
+#ifdef JP
+                       q = "¤É¤Î¥¢¥¤¥Æ¥à¤ò¸¡º÷¤·¤Þ¤¹¤«? ";
+                       s = "¥¢¥¤¥Æ¥à¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¡£";
+#else
+                       q = "Enter which item? ";
+                       s = "You have nothing to enter.";
+#endif
+                       o_ptr = choose_object(q, s);
+                       if (!o_ptr) return FALSE;
+
+                       *o_handle = o_ptr;
+
+                       string_free(*search_strp);
+                       object_desc(buf, *o_handle, FALSE, 3);
+                       *search_strp = string_make(format("<%s>", buf));
+                       return TRUE;
+
+               case KTRL('l'):
+                       if (!autopick_last_destroyed_object.k_idx) break;
+                       *o_handle = &autopick_last_destroyed_object;
+
+                       string_free(*search_strp);
+                       object_desc(buf, *o_handle, FALSE, 3);
+                       *search_strp = string_make(format("<%s>", buf));
+                       return TRUE;
+
+               case 0x7F:
+               case '\010':
+#ifdef JP
+                       if (pos > 0)
+                       {
+                               pos--;
+                               if (k_flag[pos]) pos--;
+                       }
+#else
+                       if (pos > 0) pos--;
+#endif
+                       break;
+
+               default:
+#ifdef JP
+                       if (iskanji(i))
+                       {
+                               int next;
+
+                               inkey_base = TRUE;
+                               next = inkey ();
+                               if (pos + 1 < MAX_NLEN)
+                               {
+                                       buf[pos++] = i;
+                                       buf[pos] = next;
+                                       k_flag[pos++] = 1;
+                               }
+                               else bell();
+                       }
+                       else if (pos < MAX_NLEN && isprint(i))
+                       {
+                               buf[pos] = i;
+                               k_flag[pos++] = 0;
+                       }
+                       else bell();
+#else
+                       if (pos < MAX_NLEN && isprint(i)) buf[pos++] = i;
+                       else bell();
+#endif
+                       break;
+               }
+
+               /* Terminate */
+               buf[pos] = '\0';
+
+               /* Update the entry */
+               Term_erase(col, 0, 255);
+               Term_putstr(col, 0, -1, TERM_WHITE, buf);
        }
 
-       /* Get the item (on the floor) */
-       else
+       /* Never reached */
+}
+
+
+/*
+ * Search next line matches for o_ptr
+ */
+static bool search_for_object(cptr *lines_list, object_type *o_ptr, int *cxp, int *cyp, bool forward)
+{
+       int i;
+       autopick_type an_entry, *entry = &an_entry;
+       char o_name[MAX_NLEN];
+
+       object_desc(o_name, o_ptr, FALSE, 3);
+
+       /* Force to be lower case string */
+       for (i = 0; o_name[i]; i++)
        {
-               o_ptr = &o_list[0 - item];
+#ifdef JP
+               if (iskanji(o_name[i]))
+                       i++;
+               else
+#endif
+               if (isupper(o_name[i]))
+                       o_name[i] = tolower(o_name[i]);
        }
+       
+       i = *cyp;
 
-       autopick_entry_from_object(entry, o_ptr);
-       return TRUE;
+       while (1)
+       {
+               if (forward)
+               {
+                       if (!lines_list[++i]) break;
+               }
+               else
+               {
+                       if (--i < 0) break;
+               }
+
+               if (!autopick_new_entry(entry, lines_list[i])) continue;
+
+               if (is_autopick_aux(o_ptr, entry, o_name))
+               {
+                       *cxp = 0;
+                       *cyp = i;
+                       return TRUE;
+               }
+       }
+
+       return FALSE;
+}
+
+
+/*
+ * Search next line matches to the string
+ */
+static bool search_for_string(cptr *lines_list, cptr search_str, int *cxp, int *cyp, bool forward)
+{
+       int i = *cyp;
+
+       while (1)
+       {
+               cptr pos;
+
+               if (forward)
+               {
+                       if (!lines_list[++i]) break;
+               }
+               else
+               {
+                       if (--i < 0) break;
+               }
+#ifdef JP
+               pos = strstr_j(lines_list[i], search_str);
+#else
+               pos = strstr(lines_list[i], search_str);
+#endif
+               if (pos)
+               {
+                       *cxp = (int)(pos - lines_list[i]);
+                       *cyp = i;
+                       return TRUE;
+               }
+       }
+
+       return FALSE;
 }
 
 
@@ -1841,11 +2404,164 @@ void init_autopicker(void)
        for( i = 0; i < max_autopick; i++)
                autopick_free_entry(&autopick_list[i]);
 
-       max_autopick = 0;
+       max_autopick = 0;
+
+       /* There is always one entry "=g" */
+       autopick_new_entry(&entry, easy_autopick_inscription);
+       autopick_list[max_autopick++] = entry;
+}
+
+
+
+/*
+ *  Process line for auto picker/destroyer.
+ */
+errr process_pickpref_file_line(char *buf)
+{
+       autopick_type entry;
+       int i;
+
+       if (max_autopick == MAX_AUTOPICK)
+               return 1;
+       
+       /* Nuke illegal char */
+       for(i = 0; buf[i]; i++)
+       {
+#ifdef JP
+               if (iskanji(buf[i]))
+               {
+                       i++;
+                       continue;
+               }
+#endif
+               if (isspace(buf[i]) && buf[i] != ' ')
+                       break;
+       }
+       buf[i] = 0;
+       
+       if (!autopick_new_entry(&entry, buf)) return 0;
+
+       /* Already has the same entry? */ 
+       for(i = 0; i < max_autopick; i++)
+               if(!strcmp(entry.name, autopick_list[i].name)
+                  && entry.flag[0] == autopick_list[i].flag[0]
+                  && entry.flag[1] == autopick_list[i].flag[1]
+                  && entry.dice == autopick_list[i].dice
+                  && entry.bonus == autopick_list[i].bonus) return 0;
+
+       autopick_list[max_autopick++] = entry;
+       return 0;
+}
+
+
+/*
+ * Get a trigger key and insert ASCII string for the trigger
+ */
+static bool insert_macro_line(cptr *lines_list, int cy)
+{
+       char tmp[1024];
+       char buf[1024];
+       int i, n = 0;
+
+       /* Flush */
+       flush();
+
+       /* Do not process macros */
+       inkey_base = TRUE;
+
+       /* First key */
+       i = inkey();
+
+       /* Read the pattern */
+       while (i)
+       {
+               /* Save the key */
+               buf[n++] = i;
+
+               /* Do not process macros */
+               inkey_base = TRUE;
+
+               /* Do not wait for keys */
+               inkey_scan = TRUE;
+
+               /* Attempt to read a key */
+               i = inkey();
+       }
+
+       /* Terminate */
+       buf[n] = '\0';
+
+       /* Flush */
+       flush();
+
+       /* Convert the trigger */
+       ascii_to_text(tmp, buf);
+
+       /* Null */
+       if(!tmp[0]) return FALSE;
+
+       /* Insert preference string */
+       insert_return_code(lines_list, 0, cy);
+       string_free(lines_list[cy]);
+       lines_list[cy] = string_make(format("P:%s", tmp));
+
+       /* Insert blank action preference line */
+       insert_return_code(lines_list, 0, cy);
+       string_free(lines_list[cy]);
+       lines_list[cy] = string_make("A:");
+
+       return TRUE;
+}
+
+
+/*
+ * Get a command key and insert ASCII string for the key
+ */
+static bool insert_keymap_line(cptr *lines_list, int cy)
+{
+       char tmp[1024];
+       char buf[2];
+       int mode;
+
+       /* Roguelike */
+       if (rogue_like_commands)
+       {
+               mode = KEYMAP_MODE_ROGUE;
+       }
+
+       /* Original */
+       else
+       {
+               mode = KEYMAP_MODE_ORIG;
+       }
+
+       /* Flush */
+       flush();
+
+       /* Get a key */
+       buf[0] = inkey();
+       buf[1] = '\0';
+
+       /* Flush */
+       flush();
+
+       /* Convert the trigger */
+       ascii_to_text(tmp, buf);
+
+       /* Null */
+       if(!tmp[0]) return FALSE;
+
+       /* Insert preference string */
+       insert_return_code(lines_list, 0, cy);
+       string_free(lines_list[cy]);
+       lines_list[cy] = string_make(format("C:%d:%s", mode, tmp));
+
+       /* Insert blank action preference line */
+       insert_return_code(lines_list, 0, cy);
+       string_free(lines_list[cy]);
+       lines_list[cy] = string_make("A:");
 
-       /* There is always one entry "=g" */
-       autopick_new_entry(&entry, easy_autopick_inscription);
-       autopick_list[max_autopick++] = entry;
+       return TRUE;
 }
 
 
@@ -1863,20 +2579,20 @@ static cptr ctrl_command_desc[] =
        "^A ^E ¹Ô¤ÎÀèƬ¡¢½ªÃ¼",
        "^Q ÆþÎÏ/¥³¥Þ¥ó¥É¥â¡¼¥ÉÀÚ¤êÂؤ¨",
        "^R Êѹ¹¤òÁ´¤Æ¼è¤ê¾Ã¤·¤Æ¸µ¤ËÌ᤹",
-        "------------------------------------",
-        "^I »ý¤Áʪ/ÁõÈ÷¤«¤éÁªÂò",
+       "------------------------------------",
+       "^I »ý¤Áʪ/ÁõÈ÷¤«¤éÁªÂò",
        "^L",
        "^K ¥«¡¼¥½¥ë¤«¤é½ªÃ¼¤Þ¤Çºï½ü",
        "^Y ºï½ü(^K)¤·¤¿¹Ô¤òÁÞÆþ",
        "^C ¼ï²¡¢¿¦¶È¤Î¾ò·ï¼°¤òÁÞÆþ",
-        "------------------------------------",
+       "------------------------------------",
        "^S Êѹ¹ (!Ç˲õ/~ÊüÃÖ/½¦¤¦)",
        "^G \"(\" Á´ÂΥޥåפÇɽ¼¨¤·¤Ê¤¤",
        "^O \"#\" ¼«Æ°¹ï¤ß",
-        "------------------------------------",
+       "------------------------------------",
        "^U Ì¤´ÕÄê/̤ȽÌÀ/´ÕÄê/*´ÕÄê*",
        "^W \"̵²ÁÃͤÎ\"",
-       "^X \"̵ÌäÎ\"",
+       "^X ÌµÌÃ/¥¨¥´/¥¢¡¼¥Æ¥£¥Õ¥¡¥¯¥È",
        "^Z \"¼ý½¸Ãæ¤Î\"",
        NULL
 #else
@@ -1885,55 +2601,59 @@ static cptr ctrl_command_desc[] =
        "^A ^E Beginning and End of Line",
        "^Q Toggle Insert/Command mode",
        "^R Revert to Original File",
-        "------------------------------------",
-        "^I Object in Inventry/Equipment",
+       "------------------------------------",
+       "^I Object in Inventry/Equipment",
        "^L",
        "^K Kill Rest of Line",
        "^Y Insert killed(^K) text",
        "^C Insert conditional expression",
-        "------------------------------------",
+       "------------------------------------",
        "^S Toggle(!Destroy/~Leave/Pick)",
        "^G \"(\" No display in the 'M'ap",
        "^O \"#\" Auto-Inscribe",
-        "------------------------------------",
+       "------------------------------------",
        "^U Toggle 'identified' state",
        "^W \"worthless\"",
-       "^X \"nameless\"",
+       "^X Toggle nameless/ego/artifact",
        "^Z \"collecting\"",
        NULL
 #endif
 };
 
 
-#define MAX_YANK 1024
+#define MAX_YANK MAX_LINELEN
 #define DIRTY_ALL 0x01
 #define DIRTY_COMMAND 0x02
 #define DIRTY_MODE 0x04
-#define DIRTY_SCREEN 0x04
+#define DIRTY_SCREEN 0x08
+#define DIRTY_NOT_FOUND 0x10
+#define DIRTY_NO_SEARCH 0x20
 
 /*
  * In-game editor of Object Auto-picker/Destoryer
  */
-void do_cmd_edit_autopick()
+void do_cmd_edit_autopick(void)
 {
        static int cx = 0, cy = 0;
        static int upper = 0, left = 0;
 
-       cptr last_destroyed;
+       object_type *search_o_ptr = NULL;
+       cptr search_str = NULL;
+       cptr last_destroyed = NULL;
        char last_destroyed_command[WID_DESC+3];
        char yank_buf[MAX_YANK];
        char classrace[80];
        autopick_type an_entry, *entry = &an_entry;
-       char buf[1024];
+       char buf[MAX_LINELEN];
        cptr *lines_list;
+       int filename_mode = PT_WITH_PNAME;
 
        int i, j, k, len;
-       cptr tmp;
 
        int old_upper = -1, old_left = -1;
        int old_cy = -1;
        int key = -1, old_key;
-
+       bool repeated_clearing = FALSE;
        bool edit_mode = FALSE;
 
        byte dirty_flags = DIRTY_ALL | DIRTY_COMMAND | DIRTY_MODE;
@@ -1941,18 +2661,33 @@ void do_cmd_edit_autopick()
 
        int wid, hgt, old_wid = -1, old_hgt = -1;
 
+       static s32b old_autosave_turn = 0L;
+
+       if (turn < old_autosave_turn)
+       {
+               while (old_autosave_turn > turn) old_autosave_turn -= TURNS_PER_TICK * TOWN_DAWN;
+       }
+
+       /* Autosave */
+       if (turn > old_autosave_turn + 100L)
+       {
+               do_cmd_save_game(TRUE);
+               old_autosave_turn = turn;
+       }
+
+       /* HACK -- Reset start_time to stop counting playtime while edit */
+       update_playtime();
+
        /* Free old entries */
        init_autopicker();
 
-       /* Name of the Last Destroyed Item */
-       last_destroyed = autopick_line_from_entry(&autopick_entry_last_destroyed);
-
-       /* Command Description of the Last Destroyed Item */
-       if (last_destroyed)
+       /* Command Description of the 'Last Destroyed Item' */
+       if (autopick_last_destroyed_object.k_idx)
        {
-               strcpy(last_destroyed_command, "^L \"");
-               strncpy(last_destroyed_command + 4, last_destroyed, WID_DESC-4);
-               last_destroyed_command[WID_DESC+2] = '\0';
+               autopick_entry_from_object(entry, &autopick_last_destroyed_object);
+               last_destroyed = autopick_line_from_entry_kill(entry);
+
+               my_strcpy(last_destroyed_command, format("^L \"%s\"", last_destroyed), sizeof(last_destroyed_command));
        }
        else
        {
@@ -1977,7 +2712,7 @@ void do_cmd_edit_autopick()
        yank_buf[0] = '\0';
 
        /* Read or initialize whole text */
-       lines_list = read_pickpref_text_lines();
+       lines_list = read_pickpref_text_lines(&filename_mode);
 
        /* Reset cursor position if needed */
        for (i = 0; i < cy; i++)
@@ -2033,7 +2768,7 @@ void do_cmd_edit_autopick()
 
                if (dirty_flags & DIRTY_SCREEN)
                {
-                       dirty_flags = DIRTY_ALL | DIRTY_COMMAND | DIRTY_MODE;
+                       dirty_flags |= (DIRTY_ALL | DIRTY_COMMAND | DIRTY_MODE);
 
                        /* Clear screen */
                        Term_clear();
@@ -2114,30 +2849,46 @@ void do_cmd_edit_autopick()
                if (edit_mode)
                        prt("^Q ESC ¤Ç¥³¥Þ¥ó¥É¥â¡¼¥É¤Ø°Ü¹Ô¡¢Ä̾ï¤Îʸ»ú¤Ï¤½¤Î¤Þ¤ÞÆþÎÏ", 0, 0);
                else
-                       prt("q _ ¤Ç½ªÎ»¡¢hjkl2468 ¤Ç°ÜÆ°¡¢^Q a i ¤ÇÆþÎϥ⡼¥É", 0, 0);
+                       prt("q _ ¤Ç½ªÎ»¡¢hjkl2468 ¤Ç°ÜÆ°¡¢^Q a i ¤ÇÆþÎϥ⡼¥É¡¢/ n N ¤Ç¸¡º÷", 0, 0);
 #else  
                if (edit_mode)
                        prt("Press ^Q ESC to command mode, any letters to insert", 0, 0);
                else
-                       prt("Press q _ to quit, hjkl2468 to move, ^Q a i to insert mode", 0, 0);
+                       prt(format("Press q _ to quit, %s to move, ^Q a i to insert mode, /nN to find", rogue_like_commands ? "hjkl" : "2468"), 0, 0);
 #endif
                /* Display current position */
                prt (format("(%d,%d)", cx, cy), 0, 70);
 
                /* Display information when updated */
-               if (old_cy != cy || (dirty_flags & DIRTY_ALL) || dirty_line == cy)
+               if (old_cy != cy || (dirty_flags & (DIRTY_ALL | DIRTY_NOT_FOUND | DIRTY_NO_SEARCH)) || dirty_line == cy)
                {
                        /* Clear information line */
                        Term_erase(0, hgt - 3 + 1, wid);
                        Term_erase(0, hgt - 3 + 2, wid);
 
                        /* Display information */
-                       if (lines_list[cy][0] == '#')
+                       if (dirty_flags & DIRTY_NOT_FOUND)
+                       {
+#ifdef JP
+                               prt(format("¥Ñ¥¿¡¼¥ó¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó: %s", search_str), hgt - 3 + 1, 0);
+#else
+                               prt(format("Pattern not found: %s", search_str), hgt - 3 + 1, 0);
+#endif
+                       }
+                       else if (dirty_flags & DIRTY_NO_SEARCH)
+                       {
+#ifdef JP
+                               prt("¸¡º÷Ãæ¤Î¥Ñ¥¿¡¼¥ó¤¬¤¢¤ê¤Þ¤»¤ó('/'¤Ç¸¡º÷)¡£", hgt - 3 + 1, 0);
+#else
+                               prt("No pattern to search. (Press '/' to search.)", hgt - 3 + 1, 0);
+#endif
+                       }
+                       else if (lines_list[cy][0] == '#')
                        {
 #ifdef JP
                                prt("¤³¤Î¹Ô¤Ï¥³¥á¥ó¥È¤Ç¤¹¡£", hgt - 3 + 1, 0);
 #else
-                               prt("This line is comment.", hgt - 3 + 1, 0);
+                               prt("This line is comment.", hgt - 3 + 1, 0);
 #endif
                        }
                        else if (lines_list[cy][1] == ':')
@@ -2148,28 +2899,28 @@ void do_cmd_edit_autopick()
 #ifdef JP
                                        prt("¤³¤Î¹Ô¤Ï¾ò·ïʬ´ô¼°¤Ç¤¹¡£", hgt - 3 + 1, 0);
 #else
-                                       prt("This line is Conditional Expression.", hgt - 3 + 1, 0);
+                                       prt("This line is Conditional Expression.", hgt - 3 + 1, 0);
 #endif
                                        break;
                                case 'A':
 #ifdef JP
                                        prt("¤³¤Î¹Ô¤Ï¥Þ¥¯¥í¤Î¼Â¹ÔÆâÍƤòÄêµÁ¤·¤Þ¤¹¡£", hgt - 3 + 1, 0);
 #else
-                                       prt("This line defines Macro action.", hgt - 3 + 1, 0);
+                                       prt("This line defines Macro action.", hgt - 3 + 1, 0);
 #endif
                                        break;
                                case 'P':
 #ifdef JP
                                        prt("¤³¤Î¹Ô¤Ï¥Þ¥¯¥í¤Î¥È¥ê¥¬¡¼¡¦¥­¡¼¤òÄêµÁ¤·¤Þ¤¹¡£", hgt - 3 + 1, 0);
 #else
-                                       prt("This line defines Macro trigger key.", hgt - 3 + 1, 0);
+                                       prt("This line defines Macro trigger key.", hgt - 3 + 1, 0);
 #endif
                                        break;
                                case 'C':
 #ifdef JP
                                        prt("¤³¤Î¹Ô¤Ï¥­¡¼ÇÛÃÖ¤òÄêµÁ¤·¤Þ¤¹¡£", hgt - 3 + 1, 0);
 #else
-                                       prt("This line defines Keymap.", hgt - 3 + 1, 0);
+                                       prt("This line defines Keymap.", hgt - 3 + 1, 0);
 #endif
                                        break;
                                }
@@ -2178,12 +2929,12 @@ void do_cmd_edit_autopick()
                        /* Get description of an autopicker preference line */
                        else if (autopick_new_entry(entry, lines_list[cy]))
                        {
-                               char temp[80*4];
+                               char temp[1024];
                                cptr t;
 
                                describe_autopick(buf, entry);
 
-                               roff_to_buf(buf, 79, temp);
+                               roff_to_buf(buf, 81, temp, sizeof(temp));
                                t = temp;
                                for (i = 0; i< 2; i++)
                                {
@@ -2229,39 +2980,49 @@ void do_cmd_edit_autopick()
                                /* Mode line is now dirty */
                                dirty_flags |= DIRTY_MODE;
                        }
+
+                       /* Insert a character */
                        else if (!iscntrl(key&0xff))
                        {
-                               int next;
-
+                               /* Save preceding string */
                                for (i = j = 0; lines_list[cy][i] && i < cx; i++)
                                        buf[j++] = lines_list[cy][i];
 
+                               /* Add a character */
 #ifdef JP
-                                if (iskanji(key))
+                               if (iskanji(key))
                                {
-                                        inkey_base = TRUE;
-                                        next = inkey();
-                                        if (j+2 < 1024)
+                                       int next;
+
+                                       inkey_base = TRUE;
+                                       next = inkey();
+                                       if (j+2 < MAX_LINELEN)
                                        {
-                                                buf[j++] = key;
-                                                buf[j++] = next;
+                                               buf[j++] = key;
+                                               buf[j++] = next;
                                                cx += 2;
-                                        }
+                                       }
                                        else
-                                                bell();
-                                }
+                                               bell();
+                               }
                                else
 #endif
                                {
-                                        if (j+1 < 1024)
+                                       if (j+1 < MAX_LINELEN)
                                                buf[j++] = key;
                                        cx++;
                                }
-                               for (; lines_list[cy][i] && j + 1 < 1024; i++)
+
+                               /* Add following */
+                               for (; lines_list[cy][i] && j + 1 < MAX_LINELEN; i++)
                                        buf[j++] = lines_list[cy][i];
                                buf[j] = '\0';
+
+                               /* Replace current line with new line */
                                string_free(lines_list[cy]);
                                lines_list[cy] = string_make(buf);
+
+                               /* Move to correct collumn */
                                len = strlen(lines_list[cy]);
                                if (len < cx) cx = len;
 
@@ -2284,11 +3045,27 @@ void do_cmd_edit_autopick()
                                break;
                        case '~':
                                if (!autopick_new_entry(entry, lines_list[cy]))
+                               {
+                                       if (old_key != key) repeated_clearing = FALSE;
+
+                                       /* Next line */
+                                       if (lines_list[cy + 1]) cy++;
+                                       cx = 0;
                                        break;
+                               }
                                string_free(lines_list[cy]);
 
+                               if (old_key != key)
+                               {
+                                       if (entry->action & DONT_AUTOPICK)
+                                               repeated_clearing = TRUE;
+                                       else
+                                               repeated_clearing = FALSE;
+                               }
+
                                entry->action &= ~DO_AUTODESTROY;
-                               if (entry->action & DO_AUTOPICK)
+                               entry->action &= ~DO_QUERY_AUTOPICK;
+                               if (!repeated_clearing)
                                {
                                        entry->action &= ~DO_AUTOPICK;
                                        entry->action |= DONT_AUTOPICK;
@@ -2299,18 +3076,38 @@ void do_cmd_edit_autopick()
                                        entry->action |= DO_AUTOPICK;
                                }
 
-                               lines_list[cy] = autopick_line_from_entry(entry);
+                               lines_list[cy] = autopick_line_from_entry_kill(entry);
 
                                /* Now dirty */
                                dirty_line = cy;
+
+                               /* Next line */
+                               if (lines_list[cy + 1]) cy++;
+                               cx = 0;
                                break;
                        case '!':
                                if (!autopick_new_entry(entry, lines_list[cy]))
+                               {
+                                       if (old_key != key) repeated_clearing = FALSE;
+
+                                       /* Next line */
+                                       if (lines_list[cy + 1]) cy++;
+                                       cx = 0;
                                        break;
+                               }
                                string_free(lines_list[cy]);
 
+                               if (old_key != key)
+                               {
+                                       if (entry->action & DO_AUTODESTROY)
+                                               repeated_clearing = TRUE;
+                                       else
+                                               repeated_clearing = FALSE;
+                               }
+
                                entry->action &= ~DONT_AUTOPICK;
-                               if (entry->action & DO_AUTOPICK)
+                               entry->action &= ~DO_QUERY_AUTOPICK;
+                               if (!repeated_clearing)
                                {
                                        entry->action &= ~DO_AUTOPICK;
                                        entry->action |= DO_AUTODESTROY;
@@ -2321,13 +3118,91 @@ void do_cmd_edit_autopick()
                                        entry->action |= DO_AUTOPICK;
                                }
 
-                               lines_list[cy] = autopick_line_from_entry(entry);
+                               lines_list[cy] = autopick_line_from_entry_kill(entry);
+
+                               /* Now dirty */
+                               dirty_line = cy;
+
+                               /* Next line */
+                               if (lines_list[cy + 1]) cy++;
+                               cx = 0;
+                               break;
+                       case ';':
+                               if (!autopick_new_entry(entry, lines_list[cy]))
+                               {
+                                       if (old_key != key) repeated_clearing = FALSE;
+
+                                       /* Next line */
+                                       if (lines_list[cy + 1]) cy++;
+                                       cx = 0;
+                                       break;
+                               }
+                               string_free(lines_list[cy]);
+
+                               if (old_key != key)
+                               {
+                                       if (entry->action & DO_QUERY_AUTOPICK)
+                                               repeated_clearing = TRUE;
+                                       else
+                                               repeated_clearing = FALSE;
+                               }
+
+                               entry->action &= ~DO_AUTODESTROY;
+                               entry->action &= ~DONT_AUTOPICK;
+                               if (!repeated_clearing)
+                               {
+                                       entry->action &= ~DO_AUTOPICK;
+                                       entry->action |= DO_QUERY_AUTOPICK;
+                               }
+                               else 
+                               {
+                                       entry->action &= ~DO_QUERY_AUTOPICK;
+                                       entry->action |= DO_AUTOPICK;
+                               }
+
+                               lines_list[cy] = autopick_line_from_entry_kill(entry);
 
                                /* Now dirty */
                                dirty_line = cy;
+
+                               /* Next line */
+                               if (lines_list[cy + 1]) cy++;
+                               cx = 0;
                                break;
                        case '(':
-                               key = KTRL('g');
+                               /* Toggle display on the 'M'ap */
+                               if (!autopick_new_entry(entry, lines_list[cy]))
+                               {
+                                       if (old_key != key) repeated_clearing = FALSE;
+
+                                       /* Next line */
+                                       if (lines_list[cy + 1]) cy++;
+                                       cx = 0;
+                                       break;
+                               }
+                               string_free(lines_list[cy]);
+
+                               if (old_key != key)
+                               {
+                                       if (entry->action & DO_DISPLAY)
+                                               repeated_clearing = TRUE;
+                                       else
+                                               repeated_clearing = FALSE;
+                               }
+
+                               if (!repeated_clearing)
+                                       entry->action |= DO_DISPLAY;
+                               else
+                                       entry->action &= ~DO_DISPLAY;
+
+                               lines_list[cy] = autopick_line_from_entry_kill(entry);
+
+                               /* Now dirty */
+                               dirty_line = cy;
+
+                               /* Next line */
+                               if (lines_list[cy + 1]) cy++;
+                               cx = 0;
                                break;
                        case '#':
                        case '{':
@@ -2356,6 +3231,97 @@ void do_cmd_edit_autopick()
                                while (0 < upper && cy + 1 < upper + hgt - 4)
                                        upper--;
                                break;
+
+                       case 'g':
+                               cy = 0;
+                               break;
+
+                       case 'G':
+                               while (lines_list[cy + 1])
+                                       cy++;
+                               break;
+
+                       case 'm':
+                               /* Erase line */
+                               Term_erase(0, cy - upper + 1, wid - WID_DESC);
+
+                               /* Prompt */
+#ifdef JP
+                               Term_putstr(0, cy - upper + 1, wid - WID_DESC - 1, TERM_YELLOW, "P:<¥È¥ê¥¬¡¼¥­¡¼>: ");
+#else
+                               Term_putstr(0, cy - upper + 1, wid - WID_DESC - 1, TERM_YELLOW, "P:<Trigger key>: ");
+#endif
+                               if (insert_macro_line(lines_list, cy))
+                               {
+                                       /* Prepare to input action */
+                                       cx = 2;
+                                       edit_mode = TRUE;
+
+                                       /* Now dirty */
+                                       dirty_flags |= DIRTY_ALL;
+                                       dirty_flags |= DIRTY_MODE;
+                               }
+
+                               break;
+
+                       case 'c':
+                               /* Erase line */
+                               Term_erase(0, cy - upper + 1, wid - WID_DESC);
+
+                               /* Prompt */
+#ifdef JP
+                               Term_putstr(0, cy - upper + 1, wid - WID_DESC - 1, TERM_YELLOW, format("C:%d:<¥³¥Þ¥ó¥É¥­¡¼>: ", (rogue_like_commands ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG)));
+#else
+                               Term_putstr(0, cy - upper + 1, wid - WID_DESC - 1, TERM_YELLOW, format("C:%d:<Keypress>: ", (rogue_like_commands ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG)));
+#endif
+
+                               if (insert_keymap_line(lines_list, cy))
+                               {
+                                       /* Prepare to input action */
+                                       cx = 2;
+                                       edit_mode = TRUE;
+
+                                       /* Now dirty */
+                                       dirty_flags |= DIRTY_ALL;
+                                       dirty_flags |= DIRTY_MODE;
+                               }                               
+                               break;
+                       case '/':
+                               /* Become dirty because of item/equip menu */
+                               dirty_flags |= DIRTY_SCREEN;
+
+                               if (!get_string_for_search(&search_o_ptr, &search_str))
+                                       break;
+
+                               /* fall through */
+                       case 'n':
+                               if (search_o_ptr)
+                               {
+                                       if (!search_for_object(lines_list, search_o_ptr, &cx, &cy, TRUE)) dirty_flags |= DIRTY_NOT_FOUND;
+                               }
+                               else if (search_str)
+                               {
+                                       if (!search_for_string(lines_list, search_str, &cx, &cy, TRUE)) dirty_flags |= DIRTY_NOT_FOUND;
+                               }
+                               else
+                               {
+                                       dirty_flags |= DIRTY_NO_SEARCH;
+                               }
+                               break;
+                       case 'N':
+                               if (search_o_ptr)
+                               {
+                                       if (!search_for_object(lines_list, search_o_ptr, &cx, &cy, FALSE)) dirty_flags |= DIRTY_NOT_FOUND;
+                               }
+                               else if (search_str)
+                               {
+                                       if (!search_for_string(lines_list, search_str, &cx, &cy, FALSE)) dirty_flags |= DIRTY_NOT_FOUND;
+                               }
+                               else
+                               {
+                                       dirty_flags |= DIRTY_NO_SEARCH;
+                               }
+                               break;
                        }
                }
 
@@ -2382,9 +3348,11 @@ void do_cmd_edit_autopick()
                case KTRL('c'):
                        /* Insert a conditinal expression line */
                        insert_return_code(lines_list, 0, cy);
+                       string_free(lines_list[cy]);
                        lines_list[cy] = string_make(classrace);
                        cy++;
                        insert_return_code(lines_list, 0, cy);
+                       string_free(lines_list[cy]);
                        lines_list[cy] = string_make("?:1");
                        cx = 0;
 
@@ -2414,42 +3382,51 @@ void do_cmd_edit_autopick()
                        }
                        break;
                case KTRL('g'):
-                       /* Toggle display in the 'M'ap */
-                       if (lines_list[cy][0] != '(' && lines_list[cy][1] != '(')
-                               insert_string(lines_list, "(", 0, cy);
-                       else if (lines_list[cy][0] == '(')
-                               delete_string(lines_list, 1, 0, cy);
-                       else if (lines_list[cy][1] == '(')
-                               delete_string(lines_list, 1, 1, cy);
+                       /* Toggle display on the 'M'ap */
+                       if (!autopick_new_entry(entry, lines_list[cy]))
+                               break;
+                       string_free(lines_list[cy]);
+
+                       if (entry->action & DO_DISPLAY)
+                       {
+                               entry->action &= ~DO_DISPLAY;
+                               cx++;
+                       }
+                       else
+                       {
+                               entry->action |= DO_DISPLAY;
+                               if (cx > 0) cx--;
+                       }
+
+                       lines_list[cy] = autopick_line_from_entry_kill(entry);
 
                        /* Now dirty */
                        dirty_line = cy;
                        break;
                case KTRL('i'):
                        /* Insert choosen item name */
-                       if (!entry_from_object(entry))
+                       if (!entry_from_choosed_object(entry))
                        {
                                /* Now dirty because of item/equip menu */
                                dirty_flags |= DIRTY_SCREEN;
                                break;
                        }
-                       tmp = autopick_line_from_entry(entry);
-                       autopick_free_entry(entry);
-                       if (tmp)
-                       {
-                               insert_return_code(lines_list, 0, cy);
-                               lines_list[cy] = tmp;
-                               cx = 0;
 
-                               /* Now dirty because of item/equip menu */
-                               dirty_flags |= DIRTY_SCREEN;
-                       }
+                       insert_return_code(lines_list, 0, cy);
+                       string_free(lines_list[cy]);
+                       lines_list[cy] = autopick_line_from_entry_kill(entry);
+                       cx = 0;
+
+                       /* Now dirty because of item/equip menu */
+                       dirty_flags |= DIRTY_SCREEN;
+
                        break;
                case KTRL('l'):
                        /* Insert a name of last destroyed item */
                        if (last_destroyed)
                        {
                                insert_return_code(lines_list, 0, cy);
+                               string_free(lines_list[cy]);
                                lines_list[cy] = string_make(last_destroyed);
                                cx = 0;
 
@@ -2472,10 +3449,18 @@ void do_cmd_edit_autopick()
                        break;
                case KTRL('o'):
                        /* Prepare to write auto-inscription text */
-                       for (i = 0; lines_list[cy][i]; i++)
-                               if (lines_list[cy][i] == '#') break;
-                       if (!lines_list[cy][i]) insert_string(lines_list, "#", i, cy);
-                       cx = i + 1;
+                       if (!autopick_new_entry(entry, lines_list[cy]))
+                               break;
+                       string_free(lines_list[cy]);
+
+                       if (!entry->insc) entry->insc = string_make("");
+
+                       lines_list[cy] = autopick_line_from_entry_kill(entry);
+
+                       /* Move to collumn for auto inscription */
+                       for (cx = 0; lines_list[cy][cx]; cx++)
+                               if (lines_list[cy][cx] == '#') break;
+                       cx++;
                        edit_mode = TRUE;
 
                        /* Now dirty */
@@ -2498,12 +3483,12 @@ void do_cmd_edit_autopick()
 #ifdef JP
                        if (!get_check("Á´¤Æ¤ÎÊѹ¹¤òÇË´þ¤·¤Æ¸µ¤Î¾õÂÖ¤ËÌᤷ¤Þ¤¹¡£¤è¤í¤·¤¤¤Ç¤¹¤«¡© "))
 #else
-                       if (!get_check("Discard all change and revert to original file. Are you sure? "))
+                       if (!get_check("Discard all changes and revert to original file. Are you sure? "))
 #endif
                                break;
 
                        free_text_lines(lines_list);
-                       lines_list = read_pickpref_text_lines();
+                       lines_list = read_pickpref_text_lines(&filename_mode);
                        dirty_flags |= DIRTY_ALL | DIRTY_MODE;
                        cx = cy = 0;
                        edit_mode = FALSE;
@@ -2530,7 +3515,8 @@ void do_cmd_edit_autopick()
                                entry->action |= DO_AUTOPICK;
                        }
 
-                       lines_list[cy] = autopick_line_from_entry(entry);
+                       lines_list[cy] = autopick_line_from_entry_kill(entry);
+
                        /* Now dirty */
                        dirty_line = cy;
 
@@ -2580,7 +3566,7 @@ void do_cmd_edit_autopick()
                                REM_FLG(FLG_STAR_IDENTIFIED);
                        }
 
-                       lines_list[cy] = autopick_line_from_entry(entry);
+                       lines_list[cy] = autopick_line_from_entry_kill(entry);
 
                        /* Now dirty */
                        dirty_line = cy;
@@ -2598,20 +3584,79 @@ void do_cmd_edit_autopick()
                        dirty_line = cy;
                        break;
                case KTRL('x'):
-                       /* Toggle 'nameless' */
-                       toggle_string(lines_list, FLG_NAMELESS, cy);
+                       /* Rotate within nameless, ego, artifact */
+                       if (!autopick_new_entry(entry, lines_list[cy]))
+                               break;
+                       string_free(lines_list[cy]);
+
+                       if (IS_FLG(FLG_NAMELESS)) 
+                       {
+                               REM_FLG(FLG_NAMELESS);
+                               ADD_FLG(FLG_EGO);
+                               REM_FLG(FLG_ARTIFACT);
+                       }
+                       else if (IS_FLG(FLG_EGO)) 
+                       {
+                               REM_FLG(FLG_NAMELESS);
+                               REM_FLG(FLG_EGO);
+                               ADD_FLG(FLG_ARTIFACT);
+                       }
+                       else if (IS_FLG(FLG_ARTIFACT)) 
+                       {
+                               REM_FLG(FLG_NAMELESS);
+                               REM_FLG(FLG_EGO);
+                               REM_FLG(FLG_ARTIFACT);
+                       }
+                       else
+                       {
+                               ADD_FLG(FLG_NAMELESS);
+                               REM_FLG(FLG_EGO);
+                               REM_FLG(FLG_ARTIFACT);
+                       }
+
+                       lines_list[cy] = autopick_line_from_entry_kill(entry);
+
                        /* Now dirty */
                        dirty_line = cy;
                        break;
+
                case KTRL('y'):
                        /* Paste killed text */
                        if (strlen(yank_buf))
                        {
-                               cx = 0;
+                               bool ret = FALSE;
+
                                for (j = 0; yank_buf[j]; j += strlen(yank_buf + j) + 1)
                                {
-                                       insert_return_code(lines_list, 0, cy);
-                                       lines_list[cy] = string_make(yank_buf + j);
+                                       if (ret && '\n' == yank_buf[j])
+                                       {
+                                               ret = FALSE;
+                                               continue;
+                                       }
+
+                                       /* Split current line */
+                                       insert_return_code(lines_list, cx, cy);
+
+                                       /* Save preceding string */
+                                       for(i = 0; lines_list[cy][i]; i++)
+                                               buf[i] = lines_list[cy][i];
+
+                                       /* Paste yank buffer */
+                                       if ('\n' != yank_buf[j])
+                                       {
+                                               int k = j;
+                                               while (yank_buf[k] && i < MAX_LINELEN-1)
+                                                       buf[i++] = yank_buf[k++];
+                                               ret = TRUE;
+                                       }
+
+                                       buf[i] = '\0';
+
+                                       string_free(lines_list[cy]);
+                                       lines_list[cy] = string_make(buf);
+
+                                       /* Move to the beggining of next line */
+                                       cx = 0;
                                        cy++;
                                }
 
@@ -2628,36 +3673,55 @@ void do_cmd_edit_autopick()
 
                case KTRL('k'):
                        /* Kill rest of line */
-                       if (lines_list[cy][0] != '\0' && (unsigned int) cx < strlen(lines_list[cy]))
+                       if ((uint)cx > strlen(lines_list[cy]))
+                               cx = (int)strlen(lines_list[cy]);
+
+                       /* Save preceding string */
+                       for (i = 0; lines_list[cy][i] && i < cx; i++)
                        {
-                               for (i = j = 0; lines_list[cy][i] && i < cx; i++)
-                               {
 #ifdef JP
-                                       if (iskanji(lines_list[cy][i]))
-                                               buf[j++] = lines_list[cy][i++];
-#endif
-                                       buf[j++] = lines_list[cy][i];
+                               if (iskanji(lines_list[cy][i]))
+                               {
+                                       buf[i] = lines_list[cy][i];
+                                       i++;
                                }
-                               buf[j] = '\0';
+#endif
+                               buf[i] = lines_list[cy][i];
+                       }
+                       buf[i] = '\0';
 
-                               j = 0;
-                               if (old_key == KTRL('k'))
-                                       while (yank_buf[j])
-                                               j += strlen(yank_buf + j) + 1;
+                       j = 0;
+                       if (old_key == key)
+                               while (yank_buf[j])
+                                       j += strlen(yank_buf + j) + 1;
 
+                       /* Copy following to yank buffer */
+                       if (lines_list[cy][i])
+                       {
+                               while (lines_list[cy][i] && j < MAX_YANK - 2)
+                                       yank_buf[j++] = lines_list[cy][i++];
+                               i = TRUE;
+                       }
+                       else
+                       {
                                if (j < MAX_YANK - 2)
-                               {
-                                       strncpy(yank_buf + j, lines_list[cy] + i, MAX_YANK-j-2);
-                                       yank_buf[MAX_YANK-2] = '\0';
-                                       yank_buf[j + strlen(lines_list[cy] + i) + 1] = '\0';
-                               }
-                               string_free(lines_list[cy]);
-                               lines_list[cy] = string_make(buf);
+                                       yank_buf[j++] = '\n';
+                               i = FALSE;
+                       }
+                       yank_buf[j++] = '\0';
+                       yank_buf[j] = '\0';
+
+                       /* Replace current line with 'preceding string' */
+                       string_free(lines_list[cy]);
+                       lines_list[cy] = string_make(buf);
 
+                       if (i)
+                       {
                                /* Now dirty */
                                dirty_line = cy;
-                               break;                  
+                               break;
                        }
+
                        /* fall through */
                case KTRL('d'):
                case 0x7F:
@@ -2666,6 +3730,11 @@ void do_cmd_edit_autopick()
                        if (iskanji(lines_list[cy][cx])) cx++;
 #endif
                        cx++;
+
+                       /* fall through */
+
+               case '\010':
+                       /* BACK SPACE */
                        len = strlen(lines_list[cy]);
                        if (len < cx)
                        {
@@ -2681,10 +3750,6 @@ void do_cmd_edit_autopick()
                                }
                        }
 
-                       /* fall through */
-
-               case '\010':
-                       /* BACK SPACE */
                        if (cx == 0)
                        {
                                /* delete a return code and union two lines */
@@ -2705,7 +3770,7 @@ void do_cmd_edit_autopick()
                                break;
                        }
 
-                       for (i = j = 0; lines_list[cy][i] && i < cx; i++)
+                       for (i = j = k = 0; lines_list[cy][i] && i < cx; i++)
                        {
                                k = j;
 #ifdef JP
@@ -2735,11 +3800,25 @@ void do_cmd_edit_autopick()
        /* Restore the screen */
        screen_load();
 
+       switch (filename_mode)
+       {
+       case PT_DEFAULT:
 #ifdef JP
-       sprintf(buf, "picktype-%s.prf", player_name);
+               strcpy(buf, "picktype.prf");
 #else
-       sprintf(buf, "pickpref-%s.prf", player_name);
+               strcpy(buf, "pickpref.prf");
+#endif
+               break;
+
+       case PT_WITH_PNAME:
+#ifdef JP
+               sprintf(buf, "picktype-%s.prf", player_name);
+#else
+               sprintf(buf, "pickpref-%s.prf", player_name);
 #endif
+               break;
+       }
+
        write_text_lines(buf, lines_list);
        free_text_lines(lines_list);
 
@@ -2747,4 +3826,7 @@ void do_cmd_edit_autopick()
 
        /* Reload autopick pref */
        process_pickpref_file(buf);
+
+       /* HACK -- reset start_time so that playtime is not increase while edit */
+       start_time = time(NULL);
 }