3 * @brief 自動拾い機能の実装 / Object Auto-picker/Destroyer
6 * Copyright (c) 2002 Mogami\n
8 * This software may be copied and distributed for educational, research, and\n
9 * not for profit purposes provided that this copyright and statement are\n
10 * included in all such copies.\n
11 * 2014 Deskull rearranged comment for Doxygen.\n
16 #include "autopick/autopick-commands-table.h"
17 #include "autopick/autopick-dirty-flags.h"
18 #include "autopick/autopick-flags-table.h"
19 #include "autopick/autopick-initializer.h"
20 #include "autopick/autopick-key-flag-process.h"
21 #include "autopick/autopick-menu-data-table.h"
22 #include "autopick/autopick-methods-table.h"
23 #include "autopick/autopick-destroyer.h"
24 #include "autopick/autopick-entry.h"
25 #include "autopick/autopick-reader-writer.h"
26 #include "autopick/autopick-finder.h"
27 #include "autopick/autopick-drawer.h"
28 #include "autopick/autopick-searcher.h"
29 #include "autopick/autopick-inserter-killer.h"
30 #include "autopick/autopick-registry.h"
32 #include "autopick/autopick.h"
33 #include "core/show-file.h"
34 #include "cmd/cmd-save.h"
35 #include "io/read-pref-file.h"
39 #include "market/store.h"
40 #include "player-move.h"
41 #include "player-class.h"
42 #include "view/display-player.h" // 暫定。後で消す.
43 #include "object-flavor.h"
46 #include "view/display-main-window.h" // 暫定。後で消す.
49 * Auto-destroy marked item
51 static void autopick_delayed_alter_aux(player_type *player_ptr, INVENTORY_IDX item)
54 o_ptr = REF_ITEM(player_ptr, player_ptr->current_floor_ptr, item);
56 if (o_ptr->k_idx == 0 || !(o_ptr->marked & OM_AUTODESTROY)) return;
58 GAME_TEXT o_name[MAX_NLEN];
59 object_desc(player_ptr, o_name, o_ptr, 0);
62 inven_item_increase(player_ptr, item, -(o_ptr->number));
63 inven_item_optimize(player_ptr, item);
67 delete_object_idx(player_ptr, 0 - item);
70 msg_format(_("%sを自動破壊します。", "Auto-destroying %s."), o_name);
75 * Auto-destroy marked items in inventry and on floor
77 void autopick_delayed_alter(player_type *owner_ptr)
82 * Scan inventry in reverse order to prevent
83 * skipping after inven_item_optimize()
85 for (item = INVEN_TOTAL - 1; item >= 0; item--)
86 autopick_delayed_alter_aux(owner_ptr, item);
88 floor_type *floor_ptr = owner_ptr->current_floor_ptr;
89 item = floor_ptr->grid_array[owner_ptr->y][owner_ptr->x].o_idx;
92 OBJECT_IDX next = floor_ptr->o_list[item].next_o_idx;
93 autopick_delayed_alter_aux(owner_ptr, -item);
100 * Auto-inscription and/or destroy
102 * Auto-destroyer works only on inventory or on floor stack only when
105 void autopick_alter_item(player_type *player_ptr, INVENTORY_IDX item, bool destroy)
108 o_ptr = REF_ITEM(player_ptr, player_ptr->current_floor_ptr, item);
109 int idx = find_autopick_list(player_ptr, o_ptr);
110 auto_inscribe_item(player_ptr, o_ptr, idx);
111 if (destroy && item <= INVEN_PACK)
112 auto_destroy_item(player_ptr, o_ptr, idx);
117 * Automatically pickup/destroy items in this grid.
119 void autopick_pickup_items(player_type* player_ptr, grid_type *g_ptr)
121 OBJECT_IDX this_o_idx, next_o_idx = 0;
122 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
124 object_type *o_ptr = &player_ptr->current_floor_ptr->o_list[this_o_idx];
125 next_o_idx = o_ptr->next_o_idx;
126 int idx = find_autopick_list(player_ptr, o_ptr);
127 auto_inscribe_item(player_ptr, o_ptr, idx);
128 bool is_auto_pickup = idx >= 0;
129 is_auto_pickup &= (autopick_list[idx].action & (DO_AUTOPICK | DO_QUERY_AUTOPICK)) != 0;
132 auto_destroy_item(player_ptr, o_ptr, idx);
136 disturb(player_ptr, FALSE, FALSE);
137 if (!inven_carry_okay(o_ptr))
139 GAME_TEXT o_name[MAX_NLEN];
140 object_desc(player_ptr, o_name, o_ptr, 0);
141 msg_format(_("ザックには%sを入れる隙間がない。", "You have no room for %s."), o_name);
142 o_ptr->marked |= OM_NOMSG;
146 if (!(autopick_list[idx].action & DO_QUERY_AUTOPICK))
148 py_pickup_aux(player_ptr, this_o_idx);
152 char out_val[MAX_NLEN + 20];
153 GAME_TEXT o_name[MAX_NLEN];
154 if (o_ptr->marked & OM_NO_QUERY)
159 object_desc(player_ptr, o_name, o_ptr, 0);
160 sprintf(out_val, _("%sを拾いますか? ", "Pick up %s? "), o_name);
161 if (!get_check(out_val))
163 o_ptr->marked |= OM_NOMSG | OM_NO_QUERY;
167 py_pickup_aux(player_ptr, this_o_idx);
173 * Delete or insert string
175 static void toggle_keyword(text_body_type *tb, BIT_FLAGS flg)
182 by1 = MIN(tb->my, tb->cy);
183 by2 = MAX(tb->my, tb->cy);
185 else /* if (!tb->mark) */
190 for (int y = by1; y <= by2; y++)
192 autopick_type an_entry, *entry = &an_entry;
193 if (!autopick_new_entry(entry, tb->lines_list[y], !fixed)) continue;
195 string_free(tb->lines_list[y]);
198 if (!IS_FLG(flg)) add = TRUE;
204 if (FLG_NOUN_BEGIN <= flg && flg <= FLG_NOUN_END)
207 for (i = FLG_NOUN_BEGIN; i <= FLG_NOUN_END; i++)
210 else if (FLG_UNAWARE <= flg && flg <= FLG_STAR_IDENTIFIED)
213 for (i = FLG_UNAWARE; i <= FLG_STAR_IDENTIFIED; i++)
216 else if (FLG_ARTIFACT <= flg && flg <= FLG_AVERAGE)
219 for (i = FLG_ARTIFACT; i <= FLG_AVERAGE; i++)
222 else if (FLG_RARE <= flg && flg <= FLG_COMMON)
225 for (i = FLG_RARE; i <= FLG_COMMON; i++)
229 if (add) ADD_FLG(flg);
232 tb->lines_list[y] = autopick_line_from_entry_kill(entry);
233 tb->dirty_flags |= DIRTY_ALL;
240 * Change command letter
242 static void toggle_command_letter(text_body_type *tb, byte flg)
244 autopick_type an_entry;
245 autopick_type *entry = &an_entry;
251 by1 = MIN(tb->my, tb->cy);
252 by2 = MAX(tb->my, tb->cy);
254 else /* if (!tb->mark) */
259 for (int y = by1; y <= by2; y++)
263 if (!autopick_new_entry(entry, tb->lines_list[y], FALSE)) continue;
265 string_free(tb->lines_list[y]);
269 if (!(entry->action & flg)) add = TRUE;
275 if (entry->action & DONT_AUTOPICK) wid--;
276 else if (entry->action & DO_AUTODESTROY) wid--;
277 else if (entry->action & DO_QUERY_AUTOPICK) wid--;
278 if (!(entry->action & DO_DISPLAY)) wid--;
280 if (flg != DO_DISPLAY)
282 entry->action &= ~(DO_AUTOPICK | DONT_AUTOPICK | DO_AUTODESTROY | DO_QUERY_AUTOPICK);
283 if (add) entry->action |= flg;
284 else entry->action |= DO_AUTOPICK;
288 entry->action &= ~(DO_DISPLAY);
289 if (add) entry->action |= flg;
294 if (entry->action & DONT_AUTOPICK) wid++;
295 else if (entry->action & DO_AUTODESTROY) wid++;
296 else if (entry->action & DO_QUERY_AUTOPICK) wid++;
297 if (!(entry->action & DO_DISPLAY)) wid++;
299 if (wid > 0) tb->cx++;
300 if (wid < 0 && tb->cx > 0) tb->cx--;
303 tb->lines_list[y] = autopick_line_from_entry_kill(entry);
304 tb->dirty_flags |= DIRTY_ALL;
311 * Delete or insert string
313 static void add_keyword(text_body_type *tb, BIT_FLAGS flg)
318 by1 = MIN(tb->my, tb->cy);
319 by2 = MAX(tb->my, tb->cy);
326 for (int y = by1; y <= by2; y++)
328 autopick_type an_entry, *entry = &an_entry;
329 if (!autopick_new_entry(entry, tb->lines_list[y], FALSE)) continue;
333 autopick_free_entry(entry);
337 string_free(tb->lines_list[y]);
338 if (FLG_NOUN_BEGIN <= flg && flg <= FLG_NOUN_END)
341 for (i = FLG_NOUN_BEGIN; i <= FLG_NOUN_END; i++)
346 tb->lines_list[y] = autopick_line_from_entry_kill(entry);
347 tb->dirty_flags |= DIRTY_ALL;
354 * Add an empty line at the last of the file
356 static bool add_empty_line(text_body_type *tb)
359 for (num_lines = 0; tb->lines_list[num_lines]; num_lines++);
361 if (num_lines >= MAX_LINES - 2) return FALSE;
362 if (!tb->lines_list[num_lines - 1][0]) return FALSE;
364 tb->lines_list[num_lines] = string_make("");
365 tb->dirty_flags |= DIRTY_EXPRESSION;
372 * Display the menu, and get a command
374 static int do_command_menu(int level, int start)
377 int col0 = 5 + level * 7;
378 int row0 = 1 + level * 3;
379 int menu_id_list[26];
381 char linestr[MAX_LINELEN];
384 for (int i = start; menu_data[i].level >= level; i++)
386 /* Ignore lower level sub menus */
387 if (menu_data[i].level > level) continue;
389 int len = strlen(menu_data[i].name);
390 if (len > max_len) max_len = len;
392 menu_id_list[menu_key] = i;
396 while (menu_key < 26)
398 menu_id_list[menu_key] = -1;
402 int max_menu_wid = max_len + 3 + 3;
404 /* Prepare box line */
406 strcat(linestr, "+");
407 for (int i = 0; i < max_menu_wid + 2; i++)
409 strcat(linestr, "-");
412 strcat(linestr, "+");
419 Term_putstr(col0, row0, -1, TERM_WHITE, linestr);
422 for (int i = start; menu_data[i].level >= level; i++)
426 if (menu_data[i].level > level) continue;
428 if (menu_data[i].com_id == -1)
430 strcpy(com_key_str, _("▼", ">"));
432 else if (menu_data[i].key != -1)
434 com_key_str[0] = '^';
435 com_key_str[1] = menu_data[i].key + '@';
436 com_key_str[2] = '\0';
440 com_key_str[0] = '\0';
443 str = format("| %c) %-*s %2s | ", menu_key + 'a', max_len, menu_data[i].name, com_key_str);
445 Term_putstr(col0, row1++, -1, TERM_WHITE, str);
450 Term_putstr(col0, row1, -1, TERM_WHITE, linestr);
454 prt(format(_("(a-%c) コマンド:", "(a-%c) Command:"), menu_key + 'a' - 1), 0, 0);
457 if (key == ESCAPE) return 0;
460 bool is_alphabet = key >= 'a' && key <= 'z';
463 com_id = get_com_id(key);
472 int menu_id = menu_id_list[key - 'a'];
474 if (menu_id < 0) continue;
476 com_id = menu_data[menu_id].com_id;
480 com_id = do_command_menu(level + 1, menu_id + 1);
482 if (com_id) return com_id;
493 static chain_str_type *new_chain_str(concptr str)
495 chain_str_type *chain;
496 size_t len = strlen(str);
497 chain = (chain_str_type *)ralloc(sizeof(chain_str_type) + len * sizeof(char));
498 strcpy(chain->s, str);
504 static void kill_yank_chain(text_body_type *tb)
506 chain_str_type *chain = tb->yank;
512 chain_str_type *next = chain->next;
513 size_t len = strlen(chain->s);
515 rnfree(chain, sizeof(chain_str_type) + len * sizeof(char));
522 static void add_str_to_yank(text_body_type *tb, concptr str)
524 tb->yank_eol = FALSE;
525 if (NULL == tb->yank)
527 tb->yank = new_chain_str(str);
531 chain_str_type *chain;
538 chain->next = new_chain_str(str);
549 * Do work for the copy editor-command
551 static void copy_text_to_yank(text_body_type *tb)
553 int len = strlen(tb->lines_list[tb->cy]);
554 if (tb->cx > len) tb->cx = len;
564 if (tb->my != tb->cy)
566 int by1 = MIN(tb->my, tb->cy);
567 int by2 = MAX(tb->my, tb->cy);
569 for (int y = by1; y <= by2; y++)
571 add_str_to_yank(tb, tb->lines_list[y]);
574 add_str_to_yank(tb, "");
576 tb->dirty_flags |= DIRTY_ALL;
580 char buf[MAX_LINELEN];
581 int bx1 = MIN(tb->mx, tb->cx);
582 int bx2 = MAX(tb->mx, tb->cx);
583 if (bx2 > len) bx2 = len;
585 if (bx1 == 0 && bx2 == len)
587 add_str_to_yank(tb, tb->lines_list[tb->cy]);
588 add_str_to_yank(tb, "");
593 for (int i = 0; i < bx2 - bx1; i++)
595 buf[i] = tb->lines_list[tb->cy][bx1 + i];
599 add_str_to_yank(tb, buf);
603 tb->dirty_flags |= DIRTY_ALL;
608 * Execute a single editor command
610 static bool do_editor_command(player_type *player_ptr, text_body_type *tb, int com_id)
617 if (!get_check(_("全ての変更を破棄してから終了します。よろしいですか? ",
618 "Discard all changes and quit. Are you sure? "))) break;
621 return QUIT_WITHOUT_SAVE;
624 return QUIT_AND_SAVE;
627 if (!get_check(_("全ての変更を破棄して元の状態に戻します。よろしいですか? ",
628 "Discard all changes and revert to original file. Are you sure? "))) break;
630 free_text_lines(tb->lines_list);
631 tb->lines_list = read_pickpref_text_lines(player_ptr, &tb->filename_mode);
632 tb->dirty_flags |= DIRTY_ALL | DIRTY_MODE | DIRTY_EXPRESSION;
640 (void)show_file(player_ptr, TRUE, _("jeditor.txt", "editor.txt"), NULL, 0, 0);
641 tb->dirty_flags |= DIRTY_SCREEN;
649 tb->dirty_flags |= DIRTY_ALL;
652 insert_return_code(tb);
656 tb->dirty_flags |= DIRTY_ALL;
668 len = strlen(tb->lines_list[tb->cy]);
669 if (len < tb->cx) tb->cx = len;
671 for (i = 0; tb->lines_list[tb->cy][i]; i++)
673 if (iskanji(tb->lines_list[tb->cy][i]))
688 tb->cx = strlen(tb->lines_list[tb->cy]);
694 if (!tb->lines_list[tb->cy + 1])
696 if (!add_empty_line(tb)) break;
703 if (tb->cy > 0) tb->cy--;
709 if (iskanji(tb->lines_list[tb->cy][tb->cx])) tb->cx++;
712 int len = strlen(tb->lines_list[tb->cy]);
716 if (!tb->lines_list[tb->cy + 1])
718 if (!add_empty_line(tb)) break;
732 tb->cx = strlen(tb->lines_list[tb->cy]);
736 while (0 < tb->cy && tb->upper <= tb->cy)
738 while (0 < tb->upper && tb->cy + 1 < tb->upper + tb->hgt)
743 while (tb->cy < tb->upper + tb->hgt)
745 if (!tb->lines_list[tb->cy + 1])
747 if (!add_empty_line(tb)) break;
763 if (!tb->lines_list[tb->cy + 1])
765 if (!add_empty_line(tb)) break;
776 copy_text_to_yank(tb);
777 if (tb->my == tb->cy)
779 int bx1 = MIN(tb->mx, tb->cx);
780 int bx2 = MAX(tb->mx, tb->cx);
781 int len = strlen(tb->lines_list[tb->cy]);
782 if (bx2 > len) bx2 = len;
784 kill_line_segment(tb, tb->cy, bx1, bx2, TRUE);
789 int by1 = MIN(tb->my, tb->cy);
790 int by2 = MAX(tb->my, tb->cy);
792 for (int y = by2; y >= by1; y--)
794 int len = strlen(tb->lines_list[y]);
796 kill_line_segment(tb, y, 0, len, TRUE);
804 tb->dirty_flags |= DIRTY_ALL;
809 copy_text_to_yank(tb);
812 * Move cursor position to the end of the selection
814 * Pressing ^C ^V correctly duplicates the selection.
816 if (tb->my != tb->cy)
818 tb->cy = MAX(tb->cy, tb->my);
819 if (!tb->lines_list[tb->cy + 1])
821 if (!add_empty_line(tb)) break;
828 tb->cx = MAX(tb->cx, tb->mx);
829 if (!tb->lines_list[tb->cy][tb->cx])
831 if (!tb->lines_list[tb->cy + 1])
833 if (!add_empty_line(tb)) break;
844 chain_str_type *chain = tb->yank;
845 int len = strlen(tb->lines_list[tb->cy]);
847 if (tb->cx > len) tb->cx = len;
852 tb->dirty_flags |= DIRTY_ALL;
857 concptr yank_str = chain->s;
858 char buf[MAX_LINELEN];
860 char rest[MAX_LINELEN], *rest_ptr = rest;
861 for (i = 0; i < tb->cx; i++)
862 buf[i] = tb->lines_list[tb->cy][i];
864 strcpy(rest, &(tb->lines_list[tb->cy][i]));
865 while (*yank_str && i < MAX_LINELEN - 1)
867 buf[i++] = *yank_str++;
872 if (chain || tb->yank_eol)
874 insert_return_code(tb);
875 string_free(tb->lines_list[tb->cy]);
876 tb->lines_list[tb->cy] = string_make(buf);
883 tb->cx = strlen(buf);
884 while (*rest_ptr && i < MAX_LINELEN - 1)
886 buf[i++] = *rest_ptr++;
890 string_free(tb->lines_list[tb->cy]);
891 tb->lines_list[tb->cy] = string_make(buf);
895 tb->dirty_flags |= DIRTY_ALL;
896 tb->dirty_flags |= DIRTY_EXPRESSION;
905 tb->dirty_flags |= DIRTY_ALL;
909 tb->mark = MARK_MARK;
910 if (com_id == tb->old_com_id)
918 tb->dirty_flags |= DIRTY_ALL;
922 int len = strlen(tb->lines_list[tb->cy]);
926 if (tb->cx > len) tb->mx = len;
931 int len = strlen(tb->lines_list[tb->cy]);
932 if (tb->cx > len) tb->cx = len;
937 tb->dirty_flags |= DIRTY_ALL;
940 if (tb->old_com_id != com_id)
948 add_str_to_yank(tb, &(tb->lines_list[tb->cy][tb->cx]));
949 kill_line_segment(tb, tb->cy, tb->cx, len, FALSE);
950 tb->dirty_line = tb->cy;
954 if (tb->yank_eol) add_str_to_yank(tb, "");
957 do_editor_command(player_ptr, tb, EC_DELETE_CHAR);
965 tb->dirty_flags |= DIRTY_ALL;
969 if (iskanji(tb->lines_list[tb->cy][tb->cx])) tb->cx++;
972 int len = strlen(tb->lines_list[tb->cy]);
975 do_editor_command(player_ptr, tb, EC_BACKSPACE);
979 if (tb->lines_list[tb->cy + 1])
990 do_editor_command(player_ptr, tb, EC_BACKSPACE);
996 char buf[MAX_LINELEN];
1000 tb->dirty_flags |= DIRTY_ALL;
1003 len = strlen(tb->lines_list[tb->cy]);
1004 if (len < tb->cx) tb->cx = len;
1008 if (tb->cy == 0) break;
1009 tb->cx = strlen(tb->lines_list[tb->cy - 1]);
1010 strcpy(buf, tb->lines_list[tb->cy - 1]);
1011 strcat(buf, tb->lines_list[tb->cy]);
1012 string_free(tb->lines_list[tb->cy - 1]);
1013 string_free(tb->lines_list[tb->cy]);
1014 tb->lines_list[tb->cy - 1] = string_make(buf);
1016 for (i = tb->cy; tb->lines_list[i + 1]; i++)
1017 tb->lines_list[i] = tb->lines_list[i + 1];
1019 tb->lines_list[i] = NULL;
1021 tb->dirty_flags |= DIRTY_ALL;
1022 tb->dirty_flags |= DIRTY_EXPRESSION;
1027 for (i = j = k = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
1031 if (iskanji(tb->lines_list[tb->cy][i]))
1032 buf[j++] = tb->lines_list[tb->cy][i++];
1034 buf[j++] = tb->lines_list[tb->cy][i];
1043 for (; tb->lines_list[tb->cy][i]; i++)
1045 buf[j++] = tb->lines_list[tb->cy][i];
1049 string_free(tb->lines_list[tb->cy]);
1050 tb->lines_list[tb->cy] = string_make(buf);
1051 tb->dirty_line = tb->cy;
1052 check_expression_line(tb, tb->cy);
1059 tb->dirty_flags |= DIRTY_SCREEN;
1060 search_dir = get_string_for_search(player_ptr, &tb->search_o_ptr, &tb->search_str);
1062 if (!search_dir) break;
1064 if (search_dir == 1) do_editor_command(player_ptr, tb, EC_SEARCH_FORW);
1065 else do_editor_command(player_ptr, tb, EC_SEARCH_BACK);
1068 case EC_SEARCH_FORW:
1069 if (tb->search_o_ptr)
1071 search_for_object(player_ptr, tb, tb->search_o_ptr, TRUE);
1075 if (tb->search_str && tb->search_str[0])
1077 search_for_string(tb, tb->search_str, TRUE);
1081 tb->dirty_flags |= DIRTY_NO_SEARCH;
1084 case EC_SEARCH_BACK:
1085 if (tb->search_o_ptr)
1087 search_for_object(player_ptr, tb, tb->search_o_ptr, FALSE);
1091 if (tb->search_str && tb->search_str[0])
1093 search_for_string(tb, tb->search_str, FALSE);
1097 tb->dirty_flags |= DIRTY_NO_SEARCH;
1101 tb->dirty_flags |= DIRTY_SCREEN;
1103 if (!get_object_for_search(player_ptr, &tb->search_o_ptr, &tb->search_str)) break;
1105 do_editor_command(player_ptr, tb, EC_SEARCH_FORW);
1108 case EC_SEARCH_DESTROYED:
1109 if (!get_destroyed_object_for_search(player_ptr, &tb->search_o_ptr, &tb->search_str))
1111 tb->dirty_flags |= DIRTY_NO_SEARCH;
1115 do_editor_command(player_ptr, tb, EC_SEARCH_FORW);
1118 case EC_INSERT_OBJECT:
1120 autopick_type an_entry, *entry = &an_entry;
1121 if (!entry_from_choosed_object(player_ptr, entry))
1123 tb->dirty_flags |= DIRTY_SCREEN;
1128 insert_return_code(tb);
1129 string_free(tb->lines_list[tb->cy]);
1130 tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
1131 tb->dirty_flags |= DIRTY_SCREEN;
1134 case EC_INSERT_DESTROYED:
1135 if (!tb->last_destroyed) break;
1138 insert_return_code(tb);
1139 string_free(tb->lines_list[tb->cy]);
1140 tb->lines_list[tb->cy] = string_make(tb->last_destroyed);
1141 tb->dirty_flags |= DIRTY_ALL;
1145 case EC_INSERT_BLOCK:
1147 char expression[80];
1148 sprintf(expression, "?:[AND [EQU $RACE %s] [EQU $CLASS %s] [GEQ $LEVEL %02d]]",
1150 rp_ptr->E_title, cp_ptr->E_title,
1152 rp_ptr->title, cp_ptr->title,
1156 insert_return_code(tb);
1157 string_free(tb->lines_list[tb->cy]);
1158 tb->lines_list[tb->cy] = string_make(expression);
1160 insert_return_code(tb);
1161 string_free(tb->lines_list[tb->cy]);
1162 tb->lines_list[tb->cy] = string_make("?:1");
1163 tb->dirty_flags |= DIRTY_ALL;
1168 case EC_INSERT_MACRO:
1169 draw_text_editor(player_ptr, tb);
1170 Term_erase(0, tb->cy - tb->upper + 1, tb->wid);
1171 Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW, _("P:<トリガーキー>: ", "P:<Trigger key>: "));
1172 if (!insert_macro_line(tb)) break;
1175 tb->dirty_flags |= DIRTY_ALL;
1179 case EC_INSERT_KEYMAP:
1180 draw_text_editor(player_ptr, tb);
1181 Term_erase(0, tb->cy - tb->upper + 1, tb->wid);
1182 Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW,
1183 format(_("C:%d:<コマンドキー>: ", "C:%d:<Keypress>: "), (rogue_like_commands ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG)));
1185 if (!insert_keymap_line(tb)) break;
1188 tb->dirty_flags |= DIRTY_ALL;
1192 case EC_CL_AUTOPICK: toggle_command_letter(tb, DO_AUTOPICK); break;
1193 case EC_CL_DESTROY: toggle_command_letter(tb, DO_AUTODESTROY); break;
1194 case EC_CL_LEAVE: toggle_command_letter(tb, DONT_AUTOPICK); break;
1195 case EC_CL_QUERY: toggle_command_letter(tb, DO_QUERY_AUTOPICK); break;
1196 case EC_CL_NO_DISP: toggle_command_letter(tb, DO_DISPLAY); break;
1198 case EC_IK_UNAWARE: toggle_keyword(tb, FLG_UNAWARE); break;
1199 case EC_IK_UNIDENTIFIED: toggle_keyword(tb, FLG_UNIDENTIFIED); break;
1200 case EC_IK_IDENTIFIED: toggle_keyword(tb, FLG_IDENTIFIED); break;
1201 case EC_IK_STAR_IDENTIFIED: toggle_keyword(tb, FLG_STAR_IDENTIFIED); break;
1202 case EC_KK_WEAPONS: toggle_keyword(tb, FLG_WEAPONS); break;
1203 case EC_KK_FAVORITE_WEAPONS: toggle_keyword(tb, FLG_FAVORITE_WEAPONS); break;
1204 case EC_KK_ARMORS: toggle_keyword(tb, FLG_ARMORS); break;
1205 case EC_KK_MISSILES: toggle_keyword(tb, FLG_MISSILES); break;
1206 case EC_KK_DEVICES: toggle_keyword(tb, FLG_DEVICES); break;
1207 case EC_KK_LIGHTS: toggle_keyword(tb, FLG_LIGHTS); break;
1208 case EC_KK_JUNKS: toggle_keyword(tb, FLG_JUNKS); break;
1209 case EC_KK_CORPSES: toggle_keyword(tb, FLG_CORPSES); break;
1210 case EC_KK_SPELLBOOKS: toggle_keyword(tb, FLG_SPELLBOOKS); break;
1211 case EC_KK_SHIELDS: toggle_keyword(tb, FLG_SHIELDS); break;
1212 case EC_KK_BOWS: toggle_keyword(tb, FLG_BOWS); break;
1213 case EC_KK_RINGS: toggle_keyword(tb, FLG_RINGS); break;
1214 case EC_KK_AMULETS: toggle_keyword(tb, FLG_AMULETS); break;
1215 case EC_KK_SUITS: toggle_keyword(tb, FLG_SUITS); break;
1216 case EC_KK_CLOAKS: toggle_keyword(tb, FLG_CLOAKS); break;
1217 case EC_KK_HELMS: toggle_keyword(tb, FLG_HELMS); break;
1218 case EC_KK_GLOVES: toggle_keyword(tb, FLG_GLOVES); break;
1219 case EC_KK_BOOTS: toggle_keyword(tb, FLG_BOOTS); break;
1220 case EC_OK_COLLECTING: toggle_keyword(tb, FLG_COLLECTING); break;
1221 case EC_OK_BOOSTED: toggle_keyword(tb, FLG_BOOSTED); break;
1222 case EC_OK_MORE_DICE: toggle_keyword(tb, FLG_MORE_DICE); break;
1223 case EC_OK_MORE_BONUS: toggle_keyword(tb, FLG_MORE_BONUS); break;
1224 case EC_OK_WORTHLESS: toggle_keyword(tb, FLG_WORTHLESS); break;
1225 case EC_OK_ARTIFACT: toggle_keyword(tb, FLG_ARTIFACT); break;
1226 case EC_OK_EGO: toggle_keyword(tb, FLG_EGO); break;
1227 case EC_OK_GOOD: toggle_keyword(tb, FLG_GOOD); break;
1228 case EC_OK_NAMELESS: toggle_keyword(tb, FLG_NAMELESS); break;
1229 case EC_OK_AVERAGE: toggle_keyword(tb, FLG_AVERAGE); break;
1230 case EC_OK_RARE: toggle_keyword(tb, FLG_RARE); break;
1231 case EC_OK_COMMON: toggle_keyword(tb, FLG_COMMON); break;
1232 case EC_OK_WANTED: toggle_keyword(tb, FLG_WANTED); break;
1233 case EC_OK_UNIQUE: toggle_keyword(tb, FLG_UNIQUE); break;
1234 case EC_OK_HUMAN: toggle_keyword(tb, FLG_HUMAN); break;
1235 case EC_OK_UNREADABLE:
1236 toggle_keyword(tb, FLG_UNREADABLE);
1237 add_keyword(tb, FLG_SPELLBOOKS);
1240 toggle_keyword(tb, FLG_REALM1);
1241 add_keyword(tb, FLG_SPELLBOOKS);
1244 toggle_keyword(tb, FLG_REALM2);
1245 add_keyword(tb, FLG_SPELLBOOKS);
1248 toggle_keyword(tb, FLG_FIRST);
1249 add_keyword(tb, FLG_SPELLBOOKS);
1252 toggle_keyword(tb, FLG_SECOND);
1253 add_keyword(tb, FLG_SPELLBOOKS);
1256 toggle_keyword(tb, FLG_THIRD);
1257 add_keyword(tb, FLG_SPELLBOOKS);
1260 toggle_keyword(tb, FLG_FOURTH);
1261 add_keyword(tb, FLG_SPELLBOOKS);
1265 tb->old_com_id = com_id;
1271 * Check special key code and get a movement command id
1273 static int analyze_move_key(text_body_type *tb, int skey)
1276 if (!(skey & SKEY_MASK)) return 0;
1278 switch (skey & ~SKEY_MOD_MASK)
1280 case SKEY_DOWN: com_id = EC_DOWN; break;
1281 case SKEY_LEFT: com_id = EC_LEFT; break;
1282 case SKEY_RIGHT: com_id = EC_RIGHT; break;
1283 case SKEY_UP: com_id = EC_UP; break;
1284 case SKEY_PGUP: com_id = EC_PGUP; break;
1285 case SKEY_PGDOWN: com_id = EC_PGDOWN; break;
1286 case SKEY_TOP: com_id = EC_TOP; break;
1287 case SKEY_BOTTOM: com_id = EC_BOTTOM; break;
1292 if (!(skey & SKEY_MOD_SHIFT))
1295 * Un-shifted cursor keys cancells
1296 * selection created by shift+cursor.
1298 if (tb->mark & MARK_BY_SHIFT)
1301 tb->dirty_flags |= DIRTY_ALL;
1307 if (tb->mark) return com_id;
1309 int len = strlen(tb->lines_list[tb->cy]);
1310 tb->mark = MARK_MARK | MARK_BY_SHIFT;
1313 if (tb->cx > len) tb->mx = len;
1315 if (com_id == EC_UP || com_id == EC_DOWN)
1317 tb->dirty_flags |= DIRTY_ALL;
1321 tb->dirty_line = tb->cy;
1328 * In-game editor of Object Auto-picker/Destoryer
1329 * @param player_ptr プレーヤーへの参照ポインタ
1331 void do_cmd_edit_autopick(player_type *player_ptr)
1333 static int cx_save = 0;
1334 static int cy_save = 0;
1335 autopick_type an_entry, *entry = &an_entry;
1336 char buf[MAX_LINELEN];
1339 static s32b old_autosave_turn = 0L;
1342 text_body_type text_body;
1343 text_body_type *tb = &text_body;
1344 tb->changed = FALSE;
1347 tb->upper = tb->left = 0;
1349 tb->mx = tb->my = 0;
1350 tb->old_cy = tb->old_upper = tb->old_left = -1;
1351 tb->old_wid = tb->old_hgt = -1;
1355 tb->search_o_ptr = NULL;
1356 tb->search_str = NULL;
1357 tb->last_destroyed = NULL;
1358 tb->dirty_flags = DIRTY_ALL | DIRTY_MODE | DIRTY_EXPRESSION;
1359 tb->dirty_line = -1;
1360 tb->filename_mode = PT_DEFAULT;
1362 if (current_world_ptr->game_turn < old_autosave_turn)
1364 while (old_autosave_turn > current_world_ptr->game_turn) old_autosave_turn -= TURNS_PER_TICK * TOWN_DAWN;
1367 if (current_world_ptr->game_turn > old_autosave_turn + 100L)
1369 do_cmd_save_game(player_ptr, TRUE);
1370 old_autosave_turn = current_world_ptr->game_turn;
1375 if (autopick_last_destroyed_object.k_idx)
1377 autopick_entry_from_object(player_ptr, entry, &autopick_last_destroyed_object);
1378 tb->last_destroyed = autopick_line_from_entry_kill(entry);
1381 tb->lines_list = read_pickpref_text_lines(player_ptr, &tb->filename_mode);
1382 for (i = 0; i < tb->cy; i++)
1384 if (!tb->lines_list[i])
1386 tb->cy = tb->cx = 0;
1395 draw_text_editor(player_ptr, tb);
1396 prt(_("(^Q:終了 ^W:セーブして終了, ESC:メニュー, その他:入力)",
1397 "(^Q:Quit, ^W:Save&Quit, ESC:Menu, Other:Input text)"), 0, 0);
1400 prt(format("(%d,%d)", tb->cx, tb->cy), 0, 60);
1404 prt(format("(%d,%d)-(%d,%d)", tb->mx, tb->my, tb->cx, tb->cy), 0, 60);
1407 Term_gotoxy(tb->cx - tb->left, tb->cy - tb->upper + 1);
1408 tb->dirty_flags = 0;
1409 tb->dirty_line = -1;
1410 tb->old_cy = tb->cy;
1411 tb->old_upper = tb->upper;
1412 tb->old_left = tb->left;
1413 tb->old_wid = tb->wid;
1414 tb->old_hgt = tb->hgt;
1416 key = inkey_special(TRUE);
1418 if (key & SKEY_MASK)
1420 com_id = analyze_move_key(tb, key);
1422 else if (key == ESCAPE)
1424 com_id = do_command_menu(0, 0);
1425 tb->dirty_flags |= DIRTY_SCREEN;
1427 else if (!iscntrl((unsigned char)key))
1432 tb->dirty_flags |= DIRTY_ALL;
1435 insert_single_letter(tb, key);
1440 com_id = get_com_id((char)key);
1443 if (com_id) quit = do_editor_command(player_ptr, tb, com_id);
1447 strcpy(buf, pickpref_filename(player_ptr, tb->filename_mode));
1449 if (quit == QUIT_AND_SAVE)
1450 write_text_lines(buf, tb->lines_list);
1452 free_text_lines(tb->lines_list);
1453 string_free(tb->search_str);
1454 string_free(tb->last_destroyed);
1455 kill_yank_chain(tb);
1457 process_autopick_file(player_ptr, buf);
1458 current_world_ptr->start_time = (u32b)time(NULL);