OSDN Git Service

Add new option -- show_ammo_detail / show_ammo_no_crit
[hengband/hengband.git] / src / autopick.c
index 8c011e9..cedf34c 100644 (file)
@@ -210,7 +210,7 @@ static bool autopick_new_entry(autopick_type *entry, cptr str, bool allow_defaul
        cptr prev_ptr, ptr, old_ptr;
        int prev_flg;
 
-       if (str[1] == ':') switch (str[0])
+       if (str[0] && str[1] == ':') switch (str[0])
        {
        case '?': case '%':
        case 'A': case 'P': case 'C':
@@ -219,6 +219,7 @@ static bool autopick_new_entry(autopick_type *entry, cptr str, bool allow_defaul
 
        entry->flag[0] = entry->flag[1] = 0L;
        entry->dice = 0;
+       entry->bonus = 0;
 
        act = DO_AUTOPICK | DO_DISPLAY;
        while (TRUE)
@@ -520,7 +521,6 @@ static void autopick_entry_from_object(autopick_type *entry, object_type *o_ptr)
        {
                /* Ego objects */
                if (object_is_ego(o_ptr))
-                   
                {
                        if (object_is_weapon_armour_ammo(o_ptr))
                        {
@@ -541,11 +541,8 @@ static void autopick_entry_from_object(autopick_type *entry, object_type *o_ptr)
                                /* Don't use the object description */
                                name = FALSE;
 
-                               if (object_is_weapon_armour_ammo(o_ptr))
-                               {
-                                       /* Restrict to 'common' equipments */
-                                       if (!object_is_rare(o_ptr)) ADD_FLG(FLG_COMMON);
-                               }
+                               /* Restrict to 'common' equipments */
+                               if (!object_is_rare(o_ptr)) ADD_FLG(FLG_COMMON);
                        }
 
                        ADD_FLG(FLG_EGO);
@@ -692,6 +689,8 @@ static void autopick_free_entry(autopick_type *entry)
 {
        string_free(entry->name);
        string_free(entry->insc);
+       entry->name = NULL;
+       entry->insc = NULL;
 }
 
 
@@ -745,7 +744,7 @@ static cptr pickpref_filename(int filename_mode)
                return format("%s.prf", namebase);
 
        case PT_WITH_PNAME:
-               return format("%s-%s.prf", namebase, player_name);
+               return format("%s-%s.prf", namebase, player_base);
 
        default:
                return NULL;
@@ -830,10 +829,10 @@ static void add_autopick_list(autopick_type *entry)
                C_MAKE(autopick_list, max_max_autopick, autopick_type);
 
                /* Copy from old list to new list */
-               C_COPY(autopick_list, old_autopick_list, old_max_max_autopick, autopick_type);
+               (void)C_COPY(autopick_list, old_autopick_list, old_max_max_autopick, autopick_type);
 
                /* Kill old list */
-               C_FREE(old_autopick_list, old_max_max_autopick, autopick_type);
+               C_KILL(old_autopick_list, old_max_max_autopick, autopick_type);
        }
 
        /* Add one line */
@@ -874,7 +873,11 @@ errr process_autopick_file_command(char *buf)
                   && 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;
+                  && entry->bonus == autopick_list[i].bonus)
+               {
+                       autopick_free_entry(entry);
+                       return 0;
+               }
 
        add_autopick_list(entry);
        return 0;
@@ -1058,6 +1061,12 @@ static bool is_autopick_aux(object_type *o_ptr, autopick_type *entry, cptr o_nam
                /* Require boosted dice */
                if ((o_ptr->dd == k_ptr->dd) && (o_ptr->ds == k_ptr->ds))
                        return FALSE;
+               
+               /* In Vault Quest, Dice must be hide.*/
+               if(!object_is_known(o_ptr) && object_is_quest_target(o_ptr))
+               {
+                       return FALSE;
+               }
        }
 
        /*** Weapons which dd*ds is more than nn ***/
@@ -1232,11 +1241,11 @@ static bool is_autopick_aux(object_type *o_ptr, autopick_type *entry, cptr o_nam
                }
        }
 
-       /*** Rere equpiments ***/
+       /*** Rere equipments ***/
        if (IS_FLG(FLG_RARE) && !object_is_rare(o_ptr))
                return FALSE;
 
-       /*** Common equpiments ***/
+       /*** Common equipments ***/
        if (IS_FLG(FLG_COMMON) && object_is_rare(o_ptr))
                return FALSE;
 
@@ -1494,21 +1503,21 @@ static bool is_opt_confirm_destroy(object_type *o_ptr)
        /* Known to be worthless? */
        if (leave_worth)
                if (object_value(o_ptr) > 0) return FALSE;
-       
+
        if (leave_equip)
-               if (!object_is_weapon_armour_ammo(o_ptr)) return FALSE;
-       
+               if (object_is_weapon_armour_ammo(o_ptr)) return FALSE;
+
        if (leave_chest)
                if ((o_ptr->tval == TV_CHEST) && o_ptr->pval) return FALSE;
-       
+
        if (leave_wanted)
        {
                if (object_is_shoukinkubi(o_ptr)) return FALSE;
        }
-       
+
        if (leave_corpse)
                if (o_ptr->tval == TV_CORPSE) return FALSE;
-       
+
        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;
 
@@ -1531,20 +1540,20 @@ static bool is_opt_confirm_destroy(object_type *o_ptr)
                else if (p_ptr->pclass == CLASS_NINJA)
                {
                        if (o_ptr->tval == TV_LITE &&
-                           o_ptr->name2 == EGO_LITE_DARKNESS)
+                           o_ptr->name2 == EGO_LITE_DARKNESS && object_is_known(o_ptr))
                                return FALSE;
                }
                else if (p_ptr->pclass == CLASS_BEASTMASTER ||
                         p_ptr->pclass == CLASS_CAVALRY)
                {
                        if (o_ptr->tval == TV_WAND &&
-                           o_ptr->sval == SV_WAND_HEAL_MONSTER)
+                           o_ptr->sval == SV_WAND_HEAL_MONSTER && object_is_aware(o_ptr))
                                return FALSE;
                }
        }
-       
+
        if (o_ptr->tval == TV_GOLD) return FALSE;
-       
+
        return TRUE;
 }
 
@@ -1605,7 +1614,7 @@ static void auto_destroy_item(object_type *o_ptr, int autopick_idx)
        }
 
        /* Record name of destroyed item */
-       COPY(&autopick_last_destroyed_object, o_ptr, object_type);
+       (void)COPY(&autopick_last_destroyed_object, o_ptr, object_type);
 
        /* Destroy Later */
        o_ptr->marked |= OM_AUTODESTROY;
@@ -1628,7 +1637,7 @@ static void autopick_delayed_alter_aux(int item)
        /* Get the item (on the floor) */
        else o_ptr = &o_list[0 - item];
 
-       if (o_ptr->k_idx && o_ptr->marked & OM_AUTODESTROY)
+       if (o_ptr->k_idx && (o_ptr->marked & OM_AUTODESTROY))
        {
                char o_name[MAX_NLEN];
 
@@ -2262,14 +2271,14 @@ static void describe_autopick(char *buff, autopick_type *entry)
                body_str = "ÁõÈ÷";
        }
 
-       /*** Rare equpiments ***/
+       /*** Rare equipments ***/
        if (IS_FLG(FLG_RARE))
        {
                before_str[before_n++] = "¥É¥é¥´¥óÁõÈ÷¤ä¥«¥ª¥¹¡¦¥Ö¥ì¡¼¥ÉÅù¤ò´Þ¤àÄÁ¤·¤¤";
                body_str = "ÁõÈ÷";
        }
 
-       /*** Common equpiments ***/
+       /*** Common equipments ***/
        if (IS_FLG(FLG_COMMON))
        {
                before_str[before_n++] = "¤¢¤ê¤Õ¤ì¤¿(¥É¥é¥´¥óÁõÈ÷¤ä¥«¥ª¥¹¡¦¥Ö¥ì¡¼¥ÉÅù¤ÎÄÁ¤·¤¤Êª¤Ç¤Ï¤Ê¤¤)";
@@ -2482,7 +2491,7 @@ static void describe_autopick(char *buff, autopick_type *entry)
        if (IS_FLG(FLG_STAR_IDENTIFIED))
                before_str[before_n++] = "fully identified";
 
-       /*** Rare equpiments ***/
+       /*** Rare equipments ***/
        if (IS_FLG(FLG_RARE))
        {
                before_str[before_n++] = "very rare";
@@ -2490,7 +2499,7 @@ static void describe_autopick(char *buff, autopick_type *entry)
                after_str[after_n++] = "such like Dragon armors, Blades of Chaos, etc.";
        }
 
-       /*** Common equpiments ***/
+       /*** Common equipments ***/
        if (IS_FLG(FLG_COMMON))
        {
                before_str[before_n++] = "relatively common";
@@ -2980,7 +2989,7 @@ static void free_text_lines(cptr *lines_list)
                string_free(lines_list[lines]);
 
        /* free list of pointers */
-       C_FREE((char **)lines_list, MAX_LINES, char *);
+       C_KILL(lines_list, MAX_LINES, cptr);
 }
 
 
@@ -3234,6 +3243,36 @@ static void check_expression_line(text_body_type *tb, int y)
 
 
 /*
+ * Add an empty line at the last of the file
+ */
+static bool add_empty_line(text_body_type *tb)
+{
+       int k;
+
+       for (k = 0; tb->lines_list[k]; k++)
+               /* count number of lines */ ;
+
+       /* Too many lines! */
+       if (k >= MAX_LINES - 2) return FALSE;
+
+       /* The last line is already empty */
+       if (!tb->lines_list[k-1][0]) return FALSE;
+
+       /* Create new empty line */
+       tb->lines_list[k] = string_make("");
+
+       /* Expressions need re-evaluation */
+       tb->dirty_flags |= DIRTY_EXPRESSION;
+
+       /* Text is changed */
+       tb->changed = TRUE;
+
+       /* A line is added */
+       return TRUE;
+}
+
+
+/*
  * Insert return code and split the line
  */
 static bool insert_return_code(text_body_type *tb)
@@ -3681,6 +3720,8 @@ static void search_for_object(text_body_type *tb, object_type *o_ptr, bool forwa
 
        while (TRUE)
        {
+               bool match;
+
                /* End of list? */
                if (forward)
                {
@@ -3695,8 +3736,9 @@ static void search_for_object(text_body_type *tb, object_type *o_ptr, bool forwa
                if (!autopick_new_entry(entry, tb->lines_list[i], FALSE)) continue;
 
                /* Does this line match to the object? */
-               if (!is_autopick_aux(o_ptr, entry, o_name)) continue;
-
+               match = is_autopick_aux(o_ptr, entry, o_name);
+               autopick_free_entry(entry);
+               if (!match)     continue;
 
                /* Found a line but it's inactive */
                if (tb->states[i] & LSTAT_BYPASS)
@@ -4398,6 +4440,91 @@ static void add_str_to_yank(text_body_type *tb, cptr str)
 }
 
 
+/*
+ * Do work for the copy editor-command
+ */
+static void copy_text_to_yank(text_body_type *tb)
+{
+       int len = strlen(tb->lines_list[tb->cy]);
+
+       /* Correct cursor location */
+       if (tb->cx > len) tb->cx = len;
+
+       /* Use single line? */
+       if (!tb->mark)
+       {
+               /* Select a single line */
+               tb->cx = 0;
+               tb->my = tb->cy;
+               tb->mx = len;
+       }
+
+       /* Kill old yank buffer */
+       kill_yank_chain(tb);
+
+
+       /* Single line case */
+       if (tb->my == tb->cy)
+       {
+               int i;
+               char buf[MAX_LINELEN];
+               int bx1 = MIN(tb->mx, tb->cx);
+               int bx2 = MAX(tb->mx, tb->cx);
+
+               /* Correct fake cursor position */
+               if (bx2 > len) bx2 = len;
+
+               /* Whole part of this line is selected */
+               if (bx1 == 0 && bx2 == len)
+               {
+                       /* Copy this line */
+                       add_str_to_yank(tb, tb->lines_list[tb->cy]);
+
+                       /* Add end of line to the buffer */
+                       add_str_to_yank(tb, "");
+               }
+
+               /* Segment of this line is selected */
+               else
+               {
+                       for (i = 0; i < bx2 - bx1; i++)
+                       {
+                               buf[i] = tb->lines_list[tb->cy][bx1 + i];
+                       }
+                       buf[i] = '\0';
+
+                       /* Copy this segment of line */
+                       add_str_to_yank(tb, buf);
+               }
+       }
+
+       /* Multiple lines case */
+       else /* if (tb->my != tb->cy) */
+       {
+               int y;
+
+               int by1 = MIN(tb->my, tb->cy);
+               int by2 = MAX(tb->my, tb->cy);
+
+               /* Copy lines */
+               for (y = by1; y <= by2; y++)
+               {
+                       /* Copy this line */
+                       add_str_to_yank(tb, tb->lines_list[y]);
+               }
+
+               /* Add final end of line to the buffer */
+               add_str_to_yank(tb, "");
+       }
+
+       /* Disable selection */
+       tb->mark = 0;
+
+       /* Now dirty */
+       tb->dirty_flags |= DIRTY_ALL;
+}
+
+
 #define DESCRIPT_HGT 3
 
 /*
@@ -4425,7 +4552,12 @@ static void draw_text_editor(text_body_type *tb)
                        i++;
                        if (i == tb->cx)
                        {
-                               tb->cx--;
+                               /*
+                                * Move to a correct position in the
+                                * left or right
+                                */
+                               if (i & 1) tb->cx--;
+                               else tb->cx++;
                                break;
                        }
                }
@@ -4483,6 +4615,8 @@ static void draw_text_editor(text_body_type *tb)
                        char f;
                        cptr v;
                        cptr s = tb->lines_list[y];
+                       char *ss, *s_keep;
+                       int s_len;
 
                        /* Update this line's state */
                        tb->states[y] = state;
@@ -4494,13 +4628,20 @@ static void draw_text_editor(text_body_type *tb)
                        if (streq(s, "$AUTOREGISTER"))
                                state |= LSTAT_AUTOREGISTER;
 
+                       s_len = strlen(s);
+                       ss = (char *)string_make(s);
+                       s_keep = ss;
+
                        /* Parse the expr */
-                       v = process_pref_file_expr(&s, &f);
+                       v = process_pref_file_expr(&ss, &f);
 
                        /* Set flag */
                        if (streq(v, "0")) state |= LSTAT_BYPASS;
                        else state &= ~LSTAT_BYPASS;
 
+                       /* Cannot use string_free() because the string was "destroyed" */
+                       C_KILL(s_keep, s_len + 1, char);
+
                        /* Re-update this line's state */
                        tb->states[y] = state | LSTAT_EXPRESSION;
                }
@@ -4658,7 +4799,7 @@ static void draw_text_editor(text_body_type *tb)
                        str1 = "This line is a comment.";
 #endif
                }
-               else if (tb->lines_list[tb->cy][1] == ':')
+               else if (tb->lines_list[tb->cy][0] && tb->lines_list[tb->cy][1] == ':')
                {
                        switch(tb->lines_list[tb->cy][0])
                        {
@@ -4964,8 +5105,17 @@ static bool insert_keymap_line(text_body_type *tb)
        /* Look up the keymap */
        act = keymap_act[mode][(byte)(buf[0])];
 
-       /* Analyze the current action */
-       ascii_to_text(tmp, act);
+       if (act)
+       {
+               /* Analyze the current action */
+               ascii_to_text(tmp, act);
+       }
+       else
+       {
+               /* No keymap defined -- Use trigger key itself as a default */
+
+               /* Nothing to do (use tmp) */
+       }
 
        /* Insert blank action preference line */
        insert_return_code(tb);
@@ -5052,10 +5202,30 @@ static bool do_editor_command(text_body_type *tb, int com_id)
                if (0 < tb->cx)
                {
                        int len;
+#ifdef JP
+                       int i;
+#endif
 
                        tb->cx--;
                        len = strlen(tb->lines_list[tb->cy]);
                        if (len < tb->cx) tb->cx = len;
+
+#ifdef JP
+                       /* Don't let cursor at second byte of kanji */
+                       for (i = 0; tb->lines_list[tb->cy][i]; i++)
+                       {
+                               if (iskanji(tb->lines_list[tb->cy][i]))
+                               {
+                                       i++;
+                                       if (i == tb->cx)
+                                       {
+                                               /* Move to the left */
+                                               tb->cx--;
+                                               break;
+                                       }
+                               }
+                       }
+#endif
                }
                else if (tb->cy > 0)
                {
@@ -5066,7 +5236,17 @@ static bool do_editor_command(text_body_type *tb, int com_id)
 
        case EC_DOWN:
                /* Next line */
-               if (tb->lines_list[tb->cy + 1]) tb->cy++;
+
+               /* Is this the last line? */
+               if (!tb->lines_list[tb->cy + 1])
+               {
+                       /* Add one more empty line if possible */
+                       if (!add_empty_line(tb)) break;
+               }
+
+               /* Go down */
+               tb->cy++;
+
                break;
 
        case EC_UP:
@@ -5086,13 +5266,19 @@ static bool do_editor_command(text_body_type *tb, int com_id)
                len = strlen(tb->lines_list[tb->cy]);
                if (len < tb->cx)
                {
-                       if (tb->lines_list[tb->cy + 1])
+                       /* Correct the cursor position */
+                       tb->cx = len;
+
+                       /* Is this the last line? */
+                       if (!tb->lines_list[tb->cy + 1])
                        {
-                               tb->cy++;
-                               tb->cx = 0;
+                               /* Add one more empty line if possible */
+                               if (!add_empty_line(tb)) break;
                        }
-                       else
-                               tb->cx = len;
+
+                       /* Move to the beginning of next line */
+                       tb->cy++;
+                       tb->cx = 0;
                }
                break;
        }
@@ -5116,8 +5302,18 @@ static bool do_editor_command(text_body_type *tb, int com_id)
 
        case EC_PGDOWN:
                /* Page down */
-               while (tb->cy < tb->upper + tb->hgt && tb->lines_list[tb->cy + 1])
+               while (tb->cy < tb->upper + tb->hgt)
+               {
+                       /* Is this the last line? */
+                       if (!tb->lines_list[tb->cy + 1])
+                       {
+                               /* Add one more empty line if possible */
+                               if (!add_empty_line(tb)) break;
+                       }
+
                        tb->cy++;
+               }
+
                tb->upper = tb->cy;
                break;
 
@@ -5126,14 +5322,27 @@ static bool do_editor_command(text_body_type *tb, int com_id)
                break;
 
        case EC_BOTTOM:
-               while (tb->lines_list[tb->cy + 1])
+               while (TRUE)
+               {
+                       /* Is this the last line? */
+                       if (!tb->lines_list[tb->cy + 1])
+                       {
+                               /* Add one more empty line if possible */
+                               if (!add_empty_line(tb)) break;
+                       }
+
                        tb->cy++;
+               }
+
+               /* Always at the biginning of the last line */
+               tb->cx = 0;
+
                break;
 
        case EC_CUT:
        {       
                /* Copy the text first */
-               do_editor_command(tb, EC_COPY);
+               copy_text_to_yank(tb);
 
                /* Single line case */
                if (tb->my == tb->cy)
@@ -5186,86 +5395,51 @@ static bool do_editor_command(text_body_type *tb, int com_id)
        }
 
        case EC_COPY:
-       {       
-               int len = strlen(tb->lines_list[tb->cy]);
-
-               /* Correct cursor location */
-               if (tb->cx > len) tb->cx = len;
-
-               /* Use single line? */
-               if (!tb->mark)
-               {
-                       /* Select a single line */
-                       tb->cx = 0;
-                       tb->my = tb->cy;
-                       tb->mx = len;
-               }
-
-               /* Kill old yank buffer */
-               kill_yank_chain(tb);
-
+               copy_text_to_yank(tb);
 
-               /* Single line case */
+               /*
+                * Move cursor position to the end of the selection
+                *
+                * Pressing ^C ^V correctly duplicates the selection.
+                */
                if (tb->my == tb->cy)
                {
-                       int i;
-                       char buf[MAX_LINELEN];
-                       int bx1 = MIN(tb->mx, tb->cx);
-                       int bx2 = MAX(tb->mx, tb->cx);
-
-                       /* Correct fake cursor position */
-                       if (bx2 > len) bx2 = len;
-
-                       /* Whole part of this line is selected */
-                       if (bx1 == 0 && bx2 == len)
-                       {
-                               /* Copy this line */
-                               add_str_to_yank(tb, tb->lines_list[tb->cy]);
+                       tb->cx = MAX(tb->cx, tb->mx);
 
-                               /* Add end of line to the buffer */
-                               add_str_to_yank(tb, "");
-                       }
-
-                       /* Segment of this line is selected */
-                       else
+                       /*
+                        * When whole line is selected, the end of
+                        * line code is also copyed.
+                        */
+                       if (!tb->lines_list[tb->cy][tb->cx])
                        {
-                               for (i = 0; i < bx2 - bx1; i++)
+                               /* Is this the last line? */
+                               if (!tb->lines_list[tb->cy + 1])
                                {
-                                       buf[i] = tb->lines_list[tb->cy][bx1 + i];
+                                       /* Add one more empty line if possible */
+                                       if (!add_empty_line(tb)) break;
                                }
-                               buf[i] = '\0';
 
-                               /* Copy this segment of line */
-                               add_str_to_yank(tb, buf);
+                               /* Go to the beginning of next line */
+                               tb->cy++;
+                               tb->cx = 0;
                        }
                }
-
-               /* Multiple lines case */
-               else /* if (tb->my != tb->cy) */
+               else
                {
-                       int y;
-
-                       int by1 = MIN(tb->my, tb->cy);
-                       int by2 = MAX(tb->my, tb->cy);
+                       tb->cy = MAX(tb->cy, tb->my);
 
-                       /* Copy lines */
-                       for (y = by1; y <= by2; y++)
+                       /* Is this the last line? */
+                       if (!tb->lines_list[tb->cy + 1])
                        {
-                               /* Copy this line */
-                               add_str_to_yank(tb, tb->lines_list[y]);
+                               /* Add one more empty line if possible */
+                               if (!add_empty_line(tb)) break;
                        }
 
-                       /* Add final end of line to the buffer */
-                       add_str_to_yank(tb, "");
+                       /* Go down */
+                       tb->cy++;
                }
 
-               /* Disable selection */
-               tb->mark = 0;
-
-               /* Now dirty */
-               tb->dirty_flags |= DIRTY_ALL;
                break;
-       }
 
        case EC_PASTE:
        {
@@ -6025,6 +6199,11 @@ void do_cmd_edit_autopick(void)
        tb->dirty_line = -1;
        tb->filename_mode = PT_DEFAULT;
 
+       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)
        {
@@ -6157,6 +6336,7 @@ void do_cmd_edit_autopick(void)
 
        free_text_lines(tb->lines_list);
 
+       string_free(tb->search_str);
        string_free(tb->last_destroyed);
 
        /* Destroy string chain */