OSDN Git Service

Merge branch 'develop' into macos-develop
[hengbandforosx/hengbandosx.git] / src / cmd-io / cmd-autopick.cpp
1 #include "cmd-io/cmd-autopick.h"
2 #include "autopick/autopick-command-menu.h"
3 #include "autopick/autopick-commands-table.h"
4 #include "autopick/autopick-dirty-flags.h"
5 #include "autopick/autopick-drawer.h"
6 #include "autopick/autopick-editor-command.h"
7 #include "autopick/autopick-editor-util.h"
8 #include "autopick/autopick-entry.h"
9 #include "autopick/autopick-initializer.h"
10 #include "autopick/autopick-inserter-killer.h"
11 #include "autopick/autopick-pref-processor.h"
12 #include "autopick/autopick-reader-writer.h"
13 #include "autopick/autopick-util.h"
14 #include "cmd-io/cmd-save.h"
15 #include "io/input-key-acceptor.h"
16 #include "io/read-pref-file.h"
17 #include "system/item-entity.h"
18 #include "term/screen-processor.h"
19 #include "util/int-char-converter.h"
20 #include "world/world.h"
21
22 /*
23  * Check special key code and get a movement command id
24  */
25 static int analyze_move_key(text_body_type *tb, int skey)
26 {
27     int com_id;
28     if (!(skey & SKEY_MASK)) {
29         return 0;
30     }
31
32     switch (skey & ~SKEY_MOD_MASK) {
33     case SKEY_DOWN:
34         com_id = EC_DOWN;
35         break;
36     case SKEY_LEFT:
37         com_id = EC_LEFT;
38         break;
39     case SKEY_RIGHT:
40         com_id = EC_RIGHT;
41         break;
42     case SKEY_UP:
43         com_id = EC_UP;
44         break;
45     case SKEY_PGUP:
46         com_id = EC_PGUP;
47         break;
48     case SKEY_PGDOWN:
49         com_id = EC_PGDOWN;
50         break;
51     case SKEY_TOP:
52         com_id = EC_TOP;
53         break;
54     case SKEY_BOTTOM:
55         com_id = EC_BOTTOM;
56         break;
57     default:
58         return 0;
59     }
60
61     if (!(skey & SKEY_MOD_SHIFT)) {
62         /*
63          * Un-shifted cursor keys cancells
64          * selection created by shift+cursor.
65          */
66         if (tb->mark & MARK_BY_SHIFT) {
67             tb->mark = 0;
68             tb->dirty_flags |= DIRTY_ALL;
69         }
70
71         return com_id;
72     }
73
74     if (tb->mark) {
75         return com_id;
76     }
77
78     int len = strlen(tb->lines_list[tb->cy]);
79     tb->mark = MARK_MARK | MARK_BY_SHIFT;
80     tb->my = tb->cy;
81     tb->mx = tb->cx;
82     if (tb->cx > len) {
83         tb->mx = len;
84     }
85
86     if (com_id == EC_UP || com_id == EC_DOWN) {
87         tb->dirty_flags |= DIRTY_ALL;
88     } else {
89         tb->dirty_line = tb->cy;
90     }
91
92     return com_id;
93 }
94
95 /*
96  * In-game editor of Object Auto-picker/Destoryer
97  * @param player_ptr プレイヤーへの参照ポインタ
98  */
99 void do_cmd_edit_autopick(PlayerType *player_ptr)
100 {
101     static int cx_save = 0;
102     static int cy_save = 0;
103     autopick_type an_entry, *entry = &an_entry;
104     int i;
105     int key = -1;
106     static int32_t old_autosave_turn = 0L;
107     ape_quittance quit = APE_QUIT;
108
109     text_body_type text_body;
110     text_body_type *tb = &text_body;
111     tb->changed = false;
112     tb->cx = cx_save;
113     tb->cy = cy_save;
114     tb->upper = tb->left = 0;
115     tb->mark = 0;
116     tb->mx = tb->my = 0;
117     tb->old_cy = tb->old_upper = tb->old_left = -1;
118     tb->old_wid = tb->old_hgt = -1;
119     tb->old_com_id = 0;
120
121     tb->yank.clear();
122     tb->search_o_ptr = nullptr;
123     tb->search_str = nullptr;
124     tb->last_destroyed = nullptr;
125     tb->dirty_flags = DIRTY_ALL | DIRTY_MODE | DIRTY_EXPRESSION;
126     tb->dirty_line = -1;
127     tb->filename_mode = PT_DEFAULT;
128
129     if (w_ptr->game_turn < old_autosave_turn) {
130         while (old_autosave_turn > w_ptr->game_turn) {
131             old_autosave_turn -= TURNS_PER_TICK * TOWN_DAWN;
132         }
133     }
134
135     if (w_ptr->game_turn > old_autosave_turn + 100L) {
136         do_cmd_save_game(player_ptr, true);
137         old_autosave_turn = w_ptr->game_turn;
138     }
139
140     update_playtime();
141     init_autopick();
142     if (autopick_last_destroyed_object.is_valid()) {
143         autopick_entry_from_object(player_ptr, entry, &autopick_last_destroyed_object);
144         tb->last_destroyed = autopick_line_from_entry(*entry);
145     }
146
147     tb->lines_list = read_pickpref_text_lines(player_ptr, &tb->filename_mode);
148     for (i = 0; i < tb->cy; i++) {
149         if (!tb->lines_list[i]) {
150             tb->cy = tb->cx = 0;
151             break;
152         }
153     }
154
155     TermCenteredOffsetSetter tcos(std::nullopt, std::nullopt);
156
157     screen_save();
158     while (quit == APE_QUIT) {
159         int com_id = 0;
160         draw_text_editor(player_ptr, tb);
161         prt(_("(^Q:終了 ^W:セーブして終了, ESC:メニュー, その他:入力)",
162                 "(^Q:Quit, ^W:Save&Quit, ESC:Menu, Other:Input text)"),
163             0, 0);
164         if (!tb->mark) {
165             prt(format("(%d,%d)", tb->cx, tb->cy), 0, 60);
166         } else {
167             prt(format("(%d,%d)-(%d,%d)", tb->mx, tb->my, tb->cx, tb->cy), 0, 60);
168         }
169
170         term_gotoxy(tb->cx - tb->left, tb->cy - tb->upper + 1);
171         tb->dirty_flags = 0;
172         tb->dirty_line = -1;
173         tb->old_cy = tb->cy;
174         tb->old_upper = tb->upper;
175         tb->old_left = tb->left;
176         tb->old_wid = tb->wid;
177         tb->old_hgt = tb->hgt;
178
179         key = inkey_special(true);
180
181         if (key & SKEY_MASK) {
182             com_id = analyze_move_key(tb, key);
183         } else if (key == ESCAPE) {
184             com_id = do_command_menu(0, 0);
185             tb->dirty_flags |= DIRTY_SCREEN;
186         } else if (!iscntrl((unsigned char)key)) {
187             if (tb->mark) {
188                 tb->mark = 0;
189                 tb->dirty_flags |= DIRTY_ALL;
190             }
191
192             insert_single_letter(tb, key);
193             continue;
194         } else {
195             com_id = get_com_id((char)key);
196         }
197
198         if (com_id) {
199             quit = do_editor_command(player_ptr, tb, com_id);
200         }
201     }
202
203     screen_load();
204     const auto filename = pickpref_filename(player_ptr, tb->filename_mode);
205
206     if (quit == APE_QUIT_AND_SAVE) {
207         write_text_lines(filename, tb->lines_list);
208     }
209
210     free_text_lines(tb->lines_list);
211     string_free(tb->search_str);
212     string_free(tb->last_destroyed);
213     kill_yank_chain(tb);
214
215     process_autopick_file(player_ptr, filename);
216     w_ptr->start_time = (uint32_t)time(nullptr);
217     cx_save = tb->cx;
218     cy_save = tb->cy;
219 }