OSDN Git Service

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