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"
31 #include "autopick/autopick-command-menu.h"
32 #include "autopick/autopick-editor-util.h"
33 #include "autopick/autopick-editor-command.h"
35 #include "autopick/autopick.h"
36 #include "core/show-file.h"
37 #include "cmd/cmd-save.h"
38 #include "io/read-pref-file.h"
42 #include "market/store.h"
43 #include "player-move.h"
44 #include "player-class.h"
45 #include "view/display-player.h" // 暫定。後で消す.
46 #include "object-flavor.h"
49 #include "view/display-main-window.h" // 暫定。後で消す.
52 * Auto-destroy marked item
54 static void autopick_delayed_alter_aux(player_type *player_ptr, INVENTORY_IDX item)
57 o_ptr = REF_ITEM(player_ptr, player_ptr->current_floor_ptr, item);
59 if (o_ptr->k_idx == 0 || !(o_ptr->marked & OM_AUTODESTROY)) return;
61 GAME_TEXT o_name[MAX_NLEN];
62 object_desc(player_ptr, o_name, o_ptr, 0);
65 inven_item_increase(player_ptr, item, -(o_ptr->number));
66 inven_item_optimize(player_ptr, item);
70 delete_object_idx(player_ptr, 0 - item);
73 msg_format(_("%sを自動破壊します。", "Auto-destroying %s."), o_name);
78 * Auto-destroy marked items in inventry and on floor
80 void autopick_delayed_alter(player_type *owner_ptr)
85 * Scan inventry in reverse order to prevent
86 * skipping after inven_item_optimize()
88 for (item = INVEN_TOTAL - 1; item >= 0; item--)
89 autopick_delayed_alter_aux(owner_ptr, item);
91 floor_type *floor_ptr = owner_ptr->current_floor_ptr;
92 item = floor_ptr->grid_array[owner_ptr->y][owner_ptr->x].o_idx;
95 OBJECT_IDX next = floor_ptr->o_list[item].next_o_idx;
96 autopick_delayed_alter_aux(owner_ptr, -item);
103 * Auto-inscription and/or destroy
105 * Auto-destroyer works only on inventory or on floor stack only when
108 void autopick_alter_item(player_type *player_ptr, INVENTORY_IDX item, bool destroy)
111 o_ptr = REF_ITEM(player_ptr, player_ptr->current_floor_ptr, item);
112 int idx = find_autopick_list(player_ptr, o_ptr);
113 auto_inscribe_item(player_ptr, o_ptr, idx);
114 if (destroy && item <= INVEN_PACK)
115 auto_destroy_item(player_ptr, o_ptr, idx);
120 * Automatically pickup/destroy items in this grid.
122 void autopick_pickup_items(player_type* player_ptr, grid_type *g_ptr)
124 OBJECT_IDX this_o_idx, next_o_idx = 0;
125 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
127 object_type *o_ptr = &player_ptr->current_floor_ptr->o_list[this_o_idx];
128 next_o_idx = o_ptr->next_o_idx;
129 int idx = find_autopick_list(player_ptr, o_ptr);
130 auto_inscribe_item(player_ptr, o_ptr, idx);
131 bool is_auto_pickup = idx >= 0;
132 is_auto_pickup &= (autopick_list[idx].action & (DO_AUTOPICK | DO_QUERY_AUTOPICK)) != 0;
135 auto_destroy_item(player_ptr, o_ptr, idx);
139 disturb(player_ptr, FALSE, FALSE);
140 if (!inven_carry_okay(o_ptr))
142 GAME_TEXT o_name[MAX_NLEN];
143 object_desc(player_ptr, o_name, o_ptr, 0);
144 msg_format(_("ザックには%sを入れる隙間がない。", "You have no room for %s."), o_name);
145 o_ptr->marked |= OM_NOMSG;
149 if (!(autopick_list[idx].action & DO_QUERY_AUTOPICK))
151 py_pickup_aux(player_ptr, this_o_idx);
155 char out_val[MAX_NLEN + 20];
156 GAME_TEXT o_name[MAX_NLEN];
157 if (o_ptr->marked & OM_NO_QUERY)
162 object_desc(player_ptr, o_name, o_ptr, 0);
163 sprintf(out_val, _("%sを拾いますか? ", "Pick up %s? "), o_name);
164 if (!get_check(out_val))
166 o_ptr->marked |= OM_NOMSG | OM_NO_QUERY;
170 py_pickup_aux(player_ptr, this_o_idx);
176 * Check special key code and get a movement command id
178 static int analyze_move_key(text_body_type *tb, int skey)
181 if (!(skey & SKEY_MASK)) return 0;
183 switch (skey & ~SKEY_MOD_MASK)
185 case SKEY_DOWN: com_id = EC_DOWN; break;
186 case SKEY_LEFT: com_id = EC_LEFT; break;
187 case SKEY_RIGHT: com_id = EC_RIGHT; break;
188 case SKEY_UP: com_id = EC_UP; break;
189 case SKEY_PGUP: com_id = EC_PGUP; break;
190 case SKEY_PGDOWN: com_id = EC_PGDOWN; break;
191 case SKEY_TOP: com_id = EC_TOP; break;
192 case SKEY_BOTTOM: com_id = EC_BOTTOM; break;
197 if (!(skey & SKEY_MOD_SHIFT))
200 * Un-shifted cursor keys cancells
201 * selection created by shift+cursor.
203 if (tb->mark & MARK_BY_SHIFT)
206 tb->dirty_flags |= DIRTY_ALL;
212 if (tb->mark) return com_id;
214 int len = strlen(tb->lines_list[tb->cy]);
215 tb->mark = MARK_MARK | MARK_BY_SHIFT;
218 if (tb->cx > len) tb->mx = len;
220 if (com_id == EC_UP || com_id == EC_DOWN)
222 tb->dirty_flags |= DIRTY_ALL;
226 tb->dirty_line = tb->cy;
233 * In-game editor of Object Auto-picker/Destoryer
234 * @param player_ptr プレーヤーへの参照ポインタ
236 void do_cmd_edit_autopick(player_type *player_ptr)
238 static int cx_save = 0;
239 static int cy_save = 0;
240 autopick_type an_entry, *entry = &an_entry;
241 char buf[MAX_LINELEN];
244 static s32b old_autosave_turn = 0L;
247 text_body_type text_body;
248 text_body_type *tb = &text_body;
252 tb->upper = tb->left = 0;
255 tb->old_cy = tb->old_upper = tb->old_left = -1;
256 tb->old_wid = tb->old_hgt = -1;
260 tb->search_o_ptr = NULL;
261 tb->search_str = NULL;
262 tb->last_destroyed = NULL;
263 tb->dirty_flags = DIRTY_ALL | DIRTY_MODE | DIRTY_EXPRESSION;
265 tb->filename_mode = PT_DEFAULT;
267 if (current_world_ptr->game_turn < old_autosave_turn)
269 while (old_autosave_turn > current_world_ptr->game_turn) old_autosave_turn -= TURNS_PER_TICK * TOWN_DAWN;
272 if (current_world_ptr->game_turn > old_autosave_turn + 100L)
274 do_cmd_save_game(player_ptr, TRUE);
275 old_autosave_turn = current_world_ptr->game_turn;
280 if (autopick_last_destroyed_object.k_idx)
282 autopick_entry_from_object(player_ptr, entry, &autopick_last_destroyed_object);
283 tb->last_destroyed = autopick_line_from_entry_kill(entry);
286 tb->lines_list = read_pickpref_text_lines(player_ptr, &tb->filename_mode);
287 for (i = 0; i < tb->cy; i++)
289 if (!tb->lines_list[i])
300 draw_text_editor(player_ptr, tb);
301 prt(_("(^Q:終了 ^W:セーブして終了, ESC:メニュー, その他:入力)",
302 "(^Q:Quit, ^W:Save&Quit, ESC:Menu, Other:Input text)"), 0, 0);
305 prt(format("(%d,%d)", tb->cx, tb->cy), 0, 60);
309 prt(format("(%d,%d)-(%d,%d)", tb->mx, tb->my, tb->cx, tb->cy), 0, 60);
312 Term_gotoxy(tb->cx - tb->left, tb->cy - tb->upper + 1);
316 tb->old_upper = tb->upper;
317 tb->old_left = tb->left;
318 tb->old_wid = tb->wid;
319 tb->old_hgt = tb->hgt;
321 key = inkey_special(TRUE);
325 com_id = analyze_move_key(tb, key);
327 else if (key == ESCAPE)
329 com_id = do_command_menu(0, 0);
330 tb->dirty_flags |= DIRTY_SCREEN;
332 else if (!iscntrl((unsigned char)key))
337 tb->dirty_flags |= DIRTY_ALL;
340 insert_single_letter(tb, key);
345 com_id = get_com_id((char)key);
348 if (com_id) quit = do_editor_command(player_ptr, tb, com_id);
352 strcpy(buf, pickpref_filename(player_ptr, tb->filename_mode));
354 if (quit == QUIT_AND_SAVE)
355 write_text_lines(buf, tb->lines_list);
357 free_text_lines(tb->lines_list);
358 string_free(tb->search_str);
359 string_free(tb->last_destroyed);
362 process_autopick_file(player_ptr, buf);
363 current_world_ptr->start_time = (u32b)time(NULL);