OSDN Git Service

In descriptions but not keywords, replaced "armors" with "armor".
[hengband/hengband.git] / src / autopick.c
1 /*!
2  * @file autopick.c
3  * @brief 自動拾い機能の実装 / Object Auto-picker/Destroyer
4  * @date 2014/01/02
5  * @author
6  * Copyright (c) 2002  Mogami\n
7  *\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
12  */
13
14 #include "angband.h"
15 #include "util.h"
16 #include "term.h"
17 #include "autopick.h"
18 #include "core.h"
19
20 #include "mind.h"
21
22 #include "store.h"
23 #include "player-status.h"
24 #include "player-move.h"
25 #include "player-class.h"
26 #include "player-race.h"
27 #include "player-inventory.h"
28 #include "objectkind.h"
29 #include "object-ego.h"
30 #include "object-flavor.h"
31 #include "object-hook.h"
32
33 #include "files.h"
34 #include "floor.h"
35 #include "world.h"
36 #include "monster.h"
37 #include "monsterrace.h"
38 #include "view-mainwindow.h"
39
40 #define MAX_LINELEN 1024
41
42  /*
43   * Macros for Keywords
44   */
45 #define FLG_ALL                         0
46 #define FLG_UNAWARE                     1
47 #define FLG_UNIDENTIFIED        2
48 #define FLG_IDENTIFIED          3
49 #define FLG_STAR_IDENTIFIED     4
50 #define FLG_COLLECTING          5
51 #define FLG_ARTIFACT            6
52 #define FLG_EGO              7 
53 #define FLG_GOOD             10
54 #define FLG_NAMELESS     11
55 #define FLG_AVERAGE          12
56 #define FLG_WORTHLESS    13
57 #define FLG_RARE             14
58 #define FLG_COMMON           15
59 #define FLG_BOOSTED          16
60 #define FLG_MORE_DICE    17
61 #define FLG_MORE_BONUS   18
62 #define FLG_WANTED           19
63 #define FLG_UNIQUE           20
64 #define FLG_HUMAN            21
65 #define FLG_UNREADABLE   22
66 #define FLG_REALM1           23
67 #define FLG_REALM2           24
68 #define FLG_FIRST            25
69 #define FLG_SECOND           26
70 #define FLG_THIRD            27
71 #define FLG_FOURTH           28
72
73 #define FLG_ITEMS            30
74 #define FLG_WEAPONS          31
75 #define FLG_FAVORITE_WEAPONS 32
76 #define FLG_ARMORS           33
77 #define FLG_MISSILES         34
78 #define FLG_DEVICES          35
79 #define FLG_LIGHTS           36
80 #define FLG_JUNKS            37
81 #define FLG_CORPSES          38
82 #define FLG_SPELLBOOKS       39
83 #define FLG_HAFTED           40
84 #define FLG_SHIELDS          41
85 #define FLG_BOWS             42
86 #define FLG_RINGS            43
87 #define FLG_AMULETS          44
88 #define FLG_SUITS            45
89 #define FLG_CLOAKS           46
90 #define FLG_HELMS            47
91 #define FLG_GLOVES           48
92 #define FLG_BOOTS            49
93
94 #define FLG_NOUN_BEGIN      FLG_ITEMS
95 #define FLG_NOUN_END        FLG_BOOTS
96
97 #ifdef JP
98
99 static GAME_TEXT KEY_ALL[] = "すべての";
100 static GAME_TEXT KEY_UNAWARE[] = "未判明の";
101 static GAME_TEXT KEY_UNIDENTIFIED[] = "未鑑定の";
102 static GAME_TEXT KEY_IDENTIFIED[] = "鑑定済みの";
103 static GAME_TEXT KEY_STAR_IDENTIFIED[] = "*鑑定*済みの";
104 static GAME_TEXT KEY_COLLECTING[] = "収集中の";
105 static GAME_TEXT KEY_ARTIFACT[] = "アーティファクト";
106 static GAME_TEXT KEY_EGO[] = "エゴ";
107 static GAME_TEXT KEY_GOOD[] = "上質の";
108 static GAME_TEXT KEY_NAMELESS[] = "無銘の";
109 static GAME_TEXT KEY_AVERAGE[] = "並の";
110 static GAME_TEXT KEY_WORTHLESS[] = "無価値の";
111 static GAME_TEXT KEY_RARE[] = "レアな";
112 static GAME_TEXT KEY_COMMON[] = "ありふれた";
113 static GAME_TEXT KEY_BOOSTED[] = "ダイス目の違う";
114 static GAME_TEXT KEY_MORE_THAN[] = "ダイス目";
115 static GAME_TEXT KEY_DICE[] = "以上の";
116 static GAME_TEXT KEY_MORE_BONUS[] = "修正値";
117 static GAME_TEXT KEY_MORE_BONUS2[] = "以上の";
118 static GAME_TEXT KEY_WANTED[] = "賞金首の";
119 static GAME_TEXT KEY_UNIQUE[] = "ユニーク・モンスターの";
120 static GAME_TEXT KEY_HUMAN[] = "人間の";
121 static GAME_TEXT KEY_UNREADABLE[] = "読めない";
122 static GAME_TEXT KEY_REALM1[] = "第一領域の";
123 static GAME_TEXT KEY_REALM2[] = "第二領域の";
124 static GAME_TEXT KEY_FIRST[] = "1冊目の";
125 static GAME_TEXT KEY_SECOND[] = "2冊目の";
126 static GAME_TEXT KEY_THIRD[] = "3冊目の";
127 static GAME_TEXT KEY_FOURTH[] = "4冊目の";
128 static GAME_TEXT KEY_ITEMS[] = "アイテム";
129 static GAME_TEXT KEY_WEAPONS[] = "武器";
130 static GAME_TEXT KEY_FAVORITE_WEAPONS[] = "得意武器";
131 static GAME_TEXT KEY_ARMORS[] = "防具";
132 static GAME_TEXT KEY_MISSILES[] = "矢";
133 static GAME_TEXT KEY_DEVICES[] = "魔法アイテム";
134 static GAME_TEXT KEY_LIGHTS[] = "光源";
135 static GAME_TEXT KEY_JUNKS[] = "がらくた";
136 static GAME_TEXT KEY_CORPSES[] = "死体や骨";
137 static GAME_TEXT KEY_SPELLBOOKS[] = "魔法書";
138 static GAME_TEXT KEY_HAFTED[] = "鈍器";
139 static GAME_TEXT KEY_SHIELDS[] = "盾";
140 static GAME_TEXT KEY_BOWS[] = "弓";
141 static GAME_TEXT KEY_RINGS[] = "指輪";
142 static GAME_TEXT KEY_AMULETS[] = "アミュレット";
143 static GAME_TEXT KEY_SUITS[] = "鎧";
144 static GAME_TEXT KEY_CLOAKS[] = "クローク";
145 static GAME_TEXT KEY_HELMS[] = "兜";
146 static GAME_TEXT KEY_GLOVES[] = "籠手";
147 static GAME_TEXT KEY_BOOTS[] = "靴";
148
149 #else 
150
151 static GAME_TEXT KEY_ALL[] = "all";
152 static GAME_TEXT KEY_UNAWARE[] = "unaware";
153 static GAME_TEXT KEY_UNIDENTIFIED[] = "unidentified";
154 static GAME_TEXT KEY_IDENTIFIED[] = "identified";
155 static GAME_TEXT KEY_STAR_IDENTIFIED[] = "*identified*";
156 static GAME_TEXT KEY_COLLECTING[] = "collecting";
157 static GAME_TEXT KEY_ARTIFACT[] = "artifact";
158 static GAME_TEXT KEY_EGO[] = "ego";
159 static GAME_TEXT KEY_GOOD[] = "good";
160 static GAME_TEXT KEY_NAMELESS[] = "nameless";
161 static GAME_TEXT KEY_AVERAGE[] = "average";
162 static GAME_TEXT KEY_WORTHLESS[] = "worthless";
163 static GAME_TEXT KEY_RARE[] = "rare";
164 static GAME_TEXT KEY_COMMON[] = "common";
165 static GAME_TEXT KEY_BOOSTED[] = "dice boosted";
166 static GAME_TEXT KEY_MORE_THAN[] = "more than";
167 static GAME_TEXT KEY_DICE[] = " dice";
168 static GAME_TEXT KEY_MORE_BONUS[] = "more bonus than";
169 static GAME_TEXT KEY_MORE_BONUS2[] = "";
170 static GAME_TEXT KEY_WANTED[] = "wanted";
171 static GAME_TEXT KEY_UNIQUE[] = "unique monster's";
172 static GAME_TEXT KEY_HUMAN[] = "human";
173 static GAME_TEXT KEY_UNREADABLE[] = "unreadable";
174 static GAME_TEXT KEY_REALM1[] = "first realm's";
175 static GAME_TEXT KEY_REALM2[] = "second realm's";
176 static GAME_TEXT KEY_FIRST[] = "first";
177 static GAME_TEXT KEY_SECOND[] = "second";
178 static GAME_TEXT KEY_THIRD[] = "third";
179 static GAME_TEXT KEY_FOURTH[] = "fourth";
180 static GAME_TEXT KEY_ITEMS[] = "items";
181 static GAME_TEXT KEY_WEAPONS[] = "weapons";
182 static GAME_TEXT KEY_FAVORITE_WEAPONS[] = "favorite weapons";
183 static GAME_TEXT KEY_ARMORS[] = "armors";
184 static GAME_TEXT KEY_MISSILES[] = "missiles";
185 static GAME_TEXT KEY_DEVICES[] = "magical devices";
186 static GAME_TEXT KEY_LIGHTS[] = "lights";
187 static GAME_TEXT KEY_JUNKS[] = "junks";
188 static GAME_TEXT KEY_CORPSES[] = "corpses or skeletons";
189 static GAME_TEXT KEY_SPELLBOOKS[] = "spellbooks";
190 static GAME_TEXT KEY_HAFTED[] = "hafted weapons";
191 static GAME_TEXT KEY_SHIELDS[] = "shields";
192 static GAME_TEXT KEY_BOWS[] = "bows";
193 static GAME_TEXT KEY_RINGS[] = "rings";
194 static GAME_TEXT KEY_AMULETS[] = "amulets";
195 static GAME_TEXT KEY_SUITS[] = "suits";
196 static GAME_TEXT KEY_CLOAKS[] = "cloaks";
197 static GAME_TEXT KEY_HELMS[] = "helms";
198 static GAME_TEXT KEY_GLOVES[] = "gloves";
199 static GAME_TEXT KEY_BOOTS[] = "boots";
200
201 #endif /* JP */
202
203 #define MAX_AUTOPICK_DEFAULT 200
204
205 #define PT_DEFAULT 0
206 #define PT_WITH_PNAME 1
207
208 #define MAX_YANK MAX_LINELEN
209 #define MAX_LINES 3000
210
211 #define MARK_MARK     0x01
212 #define MARK_BY_SHIFT 0x02
213
214 #define LSTAT_BYPASS        0x01
215 #define LSTAT_EXPRESSION    0x02
216 #define LSTAT_AUTOREGISTER  0x04
217
218 #define QUIT_WITHOUT_SAVE 1
219 #define QUIT_AND_SAVE     2
220
221 /*
222  * Dirty flag for text editor
223  */
224 #define DIRTY_ALL           0x0001
225 #define DIRTY_MODE          0x0004
226 #define DIRTY_SCREEN        0x0008
227 #define DIRTY_NOT_FOUND     0x0010
228 #define DIRTY_NO_SEARCH     0x0020
229 #define DIRTY_EXPRESSION    0x0040
230 #define DIRTY_SKIP_INACTIVE 0x0080
231 #define DIRTY_INACTIVE      0x0100
232
233 #define DESCRIPT_HGT 3
234
235 #define MATCH_KEY(KEY) (!strncmp(ptr, KEY, sizeof(KEY)-1)\
236      ? (ptr += sizeof(KEY)-1, (' '==*ptr) ? ptr++ : 0, TRUE) : FALSE)
237 #define MATCH_KEY2(KEY) (!strncmp(ptr, KEY, sizeof(KEY)-1)\
238      ? (prev_ptr = ptr, ptr += sizeof(KEY)-1, (' '==*ptr) ? ptr++ : 0, TRUE) : FALSE)
239
240 #ifdef JP
241 #define ADD_KEY(KEY) strcat(ptr, KEY)
242 #else
243 #define ADD_KEY(KEY) (strcat(ptr, KEY), strcat(ptr, " "))
244 #endif
245 #define ADD_KEY2(KEY) strcat(ptr, KEY)
246
247 #define ADD_FLG(FLG) (entry->flag[FLG / 32] |= (1L << (FLG % 32)))
248 #define REM_FLG(FLG) (entry->flag[FLG / 32] &= ~(1L << (FLG % 32)))
249 #define ADD_FLG_NOUN(FLG) (ADD_FLG(FLG), prev_flg = FLG)
250 #define IS_FLG(FLG) (entry->flag[FLG / 32] & (1L << (FLG % 32)))
251
252 #ifdef JP
253 static char kanji_colon[] = ":";
254 #endif
255
256 /*
257  * 自動拾い/破壊設定のリストに関する変数 / List for auto-picker/destroyer entries
258  */
259 int max_autopick = 0; /*!< 現在登録している自動拾い/破壊設定の数 */
260 int max_max_autopick = 0; /*!< 自動拾い/破壊設定の限界数 */
261 autopick_type *autopick_list = NULL; /*!< 自動拾い/破壊設定構造体のポインタ配列 */
262
263 /*
264  * Automatically destroy an item if it is to be destroyed
265  *
266  * When always_pickup is 'yes', we disable auto-destroyer function of
267  * auto-picker/destroyer, and do only easy-auto-destroyer.
268  */
269 static object_type autopick_last_destroyed_object;
270
271 /*
272  * Struct for yank buffer
273  */
274 typedef struct chain_str {
275         struct chain_str *next;
276         char s[1];
277 } chain_str_type;
278
279 /*
280  * Data struct for text editor
281  */
282 typedef struct {
283         int wid, hgt;
284         int cx, cy;
285         int upper, left;
286         int old_wid, old_hgt;
287         int old_cy;
288         int old_upper, old_left;
289         int mx, my;
290         byte mark;
291
292         object_type *search_o_ptr;
293         concptr search_str;
294         concptr last_destroyed;
295
296         chain_str_type *yank;
297         bool yank_eol;
298
299         concptr *lines_list;
300         byte states[MAX_LINES];
301
302         u16b dirty_flags;
303         int dirty_line;
304         int filename_mode;
305         int old_com_id;
306
307         bool changed;
308 } text_body_type;
309
310 /*
311  * Editor command id's
312  */
313 #define EC_QUIT            1
314 #define EC_SAVEQUIT        2
315 #define EC_REVERT              3
316 #define EC_HELP            4
317 #define EC_RETURN              5
318 #define EC_LEFT                6 
319 #define EC_DOWN                7 
320 #define EC_UP                  8 
321 #define EC_RIGHT               9 
322 #define EC_BOL                 10
323 #define EC_EOL                 11
324 #define EC_PGUP                12
325 #define EC_PGDOWN              13
326 #define EC_TOP                 14
327 #define EC_BOTTOM              15
328 #define EC_CUT                 16
329 #define EC_COPY                17
330 #define EC_PASTE               18
331 #define EC_BLOCK               19
332 #define EC_KILL_LINE           20
333 #define EC_DELETE_CHAR         21
334 #define EC_BACKSPACE           22
335 #define EC_SEARCH_STR          23
336 #define EC_SEARCH_FORW         24
337 #define EC_SEARCH_BACK         25
338 #define EC_SEARCH_OBJ          26
339 #define EC_SEARCH_DESTROYED    27
340 #define EC_INSERT_OBJECT       28
341 #define EC_INSERT_DESTROYED    29
342 #define EC_INSERT_BLOCK        30
343 #define EC_INSERT_MACRO        31
344 #define EC_INSERT_KEYMAP       32
345 #define EC_CL_AUTOPICK         33
346 #define EC_CL_DESTROY          34
347 #define EC_CL_LEAVE            35
348 #define EC_CL_QUERY            36
349 #define EC_CL_NO_DISP          37
350 #define EC_OK_COLLECTING       38
351 #define EC_IK_UNAWARE          39
352 #define EC_IK_UNIDENTIFIED     40
353 #define EC_IK_IDENTIFIED       41
354 #define EC_IK_STAR_IDENTIFIED  42
355 #define EC_OK_BOOSTED          43
356 #define EC_OK_MORE_DICE        44
357 #define EC_OK_MORE_BONUS       45
358 #define EC_OK_WORTHLESS        46
359 #define EC_OK_ARTIFACT         47
360 #define EC_OK_EGO              48
361 #define EC_OK_GOOD             49
362 #define EC_OK_NAMELESS         50
363 #define EC_OK_AVERAGE          51
364 #define EC_OK_RARE             52       
365 #define EC_OK_COMMON           53
366 #define EC_OK_WANTED           54
367 #define EC_OK_UNIQUE           55
368 #define EC_OK_HUMAN            56
369 #define EC_OK_UNREADABLE       57
370 #define EC_OK_REALM1           58
371 #define EC_OK_REALM2           59
372 #define EC_OK_FIRST            60
373 #define EC_OK_SECOND           61
374 #define EC_OK_THIRD            62
375 #define EC_OK_FOURTH           63
376 #define EC_KK_WEAPONS          64
377 #define EC_KK_FAVORITE_WEAPONS 65
378 #define EC_KK_ARMORS           66
379 #define EC_KK_MISSILES         67
380 #define EC_KK_DEVICES          68
381 #define EC_KK_LIGHTS           69
382 #define EC_KK_JUNKS            70
383 #define EC_KK_CORPSES          71
384 #define EC_KK_SPELLBOOKS       72
385 #define EC_KK_SHIELDS          73
386 #define EC_KK_BOWS             74
387 #define EC_KK_RINGS            75
388 #define EC_KK_AMULETS          76
389 #define EC_KK_SUITS            77
390 #define EC_KK_CLOAKS           78
391 #define EC_KK_HELMS            79
392 #define EC_KK_GLOVES           80
393 #define EC_KK_BOOTS            81
394
395
396  /* Manu names */
397 #ifdef JP
398
399 static GAME_TEXT MN_QUIT[] = "セーブ無しで終了";
400 static GAME_TEXT MN_SAVEQUIT[] = "セーブして終了";
401 static GAME_TEXT MN_REVERT[] = "全ての変更を破棄";
402 static GAME_TEXT MN_HELP[] = "ヘルプ";
403
404 static GAME_TEXT MN_MOVE[] = "カーソル移動";
405 static GAME_TEXT MN_LEFT[] = "左          (←矢印キー)";
406 static GAME_TEXT MN_DOWN[] = "下          (↓矢印キー)";
407 static GAME_TEXT MN_UP[] = "上          (↑矢印キー)";
408 static GAME_TEXT MN_RIGHT[] = "右          (→矢印キー)";
409 static GAME_TEXT MN_BOL[] = "行の先頭";
410 static GAME_TEXT MN_EOL[] = "行の終端";
411 static GAME_TEXT MN_PGUP[] = "上のページ  (PageUpキー)";
412 static GAME_TEXT MN_PGDOWN[] = "下のページ  (PageDownキー)";
413 static GAME_TEXT MN_TOP[] = "1行目へ移動 (Homeキー)";
414 static GAME_TEXT MN_BOTTOM[] = "最下行へ移動(Endキー)";
415
416 static GAME_TEXT MN_EDIT[] = "編集";
417 static GAME_TEXT MN_CUT[] = "カット";
418 static GAME_TEXT MN_COPY[] = "コピー";
419 static GAME_TEXT MN_PASTE[] = "ペースト";
420 static GAME_TEXT MN_BLOCK[] = "選択範囲の指定";
421 static GAME_TEXT MN_KILL_LINE[] = "行の残りを削除";
422 static GAME_TEXT MN_DELETE_CHAR[] = "1文字削除";
423 static GAME_TEXT MN_BACKSPACE[] = "バックスペース";
424 static GAME_TEXT MN_RETURN[] = "改行";
425
426 static GAME_TEXT MN_SEARCH[] = "検索";
427 static GAME_TEXT MN_SEARCH_STR[] = "文字列で検索";
428 static GAME_TEXT MN_SEARCH_FORW[] = "前方へ再検索";
429 static GAME_TEXT MN_SEARCH_BACK[] = "後方へ再検索";
430 static GAME_TEXT MN_SEARCH_OBJ[] = "アイテムを選択して検索";
431 static GAME_TEXT MN_SEARCH_DESTROYED[] = "自動破壊されたアイテムで検索";
432
433 static GAME_TEXT MN_INSERT[] = "色々挿入";
434 static GAME_TEXT MN_INSERT_OBJECT[] = "選択したアイテムの名前を挿入";
435 static GAME_TEXT MN_INSERT_DESTROYED[] = "自動破壊されたアイテムの名前を挿入";
436 static GAME_TEXT MN_INSERT_BLOCK[] = "条件分岐ブロックの例を挿入";
437 static GAME_TEXT MN_INSERT_MACRO[] = "マクロ定義を挿入";
438 static GAME_TEXT MN_INSERT_KEYMAP[] = "キーマップ定義を挿入";
439
440 static GAME_TEXT MN_COMMAND_LETTER[] = "拾い/破壊/放置の選択";
441 static GAME_TEXT MN_CL_AUTOPICK[] = "「 」 (自動拾い)";
442 static GAME_TEXT MN_CL_DESTROY[] = "「!」 (自動破壊)";
443 static GAME_TEXT MN_CL_LEAVE[] = "「~」 (放置)";
444 static GAME_TEXT MN_CL_QUERY[] = "「;」 (確認して拾う)";
445 static GAME_TEXT MN_CL_NO_DISP[] = "「(」 (マップコマンドで表示しない)";
446
447 static GAME_TEXT MN_ADJECTIVE_GEN[] = "形容詞(一般)の選択";
448 static GAME_TEXT MN_RARE[] = "レアな (装備)";
449 static GAME_TEXT MN_COMMON[] = "ありふれた (装備)";
450
451 static GAME_TEXT MN_ADJECTIVE_SPECIAL[] = "形容詞(特殊)の選択";
452 static GAME_TEXT MN_BOOSTED[] = "ダイス目の違う (武器)";
453 static GAME_TEXT MN_MORE_DICE[] = "ダイス目 # 以上の (武器)";
454 static GAME_TEXT MN_MORE_BONUS[] = "修正値 # 以上の (指輪等)";
455 static GAME_TEXT MN_WANTED[] = "賞金首の (死体)";
456 static GAME_TEXT MN_UNIQUE[] = "ユニーク・モンスターの (死体)";
457 static GAME_TEXT MN_HUMAN[] = "人間の (死体)";
458 static GAME_TEXT MN_UNREADABLE[] = "読めない (魔法書)";
459 static GAME_TEXT MN_REALM1[] = "第一領域の (魔法書)";
460 static GAME_TEXT MN_REALM2[] = "第二領域の (魔法書)";
461 static GAME_TEXT MN_FIRST[] = "1冊目の (魔法書)";
462 static GAME_TEXT MN_SECOND[] = "2冊目の (魔法書)";
463 static GAME_TEXT MN_THIRD[] = "3冊目の (魔法書)";
464 static GAME_TEXT MN_FOURTH[] = "4冊目の (魔法書)";
465
466 static GAME_TEXT MN_NOUN[] = "名詞の選択";
467
468 #else
469
470 static GAME_TEXT MN_QUIT[] = "Quit without save";
471 static GAME_TEXT MN_SAVEQUIT[] = "Save & Quit";
472 static GAME_TEXT MN_REVERT[] = "Revert all changes";
473 static GAME_TEXT MN_HELP[] = "Help";
474
475 static GAME_TEXT MN_MOVE[] = "Move cursor";
476 static GAME_TEXT MN_LEFT[] = "Left     (Left Arrow key)";
477 static GAME_TEXT MN_DOWN[] = "Down     (Down Arrow key)";
478 static GAME_TEXT MN_UP[] = "Up       (Up Arrow key)";
479 static GAME_TEXT MN_RIGHT[] = "Right    (Right Arrow key)";
480 static GAME_TEXT MN_BOL[] = "Beggining of line";
481 static GAME_TEXT MN_EOL[] = "End of line";
482 static GAME_TEXT MN_PGUP[] = "Page up  (PageUp key)";
483 static GAME_TEXT MN_PGDOWN[] = "Page down(PageDown key)";
484 static GAME_TEXT MN_TOP[] = "Top      (Home key)";
485 static GAME_TEXT MN_BOTTOM[] = "Bottom   (End key)";
486
487 static GAME_TEXT MN_EDIT[] = "Edit";
488 static GAME_TEXT MN_CUT[] = "Cut";
489 static GAME_TEXT MN_COPY[] = "Copy";
490 static GAME_TEXT MN_PASTE[] = "Paste";
491 static GAME_TEXT MN_BLOCK[] = "Select block";
492 static GAME_TEXT MN_KILL_LINE[] = "Kill rest of line";
493 static GAME_TEXT MN_DELETE_CHAR[] = "Delete character";
494 static GAME_TEXT MN_BACKSPACE[] = "Backspace";
495 static GAME_TEXT MN_RETURN[] = "Return";
496
497 static GAME_TEXT MN_SEARCH[] = "Search";
498 static GAME_TEXT MN_SEARCH_STR[] = "Search by string";
499 static GAME_TEXT MN_SEARCH_FORW[] = "Search forward";
500 static GAME_TEXT MN_SEARCH_BACK[] = "Search backward";
501 static GAME_TEXT MN_SEARCH_OBJ[] = "Search by inventory list object";
502 static GAME_TEXT MN_SEARCH_DESTROYED[] = "Search by destroyed object";
503
504 static GAME_TEXT MN_INSERT[] = "Insert...";
505 static GAME_TEXT MN_INSERT_OBJECT[] = "Insert name of choosen object";
506 static GAME_TEXT MN_INSERT_DESTROYED[] = "Insert name of destroyed object";
507 static GAME_TEXT MN_INSERT_BLOCK[] = "Insert conditional block";
508 static GAME_TEXT MN_INSERT_MACRO[] = "Insert a macro definition";
509 static GAME_TEXT MN_INSERT_KEYMAP[] = "Insert a keymap definition";
510
511 static GAME_TEXT MN_COMMAND_LETTER[] = "Command letter";
512 static GAME_TEXT MN_CL_AUTOPICK[] = "' ' (Auto pick)";
513 static GAME_TEXT MN_CL_DESTROY[] = "'!' (Auto destroy)";
514 static GAME_TEXT MN_CL_LEAVE[] = "'~' (Leave it on the floor)";
515 static GAME_TEXT MN_CL_QUERY[] = "';' (Query to pick up)";
516 static GAME_TEXT MN_CL_NO_DISP[] = "'(' (No display on the large map)";
517
518 static GAME_TEXT MN_ADJECTIVE_GEN[] = "Adjective (general)";
519 static GAME_TEXT MN_RARE[] = "rare (equipments)";
520 static GAME_TEXT MN_COMMON[] = "common (equipments)";
521
522 static GAME_TEXT MN_ADJECTIVE_SPECIAL[] = "Adjective (special)";
523 static GAME_TEXT MN_BOOSTED[] = "dice boosted (weapons)";
524 static GAME_TEXT MN_MORE_DICE[] = "more than # dice (weapons)";
525 static GAME_TEXT MN_MORE_BONUS[] = "more bonus than # (rings etc.)";
526 static GAME_TEXT MN_WANTED[] = "wanted (corpse)";
527 static GAME_TEXT MN_UNIQUE[] = "unique (corpse)";
528 static GAME_TEXT MN_HUMAN[] = "human (corpse)";
529 static GAME_TEXT MN_UNREADABLE[] = "unreadable (spellbooks)";
530 static GAME_TEXT MN_REALM1[] = "realm1 (spellbooks)";
531 static GAME_TEXT MN_REALM2[] = "realm2 (spellbooks)";
532 static GAME_TEXT MN_FIRST[] = "first (spellbooks)";
533 static GAME_TEXT MN_SECOND[] = "second (spellbooks)";
534 static GAME_TEXT MN_THIRD[] = "third (spellbooks)";
535 static GAME_TEXT MN_FOURTH[] = "fourth (spellbooks)";
536
537 static GAME_TEXT MN_NOUN[] = "Keywords (noun)";
538
539 #endif
540
541
542 typedef struct {
543         concptr name;
544         int level;
545         int key;
546         int com_id;
547 } command_menu_type;
548
549
550 command_menu_type menu_data[] =
551 {
552         {MN_HELP, 0, -1, EC_HELP},
553         {MN_QUIT, 0, KTRL('q'), EC_QUIT},
554         {MN_SAVEQUIT, 0, KTRL('w'), EC_SAVEQUIT},
555         {MN_REVERT, 0, KTRL('z'), EC_REVERT},
556
557         {MN_EDIT, 0, -1, -1},
558         {MN_CUT, 1, KTRL('x'), EC_CUT},
559         {MN_COPY, 1, KTRL('c'), EC_COPY},
560         {MN_PASTE, 1, KTRL('v'), EC_PASTE},
561         {MN_BLOCK, 1, KTRL('g'), EC_BLOCK},
562         {MN_KILL_LINE, 1, KTRL('k'), EC_KILL_LINE},
563         {MN_DELETE_CHAR, 1, KTRL('d'), EC_DELETE_CHAR},
564         {MN_BACKSPACE, 1, KTRL('h'), EC_BACKSPACE},
565         {MN_RETURN, 1, KTRL('j'), EC_RETURN},
566         {MN_RETURN, 1, KTRL('m'), EC_RETURN},
567
568         {MN_SEARCH, 0, -1, -1},
569         {MN_SEARCH_STR, 1, KTRL('s'), EC_SEARCH_STR},
570         {MN_SEARCH_FORW, 1, -1, EC_SEARCH_FORW},
571         {MN_SEARCH_BACK, 1, KTRL('r'), EC_SEARCH_BACK},
572         {MN_SEARCH_OBJ, 1, KTRL('y'), EC_SEARCH_OBJ},
573         {MN_SEARCH_DESTROYED, 1, -1, EC_SEARCH_DESTROYED},
574
575         {MN_MOVE, 0, -1, -1},
576         {MN_LEFT, 1, KTRL('b'), EC_LEFT},
577         {MN_DOWN, 1, KTRL('n'), EC_DOWN},
578         {MN_UP, 1, KTRL('p'), EC_UP},
579         {MN_RIGHT, 1, KTRL('f'), EC_RIGHT},
580         {MN_BOL, 1, KTRL('a'), EC_BOL},
581         {MN_EOL, 1, KTRL('e'), EC_EOL},
582         {MN_PGUP, 1, KTRL('o'), EC_PGUP},
583         {MN_PGDOWN, 1, KTRL('l'), EC_PGDOWN},
584         {MN_TOP, 1, KTRL('t'), EC_TOP},
585         {MN_BOTTOM, 1, KTRL('u'), EC_BOTTOM},
586
587         {MN_INSERT, 0, -1, -1},
588         {MN_INSERT_OBJECT, 1, KTRL('i'), EC_INSERT_OBJECT},
589         {MN_INSERT_DESTROYED, 1, -1, EC_INSERT_DESTROYED},
590         {MN_INSERT_BLOCK, 1, -1, EC_INSERT_BLOCK},
591         {MN_INSERT_MACRO, 1, -1, EC_INSERT_MACRO},
592         {MN_INSERT_KEYMAP, 1, -1, EC_INSERT_KEYMAP},
593
594         {MN_ADJECTIVE_GEN, 0, -1, -1},
595         {KEY_UNAWARE, 1, -1, EC_IK_UNAWARE},
596         {KEY_UNIDENTIFIED, 1, -1, EC_IK_UNIDENTIFIED},
597         {KEY_IDENTIFIED, 1, -1, EC_IK_IDENTIFIED},
598         {KEY_STAR_IDENTIFIED, 1, -1, EC_IK_STAR_IDENTIFIED},
599         {KEY_COLLECTING, 1, -1, EC_OK_COLLECTING},
600         {KEY_ARTIFACT, 1, -1, EC_OK_ARTIFACT},
601         {KEY_EGO, 1, -1, EC_OK_EGO},
602         {KEY_GOOD, 1, -1, EC_OK_GOOD},
603         {KEY_NAMELESS, 1, -1, EC_OK_NAMELESS},
604         {KEY_AVERAGE, 1, -1, EC_OK_AVERAGE},
605         {KEY_WORTHLESS, 1, -1, EC_OK_WORTHLESS},
606         {MN_RARE, 1, -1, EC_OK_RARE},
607         {MN_COMMON, 1, -1, EC_OK_COMMON},
608
609         {MN_ADJECTIVE_SPECIAL, 0, -1, -1},
610         {MN_BOOSTED, 1, -1, EC_OK_BOOSTED},
611         {MN_MORE_DICE, 1, -1, EC_OK_MORE_DICE},
612         {MN_MORE_BONUS, 1, -1, EC_OK_MORE_BONUS},
613         {MN_WANTED, 1, -1, EC_OK_WANTED},
614         {MN_UNIQUE, 1, -1, EC_OK_UNIQUE},
615         {MN_HUMAN, 1, -1, EC_OK_HUMAN},
616         {MN_UNREADABLE, 1, -1, EC_OK_UNREADABLE},
617         {MN_REALM1, 1, -1, EC_OK_REALM1},
618         {MN_REALM2, 1, -1, EC_OK_REALM2},
619         {MN_FIRST, 1, -1, EC_OK_FIRST},
620         {MN_SECOND, 1, -1, EC_OK_SECOND},
621         {MN_THIRD, 1, -1, EC_OK_THIRD},
622         {MN_FOURTH, 1, -1, EC_OK_FOURTH},
623
624         {MN_NOUN, 0, -1, -1},
625         {KEY_WEAPONS, 1, -1, EC_KK_WEAPONS},
626         {KEY_FAVORITE_WEAPONS, 1, -1, EC_KK_FAVORITE_WEAPONS},
627         {KEY_ARMORS, 1, -1, EC_KK_ARMORS},
628         {KEY_MISSILES, 1, -1, EC_KK_MISSILES},
629         {KEY_DEVICES, 1, -1, EC_KK_DEVICES},
630         {KEY_LIGHTS, 1, -1, EC_KK_LIGHTS},
631         {KEY_JUNKS, 1, -1, EC_KK_JUNKS},
632         {KEY_CORPSES, 1, -1, EC_KK_CORPSES},
633         {KEY_SPELLBOOKS, 1, -1, EC_KK_SPELLBOOKS},
634         {KEY_SHIELDS, 1, -1, EC_KK_SHIELDS},
635         {KEY_BOWS, 1, -1, EC_KK_BOWS},
636         {KEY_RINGS, 1, -1, EC_KK_RINGS},
637         {KEY_AMULETS, 1, -1, EC_KK_AMULETS},
638         {KEY_SUITS, 1, -1, EC_KK_SUITS},
639         {KEY_CLOAKS, 1, -1, EC_KK_CLOAKS},
640         {KEY_HELMS, 1, -1, EC_KK_HELMS},
641         {KEY_GLOVES, 1, -1, EC_KK_GLOVES},
642         {KEY_BOOTS, 1, -1, EC_KK_BOOTS},
643
644         {MN_COMMAND_LETTER, 0, -1, -1},
645         {MN_CL_AUTOPICK, 1, -1, EC_CL_AUTOPICK},
646         {MN_CL_DESTROY, 1, -1, EC_CL_DESTROY},
647         {MN_CL_LEAVE, 1, -1, EC_CL_LEAVE},
648         {MN_CL_QUERY, 1, -1, EC_CL_QUERY},
649         {MN_CL_NO_DISP, 1, -1, EC_CL_NO_DISP},
650
651         {MN_DELETE_CHAR, -1, 0x7F, EC_DELETE_CHAR},
652
653         {NULL, -1, -1, 0}
654 };
655
656 /*
657  * A function to create new entry
658  */
659 static bool autopick_new_entry(autopick_type *entry, concptr str, bool allow_default)
660 {
661         if (str[0] && str[1] == ':') switch (str[0])
662         {
663         case '?': case '%':
664         case 'A': case 'P': case 'C':
665                 return FALSE;
666         }
667
668         entry->flag[0] = entry->flag[1] = 0L;
669         entry->dice = 0;
670         entry->bonus = 0;
671
672         byte act = DO_AUTOPICK | DO_DISPLAY;
673         while (TRUE)
674         {
675                 if ((act & DO_AUTOPICK) && *str == '!')
676                 {
677                         act &= ~DO_AUTOPICK;
678                         act |= DO_AUTODESTROY;
679                         str++;
680                         continue;
681                 }
682
683                 if ((act & DO_AUTOPICK) && *str == '~')
684                 {
685                         act &= ~DO_AUTOPICK;
686                         act |= DONT_AUTOPICK;
687                         str++;
688                         continue;
689                 }
690
691                 if ((act & DO_AUTOPICK) && *str == ';')
692                 {
693                         act &= ~DO_AUTOPICK;
694                         act |= DO_QUERY_AUTOPICK;
695                         str++;
696                         continue;
697                 }
698
699                 if ((act & DO_DISPLAY) && *str == '(')
700                 {
701                         act &= ~DO_DISPLAY;
702                         str++;
703                         continue;
704                 }
705
706                 break;
707         }
708
709         /* don't mind upper or lower case */
710         concptr insc = NULL;
711         char buf[MAX_LINELEN];
712         int i;
713         for (i = 0; *str; i++)
714         {
715                 char c = *str++;
716 #ifdef JP
717                 if (iskanji(c))
718                 {
719                         buf[i++] = c;
720                         buf[i] = *str++;
721                         continue;
722                 }
723 #endif
724                 /* Auto-inscription? */
725                 if (c == '#')
726                 {
727                         buf[i] = '\0';
728                         insc = str;
729                         break;
730                 }
731
732                 if (isupper(c)) c = (char)tolower(c);
733
734                 buf[i] = c;
735         }
736
737         buf[i] = '\0';
738
739         /* Skip empty line unless allow_default */
740         if (!allow_default && *buf == 0) return FALSE;
741
742         /* Skip comment line */
743         if (*buf == 0 && insc) return FALSE;
744
745         concptr prev_ptr, ptr;
746         ptr = prev_ptr = buf;
747         concptr old_ptr = NULL;
748
749         while (old_ptr != ptr)
750         {
751                 /* Save current location */
752                 old_ptr = ptr;
753
754                 if (MATCH_KEY(KEY_ALL)) ADD_FLG(FLG_ALL);
755                 if (MATCH_KEY(KEY_COLLECTING)) ADD_FLG(FLG_COLLECTING);
756                 if (MATCH_KEY(KEY_UNAWARE)) ADD_FLG(FLG_UNAWARE);
757                 if (MATCH_KEY(KEY_UNIDENTIFIED)) ADD_FLG(FLG_UNIDENTIFIED);
758                 if (MATCH_KEY(KEY_IDENTIFIED)) ADD_FLG(FLG_IDENTIFIED);
759                 if (MATCH_KEY(KEY_STAR_IDENTIFIED)) ADD_FLG(FLG_STAR_IDENTIFIED);
760                 if (MATCH_KEY(KEY_BOOSTED)) ADD_FLG(FLG_BOOSTED);
761
762                 /*** Weapons whose dd*ds is more than nn ***/
763                 if (MATCH_KEY2(KEY_MORE_THAN))
764                 {
765                         int k = 0;
766                         entry->dice = 0;
767
768                         /* Drop leading spaces */
769                         while (' ' == *ptr) ptr++;
770
771                         /* Read number */
772                         while ('0' <= *ptr && *ptr <= '9')
773                         {
774                                 entry->dice = 10 * entry->dice + (*ptr - '0');
775                                 ptr++;
776                                 k++;
777                         }
778
779                         if (k > 0 && k <= 2)
780                         {
781                                 (void)MATCH_KEY(KEY_DICE);
782                                 ADD_FLG(FLG_MORE_DICE);
783                         }
784                         else
785                                 ptr = prev_ptr;
786                 }
787
788                 /*** Items whose magical bonus is more than n ***/
789                 if (MATCH_KEY2(KEY_MORE_BONUS))
790                 {
791                         int k = 0;
792                         entry->bonus = 0;
793
794                         /* Drop leading spaces */
795                         while (' ' == *ptr) ptr++;
796
797                         /* Read number */
798                         while ('0' <= *ptr && *ptr <= '9')
799                         {
800                                 entry->bonus = 10 * entry->bonus + (*ptr - '0');
801                                 ptr++;
802                                 k++;
803                         }
804
805                         if (k > 0 && k <= 2)
806                         {
807 #ifdef JP
808                                 (void)MATCH_KEY(KEY_MORE_BONUS2);
809 #else
810                                 if (' ' == *ptr) ptr++;
811 #endif
812                                 ADD_FLG(FLG_MORE_BONUS);
813                         }
814                         else
815                                 ptr = prev_ptr;
816                 }
817
818                 if (MATCH_KEY(KEY_WORTHLESS)) ADD_FLG(FLG_WORTHLESS);
819                 if (MATCH_KEY(KEY_EGO)) ADD_FLG(FLG_EGO);
820                 if (MATCH_KEY(KEY_GOOD)) ADD_FLG(FLG_GOOD);
821                 if (MATCH_KEY(KEY_NAMELESS)) ADD_FLG(FLG_NAMELESS);
822                 if (MATCH_KEY(KEY_AVERAGE)) ADD_FLG(FLG_AVERAGE);
823                 if (MATCH_KEY(KEY_RARE)) ADD_FLG(FLG_RARE);
824                 if (MATCH_KEY(KEY_COMMON)) ADD_FLG(FLG_COMMON);
825                 if (MATCH_KEY(KEY_WANTED)) ADD_FLG(FLG_WANTED);
826                 if (MATCH_KEY(KEY_UNIQUE)) ADD_FLG(FLG_UNIQUE);
827                 if (MATCH_KEY(KEY_HUMAN)) ADD_FLG(FLG_HUMAN);
828                 if (MATCH_KEY(KEY_UNREADABLE)) ADD_FLG(FLG_UNREADABLE);
829                 if (MATCH_KEY(KEY_REALM1)) ADD_FLG(FLG_REALM1);
830                 if (MATCH_KEY(KEY_REALM2)) ADD_FLG(FLG_REALM2);
831                 if (MATCH_KEY(KEY_FIRST)) ADD_FLG(FLG_FIRST);
832                 if (MATCH_KEY(KEY_SECOND)) ADD_FLG(FLG_SECOND);
833                 if (MATCH_KEY(KEY_THIRD)) ADD_FLG(FLG_THIRD);
834                 if (MATCH_KEY(KEY_FOURTH)) ADD_FLG(FLG_FOURTH);
835         }
836
837         /* Not yet found any noun */
838         int prev_flg = -1;
839
840         if (MATCH_KEY2(KEY_ARTIFACT)) ADD_FLG_NOUN(FLG_ARTIFACT);
841
842         if (MATCH_KEY2(KEY_ITEMS)) ADD_FLG_NOUN(FLG_ITEMS);
843         else if (MATCH_KEY2(KEY_WEAPONS)) ADD_FLG_NOUN(FLG_WEAPONS);
844         else if (MATCH_KEY2(KEY_FAVORITE_WEAPONS)) ADD_FLG_NOUN(FLG_FAVORITE_WEAPONS);
845         else if (MATCH_KEY2(KEY_ARMORS)) ADD_FLG_NOUN(FLG_ARMORS);
846         else if (MATCH_KEY2(KEY_MISSILES)) ADD_FLG_NOUN(FLG_MISSILES);
847         else if (MATCH_KEY2(KEY_DEVICES)) ADD_FLG_NOUN(FLG_DEVICES);
848         else if (MATCH_KEY2(KEY_LIGHTS)) ADD_FLG_NOUN(FLG_LIGHTS);
849         else if (MATCH_KEY2(KEY_JUNKS)) ADD_FLG_NOUN(FLG_JUNKS);
850         else if (MATCH_KEY2(KEY_CORPSES)) ADD_FLG_NOUN(FLG_CORPSES);
851         else if (MATCH_KEY2(KEY_SPELLBOOKS)) ADD_FLG_NOUN(FLG_SPELLBOOKS);
852         else if (MATCH_KEY2(KEY_HAFTED)) ADD_FLG_NOUN(FLG_HAFTED);
853         else if (MATCH_KEY2(KEY_SHIELDS)) ADD_FLG_NOUN(FLG_SHIELDS);
854         else if (MATCH_KEY2(KEY_BOWS)) ADD_FLG_NOUN(FLG_BOWS);
855         else if (MATCH_KEY2(KEY_RINGS)) ADD_FLG_NOUN(FLG_RINGS);
856         else if (MATCH_KEY2(KEY_AMULETS)) ADD_FLG_NOUN(FLG_AMULETS);
857         else if (MATCH_KEY2(KEY_SUITS)) ADD_FLG_NOUN(FLG_SUITS);
858         else if (MATCH_KEY2(KEY_CLOAKS)) ADD_FLG_NOUN(FLG_CLOAKS);
859         else if (MATCH_KEY2(KEY_HELMS)) ADD_FLG_NOUN(FLG_HELMS);
860         else if (MATCH_KEY2(KEY_GLOVES)) ADD_FLG_NOUN(FLG_GLOVES);
861         else if (MATCH_KEY2(KEY_BOOTS)) ADD_FLG_NOUN(FLG_BOOTS);
862
863         /* Last 'keyword' must be at the correct location */
864         if (*ptr == ':')
865                 ptr++;
866 #ifdef JP
867         else if (ptr[0] == kanji_colon[0] && ptr[1] == kanji_colon[1])
868                 ptr += 2;
869 #endif
870         else if (*ptr == '\0')
871         {
872                 /* There was no noun */
873                 if (prev_flg == -1)
874
875                         /* Add extra word "items" */
876                         ADD_FLG_NOUN(FLG_ITEMS);
877         }
878         else
879         {
880                 /* Noun type? */
881                 if (prev_flg != -1)
882                 {
883                         /* A noun type keyword didn't end correctly */
884                         entry->flag[prev_flg / 32] &= ~(1L << (prev_flg % 32));
885                         ptr = prev_ptr;
886                 }
887         }
888
889         /* Save this auto-picker entry line */
890         entry->name = string_make(ptr);
891         entry->action = act;
892         entry->insc = string_make(insc);
893
894         return TRUE;
895 }
896
897
898 /*
899  * Get auto-picker entry from o_ptr.
900  */
901 static void autopick_entry_from_object(player_type *player_ptr, autopick_type *entry, object_type *o_ptr)
902 {
903         /* Assume that object name is to be added */
904         bool name = TRUE;
905
906 #ifdef JP
907         /* エゴ銘が邪魔かもしれないので、デフォルトで「^」は付けない */
908         bool bol_mark = FALSE;
909 #else
910         /* We can always use the ^ mark in English */
911         bool bol_mark = TRUE;
912 #endif
913
914         GAME_TEXT name_str[MAX_NLEN];
915
916         /* Initialize name string */
917         name_str[0] = '\0';
918
919         entry->insc = string_make(quark_str(o_ptr->inscription));
920         entry->action = DO_AUTOPICK | DO_DISPLAY;
921         entry->flag[0] = entry->flag[1] = 0L;
922         entry->dice = 0;
923
924         /* Unaware */
925         if (!object_is_aware(o_ptr))
926         {
927                 ADD_FLG(FLG_UNAWARE);
928                 bol_mark = TRUE;
929         }
930
931         /* Not really identified */
932         else if (!object_is_known(o_ptr))
933         {
934                 if (!(o_ptr->ident & IDENT_SENSE))
935                 {
936                         ADD_FLG(FLG_UNIDENTIFIED);
937                         bol_mark = TRUE;
938                 }
939                 else
940                 {
941                         /* Pseudo-identified */
942                         switch (o_ptr->feeling)
943                         {
944                         case FEEL_AVERAGE:
945                         case FEEL_GOOD:
946                                 ADD_FLG(FLG_NAMELESS);
947                                 bol_mark = TRUE;
948                                 break;
949
950                         case FEEL_BROKEN:
951                         case FEEL_CURSED:
952                                 ADD_FLG(FLG_NAMELESS);
953                                 ADD_FLG(FLG_WORTHLESS);
954                                 bol_mark = TRUE;
955                                 break;
956
957                         case FEEL_TERRIBLE:
958                         case FEEL_WORTHLESS:
959                                 ADD_FLG(FLG_WORTHLESS);
960                                 break;
961
962                         case FEEL_EXCELLENT:
963                                 ADD_FLG(FLG_EGO);
964                                 break;
965
966                         case FEEL_UNCURSED:
967                                 /* XXX No appropriate flag */
968                                 /* ADD_FLG(); */
969                                 break;
970
971                         default:
972                                 /* Never reach here */
973                                 break;
974                         }
975                 }
976         }
977
978         /* Identified */
979         else
980         {
981                 /* Ego objects */
982                 if (object_is_ego(o_ptr))
983                 {
984                         if (object_is_weapon_armour_ammo(o_ptr))
985                         {
986                                 /*
987                                  * Base name of ego weapons and armors
988                                  * are almost meaningless.
989                                  * Register the ego type only.
990                                  */
991                                 ego_item_type *e_ptr = &e_info[o_ptr->name2];
992 #ifdef JP
993                                 /* エゴ銘には「^」マークが使える */
994                                 sprintf(name_str, "^%s", e_name + e_ptr->name);
995 #else
996                                 /* We ommit the basename and cannot use the ^ mark */
997                                 strcpy(name_str, e_name + e_ptr->name);
998 #endif
999
1000                                 /* Don't use the object description */
1001                                 name = FALSE;
1002
1003                                 /* Restrict to 'common' equipments */
1004                                 if (!object_is_rare(o_ptr)) ADD_FLG(FLG_COMMON);
1005                         }
1006
1007                         ADD_FLG(FLG_EGO);
1008                 }
1009
1010                 /* Artifact */
1011                 else if (object_is_artifact(o_ptr))
1012                         ADD_FLG(FLG_ARTIFACT);
1013
1014                 /* Non-ego, non-artifact */
1015                 else
1016                 {
1017                         /* Wearable nameless object */
1018                         if (object_is_equipment(o_ptr))
1019                                 ADD_FLG(FLG_NAMELESS);
1020
1021                         bol_mark = TRUE;
1022                 }
1023
1024         }
1025
1026         /* Melee weapon with boosted dice */
1027         if (object_is_melee_weapon(o_ptr))
1028         {
1029                 object_kind *k_ptr = &k_info[o_ptr->k_idx];
1030
1031                 if ((o_ptr->dd != k_ptr->dd) || (o_ptr->ds != k_ptr->ds))
1032                         ADD_FLG(FLG_BOOSTED);
1033         }
1034
1035         /* Wanted monster's corpse */
1036         if (object_is_bounty(o_ptr))
1037         {
1038                 REM_FLG(FLG_WORTHLESS);
1039                 ADD_FLG(FLG_WANTED);
1040         }
1041
1042         if ((o_ptr->tval == TV_CORPSE || o_ptr->tval == TV_STATUE)
1043                 && (r_info[o_ptr->pval].flags1 & RF1_UNIQUE))
1044         {
1045                 ADD_FLG(FLG_UNIQUE);
1046         }
1047
1048         if (o_ptr->tval == TV_CORPSE && my_strchr("pht", r_info[o_ptr->pval].d_char))
1049         {
1050                 ADD_FLG(FLG_HUMAN);
1051         }
1052
1053         if (o_ptr->tval >= TV_LIFE_BOOK &&
1054                 !check_book_realm(player_ptr, o_ptr->tval, o_ptr->sval))
1055         {
1056                 ADD_FLG(FLG_UNREADABLE);
1057                 if (o_ptr->tval != TV_ARCANE_BOOK) name = FALSE;
1058         }
1059
1060         if (REALM1_BOOK == o_ptr->tval &&
1061                 player_ptr->pclass != CLASS_SORCERER &&
1062                 player_ptr->pclass != CLASS_RED_MAGE)
1063         {
1064                 ADD_FLG(FLG_REALM1);
1065                 name = FALSE;
1066         }
1067
1068         if (REALM2_BOOK == o_ptr->tval &&
1069                 player_ptr->pclass != CLASS_SORCERER &&
1070                 player_ptr->pclass != CLASS_RED_MAGE)
1071         {
1072                 ADD_FLG(FLG_REALM2);
1073                 name = FALSE;
1074         }
1075
1076         if (o_ptr->tval >= TV_LIFE_BOOK && 0 == o_ptr->sval)
1077                 ADD_FLG(FLG_FIRST);
1078         if (o_ptr->tval >= TV_LIFE_BOOK && 1 == o_ptr->sval)
1079                 ADD_FLG(FLG_SECOND);
1080         if (o_ptr->tval >= TV_LIFE_BOOK && 2 == o_ptr->sval)
1081                 ADD_FLG(FLG_THIRD);
1082         if (o_ptr->tval >= TV_LIFE_BOOK && 3 == o_ptr->sval)
1083                 ADD_FLG(FLG_FOURTH);
1084
1085         if (object_is_ammo(o_ptr))
1086                 ADD_FLG(FLG_MISSILES);
1087         else if (o_ptr->tval == TV_SCROLL || o_ptr->tval == TV_STAFF
1088                 || o_ptr->tval == TV_WAND || o_ptr->tval == TV_ROD)
1089                 ADD_FLG(FLG_DEVICES);
1090         else if (o_ptr->tval == TV_LITE)
1091                 ADD_FLG(FLG_LIGHTS);
1092         else if (o_ptr->tval == TV_SKELETON || o_ptr->tval == TV_BOTTLE
1093                 || o_ptr->tval == TV_JUNK || o_ptr->tval == TV_STATUE)
1094                 ADD_FLG(FLG_JUNKS);
1095         else if (o_ptr->tval == TV_CORPSE)
1096                 ADD_FLG(FLG_CORPSES);
1097         else if (o_ptr->tval >= TV_LIFE_BOOK)
1098                 ADD_FLG(FLG_SPELLBOOKS);
1099         else if (o_ptr->tval == TV_POLEARM || o_ptr->tval == TV_SWORD
1100                 || o_ptr->tval == TV_DIGGING || o_ptr->tval == TV_HAFTED)
1101                 ADD_FLG(FLG_WEAPONS);
1102         else if (o_ptr->tval == TV_SHIELD)
1103                 ADD_FLG(FLG_SHIELDS);
1104         else if (o_ptr->tval == TV_BOW)
1105                 ADD_FLG(FLG_BOWS);
1106         else if (o_ptr->tval == TV_RING)
1107                 ADD_FLG(FLG_RINGS);
1108         else if (o_ptr->tval == TV_AMULET)
1109                 ADD_FLG(FLG_AMULETS);
1110         else if (o_ptr->tval == TV_DRAG_ARMOR || o_ptr->tval == TV_HARD_ARMOR ||
1111                 o_ptr->tval == TV_SOFT_ARMOR)
1112                 ADD_FLG(FLG_SUITS);
1113         else if (o_ptr->tval == TV_CLOAK)
1114                 ADD_FLG(FLG_CLOAKS);
1115         else if (o_ptr->tval == TV_HELM)
1116                 ADD_FLG(FLG_HELMS);
1117         else if (o_ptr->tval == TV_GLOVES)
1118                 ADD_FLG(FLG_GLOVES);
1119         else if (o_ptr->tval == TV_BOOTS)
1120                 ADD_FLG(FLG_BOOTS);
1121
1122         /* Prepare the object description */
1123         if (!name)
1124         {
1125                 str_tolower(name_str);
1126                 entry->name = string_make(name_str);
1127                 return;
1128         }
1129
1130         GAME_TEXT o_name[MAX_NLEN];
1131         object_desc(o_name, o_ptr, (OD_NO_FLAVOR | OD_OMIT_PREFIX | OD_NO_PLURAL | OD_NAME_ONLY));
1132
1133         /*
1134          * If necessary, add a '^' which indicates the
1135          * beginning of line.
1136          */
1137         sprintf(name_str, "%s%s", bol_mark ? "^" : "", o_name);
1138         str_tolower(name_str);
1139         entry->name = string_make(name_str);
1140 }
1141
1142
1143 /*
1144  * A function to delete entry
1145  */
1146 static void autopick_free_entry(autopick_type *entry)
1147 {
1148         string_free(entry->name);
1149         string_free(entry->insc);
1150         entry->name = NULL;
1151         entry->insc = NULL;
1152 }
1153
1154
1155 /*
1156  * Initialize the autopick
1157  */
1158 static void init_autopick(void)
1159 {
1160         static const char easy_autopick_inscription[] = "(:=g";
1161         autopick_type entry;
1162         int i;
1163
1164         if (!autopick_list)
1165         {
1166                 max_max_autopick = MAX_AUTOPICK_DEFAULT;
1167                 C_MAKE(autopick_list, max_max_autopick, autopick_type);
1168                 max_autopick = 0;
1169         }
1170
1171         /* Clear old entries */
1172         for (i = 0; i < max_autopick; i++)
1173                 autopick_free_entry(&autopick_list[i]);
1174
1175         max_autopick = 0;
1176
1177         /* There is always one entry "=g" */
1178         autopick_new_entry(&entry, easy_autopick_inscription, TRUE);
1179         autopick_list[max_autopick++] = entry;
1180 }
1181
1182
1183 /*
1184  *  Get file name for autopick preference
1185  */
1186 static concptr pickpref_filename(player_type *player_ptr, int filename_mode)
1187 {
1188         static const char namebase[] = _("picktype", "pickpref");
1189
1190         switch (filename_mode)
1191         {
1192         case PT_DEFAULT:
1193                 return format("%s.prf", namebase);
1194
1195         case PT_WITH_PNAME:
1196                 return format("%s-%s.prf", namebase, player_ptr->base_name);
1197
1198         default:
1199                 return NULL;
1200         }
1201 }
1202
1203
1204 /*
1205  * Load an autopick preference file
1206  */
1207 void autopick_load_pref(player_type *player_ptr, bool disp_mes)
1208 {
1209         GAME_TEXT buf[80];
1210
1211         /* Free old entries */
1212         init_autopick();
1213
1214         /* Try a filename with player name */
1215         my_strcpy(buf, pickpref_filename(player_ptr, PT_WITH_PNAME), sizeof(buf));
1216
1217         /* Load the file */
1218         errr err = process_autopick_file(player_ptr, buf);
1219
1220         if (err == 0 && disp_mes)
1221         {
1222                 msg_format(_("%sを読み込みました。", "Loaded '%s'."), buf);
1223         }
1224
1225         /* No file found */
1226         if (err < 0)
1227         {
1228                 /* Use default name */
1229                 my_strcpy(buf, pickpref_filename(player_ptr, PT_DEFAULT), sizeof(buf));
1230
1231                 /* Load the file */
1232                 err = process_autopick_file(player_ptr, buf);
1233
1234                 if (err == 0 && disp_mes)
1235                 {
1236                         /* Success */
1237                         msg_format(_("%sを読み込みました。", "Loaded '%s'."), buf);
1238                 }
1239         }
1240
1241         if (err && disp_mes)
1242         {
1243                 /* Failed */
1244                 msg_print(_("自動拾い設定ファイルの読み込みに失敗しました。", "Failed to reload autopick preference."));
1245         }
1246 }
1247
1248
1249 /*
1250  * Add one line to autopick_list[]
1251  */
1252 static void add_autopick_list(autopick_type *entry)
1253 {
1254         /* There is no enough space to add one line */
1255         if (max_autopick >= max_max_autopick)
1256         {
1257                 int old_max_max_autopick = max_max_autopick;
1258                 autopick_type *old_autopick_list = autopick_list;
1259
1260                 /* Increase size of list */
1261                 max_max_autopick += MAX_AUTOPICK_DEFAULT;
1262
1263                 /* Allocate */
1264                 C_MAKE(autopick_list, max_max_autopick, autopick_type);
1265
1266                 /* Copy from old list to new list */
1267                 (void)C_COPY(autopick_list, old_autopick_list, old_max_max_autopick, autopick_type);
1268
1269                 /* Kill old list */
1270                 C_KILL(old_autopick_list, old_max_max_autopick, autopick_type);
1271         }
1272
1273         /* Add one line */
1274         autopick_list[max_autopick] = *entry;
1275
1276         max_autopick++;
1277 }
1278
1279
1280 /*
1281  *  Process line for auto picker/destroyer.
1282  */
1283 errr process_autopick_file_command(char *buf)
1284 {
1285         autopick_type an_entry, *entry = &an_entry;
1286         int i;
1287
1288         /* Nuke illegal char */
1289         for (i = 0; buf[i]; i++)
1290         {
1291 #ifdef JP
1292                 if (iskanji(buf[i]))
1293                 {
1294                         i++;
1295                         continue;
1296                 }
1297 #endif
1298                 if (iswspace(buf[i]) && buf[i] != ' ')
1299                         break;
1300         }
1301
1302         buf[i] = 0;
1303
1304         if (!autopick_new_entry(entry, buf, FALSE)) return 0;
1305
1306         /* Already has the same entry? */
1307         for (i = 0; i < max_autopick; i++)
1308         {
1309                 if (!strcmp(entry->name, autopick_list[i].name)
1310                         && entry->flag[0] == autopick_list[i].flag[0]
1311                         && entry->flag[1] == autopick_list[i].flag[1]
1312                         && entry->dice == autopick_list[i].dice
1313                         && entry->bonus == autopick_list[i].bonus)
1314                 {
1315                         autopick_free_entry(entry);
1316                         return 0;
1317                 }
1318         }
1319
1320         add_autopick_list(entry);
1321         return 0;
1322 }
1323
1324
1325 /*
1326  * Reconstruct preference line from entry
1327  */
1328 concptr autopick_line_from_entry(autopick_type *entry)
1329 {
1330         char buf[MAX_LINELEN];
1331         *buf = '\0';
1332         if (!(entry->action & DO_DISPLAY)) strcat(buf, "(");
1333         if (entry->action & DO_QUERY_AUTOPICK) strcat(buf, ";");
1334         if (entry->action & DO_AUTODESTROY) strcat(buf, "!");
1335         if (entry->action & DONT_AUTOPICK) strcat(buf, "~");
1336
1337         char *ptr;
1338         ptr = buf;
1339
1340         if (IS_FLG(FLG_ALL)) ADD_KEY(KEY_ALL);
1341         if (IS_FLG(FLG_COLLECTING)) ADD_KEY(KEY_COLLECTING);
1342         if (IS_FLG(FLG_UNAWARE)) ADD_KEY(KEY_UNAWARE);
1343         if (IS_FLG(FLG_UNIDENTIFIED)) ADD_KEY(KEY_UNIDENTIFIED);
1344         if (IS_FLG(FLG_IDENTIFIED)) ADD_KEY(KEY_IDENTIFIED);
1345         if (IS_FLG(FLG_STAR_IDENTIFIED)) ADD_KEY(KEY_STAR_IDENTIFIED);
1346         if (IS_FLG(FLG_BOOSTED)) ADD_KEY(KEY_BOOSTED);
1347
1348         if (IS_FLG(FLG_MORE_DICE))
1349         {
1350                 ADD_KEY(KEY_MORE_THAN);
1351                 strcat(ptr, format("%d", entry->dice));
1352                 ADD_KEY(KEY_DICE);
1353         }
1354
1355         if (IS_FLG(FLG_MORE_BONUS))
1356         {
1357                 ADD_KEY(KEY_MORE_BONUS);
1358                 strcat(ptr, format("%d", entry->bonus));
1359                 ADD_KEY(KEY_MORE_BONUS2);
1360         }
1361
1362         if (IS_FLG(FLG_UNREADABLE)) ADD_KEY(KEY_UNREADABLE);
1363         if (IS_FLG(FLG_REALM1)) ADD_KEY(KEY_REALM1);
1364         if (IS_FLG(FLG_REALM2)) ADD_KEY(KEY_REALM2);
1365         if (IS_FLG(FLG_FIRST)) ADD_KEY(KEY_FIRST);
1366         if (IS_FLG(FLG_SECOND)) ADD_KEY(KEY_SECOND);
1367         if (IS_FLG(FLG_THIRD)) ADD_KEY(KEY_THIRD);
1368         if (IS_FLG(FLG_FOURTH)) ADD_KEY(KEY_FOURTH);
1369         if (IS_FLG(FLG_WANTED)) ADD_KEY(KEY_WANTED);
1370         if (IS_FLG(FLG_UNIQUE)) ADD_KEY(KEY_UNIQUE);
1371         if (IS_FLG(FLG_HUMAN)) ADD_KEY(KEY_HUMAN);
1372         if (IS_FLG(FLG_WORTHLESS)) ADD_KEY(KEY_WORTHLESS);
1373         if (IS_FLG(FLG_GOOD)) ADD_KEY(KEY_GOOD);
1374         if (IS_FLG(FLG_NAMELESS)) ADD_KEY(KEY_NAMELESS);
1375         if (IS_FLG(FLG_AVERAGE)) ADD_KEY(KEY_AVERAGE);
1376         if (IS_FLG(FLG_RARE)) ADD_KEY(KEY_RARE);
1377         if (IS_FLG(FLG_COMMON)) ADD_KEY(KEY_COMMON);
1378         if (IS_FLG(FLG_EGO)) ADD_KEY(KEY_EGO);
1379
1380         if (IS_FLG(FLG_ARTIFACT)) ADD_KEY(KEY_ARTIFACT);
1381
1382         bool sepa_flag = TRUE;
1383         if (IS_FLG(FLG_ITEMS)) ADD_KEY2(KEY_ITEMS);
1384         else if (IS_FLG(FLG_WEAPONS)) ADD_KEY2(KEY_WEAPONS);
1385         else if (IS_FLG(FLG_FAVORITE_WEAPONS)) ADD_KEY2(KEY_FAVORITE_WEAPONS);
1386         else if (IS_FLG(FLG_ARMORS)) ADD_KEY2(KEY_ARMORS);
1387         else if (IS_FLG(FLG_MISSILES)) ADD_KEY2(KEY_MISSILES);
1388         else if (IS_FLG(FLG_DEVICES)) ADD_KEY2(KEY_DEVICES);
1389         else if (IS_FLG(FLG_LIGHTS)) ADD_KEY2(KEY_LIGHTS);
1390         else if (IS_FLG(FLG_JUNKS)) ADD_KEY2(KEY_JUNKS);
1391         else if (IS_FLG(FLG_CORPSES)) ADD_KEY2(KEY_CORPSES);
1392         else if (IS_FLG(FLG_SPELLBOOKS)) ADD_KEY2(KEY_SPELLBOOKS);
1393         else if (IS_FLG(FLG_HAFTED)) ADD_KEY2(KEY_HAFTED);
1394         else if (IS_FLG(FLG_SHIELDS)) ADD_KEY2(KEY_SHIELDS);
1395         else if (IS_FLG(FLG_BOWS)) ADD_KEY2(KEY_BOWS);
1396         else if (IS_FLG(FLG_RINGS)) ADD_KEY2(KEY_RINGS);
1397         else if (IS_FLG(FLG_AMULETS)) ADD_KEY2(KEY_AMULETS);
1398         else if (IS_FLG(FLG_SUITS)) ADD_KEY2(KEY_SUITS);
1399         else if (IS_FLG(FLG_CLOAKS)) ADD_KEY2(KEY_CLOAKS);
1400         else if (IS_FLG(FLG_HELMS)) ADD_KEY2(KEY_HELMS);
1401         else if (IS_FLG(FLG_GLOVES)) ADD_KEY2(KEY_GLOVES);
1402         else if (IS_FLG(FLG_BOOTS)) ADD_KEY2(KEY_BOOTS);
1403
1404         /* You don't need sepalator after adjective */
1405         /* 'artifact' is not true adjective */
1406         else if (!IS_FLG(FLG_ARTIFACT))
1407                 sepa_flag = FALSE;
1408
1409         if (entry->name && entry->name[0])
1410         {
1411                 if (sepa_flag) strcat(buf, ":");
1412
1413                 int i = strlen(buf);
1414                 int j = 0;
1415                 while (entry->name[j] && i < MAX_LINELEN - 2 - 1)
1416                 {
1417 #ifdef JP
1418                         if (iskanji(entry->name[j]))
1419                                 buf[i++] = entry->name[j++];
1420 #endif
1421                         buf[i++] = entry->name[j++];
1422                 }
1423                 buf[i] = '\0';
1424         }
1425
1426         if (!entry->insc) return string_make(buf);
1427
1428         int i, j = 0;
1429         strcat(buf, "#");
1430         i = strlen(buf);
1431
1432         while (entry->insc[j] && i < MAX_LINELEN - 2)
1433         {
1434 #ifdef JP
1435                 if (iskanji(entry->insc[j]))
1436                         buf[i++] = entry->insc[j++];
1437 #endif
1438                 buf[i++] = entry->insc[j++];
1439         }
1440
1441         buf[i] = '\0';
1442         return string_make(buf);
1443 }
1444
1445
1446 /*
1447  * Reconstruct preference line from entry and kill entry
1448  */
1449 static concptr autopick_line_from_entry_kill(autopick_type *entry)
1450 {
1451         concptr ptr = autopick_line_from_entry(entry);
1452         autopick_free_entry(entry);
1453         return ptr;
1454 }
1455
1456
1457 /*
1458  * A function for Auto-picker/destroyer
1459  * Examine whether the object matches to the entry
1460  */
1461 static bool is_autopick_aux(player_type *player_ptr, object_type *o_ptr, autopick_type *entry, concptr o_name)
1462 {
1463         concptr ptr = entry->name;
1464
1465         /*** Unaware items ***/
1466         if (IS_FLG(FLG_UNAWARE) && object_is_aware(o_ptr))
1467                 return FALSE;
1468
1469         /*** Unidentified ***/
1470         if (IS_FLG(FLG_UNIDENTIFIED)
1471                 && (object_is_known(o_ptr) || (o_ptr->ident & IDENT_SENSE)))
1472                 return FALSE;
1473
1474         /*** Identified ***/
1475         if (IS_FLG(FLG_IDENTIFIED) && !object_is_known(o_ptr))
1476                 return FALSE;
1477
1478         /*** *Identified* ***/
1479         if (IS_FLG(FLG_STAR_IDENTIFIED) &&
1480                 (!object_is_known(o_ptr) || !(o_ptr->ident & IDENT_MENTAL)))
1481                 return FALSE;
1482
1483         /*** Dice boosted (weapon of slaying) ***/
1484         if (IS_FLG(FLG_BOOSTED))
1485         {
1486                 object_kind *k_ptr = &k_info[o_ptr->k_idx];
1487
1488                 /* Require melee weapon */
1489                 if (!object_is_melee_weapon(o_ptr))
1490                         return FALSE;
1491
1492                 /* Require boosted dice */
1493                 if ((o_ptr->dd == k_ptr->dd) && (o_ptr->ds == k_ptr->ds))
1494                         return FALSE;
1495
1496                 /* In Vault Quest, Dice must be hide.*/
1497                 if (!object_is_known(o_ptr) && object_is_quest_target(o_ptr))
1498                 {
1499                         return FALSE;
1500                 }
1501         }
1502
1503         /*** Weapons which dd*ds is more than nn ***/
1504         if (IS_FLG(FLG_MORE_DICE))
1505         {
1506                 if (o_ptr->dd * o_ptr->ds < entry->dice)
1507                         return FALSE;
1508         }
1509
1510         /*** Weapons whic dd*ds is more than nn ***/
1511         if (IS_FLG(FLG_MORE_BONUS))
1512         {
1513                 if (!object_is_known(o_ptr)) return FALSE;
1514
1515                 if (o_ptr->pval)
1516                 {
1517                         if (o_ptr->pval < entry->bonus) return FALSE;
1518                 }
1519                 else
1520                 {
1521                         if (o_ptr->to_h < entry->bonus &&
1522                                 o_ptr->to_d < entry->bonus &&
1523                                 o_ptr->to_a < entry->bonus &&
1524                                 o_ptr->pval < entry->bonus)
1525                                 return FALSE;
1526                 }
1527         }
1528
1529         /*** Worthless items ***/
1530         if (IS_FLG(FLG_WORTHLESS) && object_value(o_ptr) > 0)
1531                 return FALSE;
1532
1533         /*** Artifact object ***/
1534         if (IS_FLG(FLG_ARTIFACT))
1535         {
1536                 if (!object_is_known(o_ptr) || !object_is_artifact(o_ptr))
1537                         return FALSE;
1538         }
1539
1540         /*** Ego object ***/
1541         if (IS_FLG(FLG_EGO))
1542         {
1543                 /* Need to be an ego item */
1544                 if (!object_is_ego(o_ptr)) return FALSE;
1545
1546                 /* Need to be known to be an ego */
1547                 if (!object_is_known(o_ptr) &&
1548                         !((o_ptr->ident & IDENT_SENSE) && o_ptr->feeling == FEEL_EXCELLENT))
1549                         return FALSE;
1550         }
1551
1552         /*** Good ***/
1553         if (IS_FLG(FLG_GOOD))
1554         {
1555                 if (!object_is_equipment(o_ptr)) return FALSE;
1556
1557                 /* Identified */
1558                 if (object_is_known(o_ptr))
1559                 {
1560                         /* Artifacts and Ego objects are not okay */
1561                         if (!object_is_nameless(o_ptr))
1562                                 return FALSE;
1563
1564                         /* Average are not okay */
1565                         if (o_ptr->to_a <= 0 && (o_ptr->to_h + o_ptr->to_d) <= 0)
1566                                 return FALSE;
1567                 }
1568
1569                 /* Pseudo-identified */
1570                 else if (o_ptr->ident & IDENT_SENSE)
1571                 {
1572                         switch (o_ptr->feeling)
1573                         {
1574                         case FEEL_GOOD:
1575                                 /* It's good */
1576                                 break;
1577
1578                         default:
1579                                 /* It's not good */
1580                                 return FALSE;
1581                         }
1582                 }
1583
1584                 /* Unidentified */
1585                 else
1586                 {
1587                         /* Not known to be good */
1588                         return FALSE;
1589                 }
1590         }
1591
1592         /*** Nameless ***/
1593         if (IS_FLG(FLG_NAMELESS))
1594         {
1595                 if (!object_is_equipment(o_ptr)) return FALSE;
1596
1597                 /* Identified */
1598                 if (object_is_known(o_ptr))
1599                 {
1600                         /* Artifacts and Ego objects are not okay */
1601                         if (!object_is_nameless(o_ptr))
1602                                 return FALSE;
1603                 }
1604
1605                 /* Pseudo-identified */
1606                 else if (o_ptr->ident & IDENT_SENSE)
1607                 {
1608                         switch (o_ptr->feeling)
1609                         {
1610                         case FEEL_AVERAGE:
1611                         case FEEL_GOOD:
1612                         case FEEL_BROKEN:
1613                         case FEEL_CURSED:
1614                                 /* It's nameless */
1615                                 break;
1616
1617                         default:
1618                                 /* It's not nameless */
1619                                 return FALSE;
1620                         }
1621                 }
1622
1623                 /* Unidentified */
1624                 else
1625                 {
1626                         /* Not known to be nameless */
1627                         return FALSE;
1628                 }
1629         }
1630
1631         /*** Average ***/
1632         if (IS_FLG(FLG_AVERAGE))
1633         {
1634                 if (!object_is_equipment(o_ptr)) return FALSE;
1635
1636                 /* Identified */
1637                 if (object_is_known(o_ptr))
1638                 {
1639                         /* Artifacts and Ego objects are not okay */
1640                         if (!object_is_nameless(o_ptr))
1641                                 return FALSE;
1642
1643                         /* Cursed or broken objects are not okay */
1644                         if (object_is_cursed(o_ptr) || object_is_broken(o_ptr))
1645                                 return FALSE;
1646
1647                         /* Good are not okay */
1648                         if (o_ptr->to_a > 0 || (o_ptr->to_h + o_ptr->to_d) > 0)
1649                                 return FALSE;
1650                 }
1651
1652                 /* Pseudo-identified */
1653                 else if (o_ptr->ident & IDENT_SENSE)
1654                 {
1655                         switch (o_ptr->feeling)
1656                         {
1657                         case FEEL_AVERAGE:
1658                                 /* It's average */
1659                                 break;
1660
1661                         default:
1662                                 /* It's not average */
1663                                 return FALSE;
1664                         }
1665                 }
1666
1667                 /* Unidentified */
1668                 else
1669                 {
1670                         /* Not known to be average */
1671                         return FALSE;
1672                 }
1673         }
1674
1675         /*** Rere equipments ***/
1676         if (IS_FLG(FLG_RARE) && !object_is_rare(o_ptr))
1677                 return FALSE;
1678
1679         /*** Common equipments ***/
1680         if (IS_FLG(FLG_COMMON) && object_is_rare(o_ptr))
1681                 return FALSE;
1682
1683         /*** Wanted monster's corpse/skeletons ***/
1684         if (IS_FLG(FLG_WANTED) && !object_is_bounty(o_ptr))
1685                 return FALSE;
1686
1687         /*** Unique monster's corpse/skeletons/statues ***/
1688         if (IS_FLG(FLG_UNIQUE) &&
1689                 ((o_ptr->tval != TV_CORPSE && o_ptr->tval != TV_STATUE) ||
1690                         !(r_info[o_ptr->pval].flags1 & RF1_UNIQUE)))
1691                 return FALSE;
1692
1693         /*** Human corpse/skeletons (for Daemon magic) ***/
1694         if (IS_FLG(FLG_HUMAN) &&
1695                 (o_ptr->tval != TV_CORPSE ||
1696                         !my_strchr("pht", r_info[o_ptr->pval].d_char)))
1697                 return FALSE;
1698
1699         /*** Unreadable spellbooks ***/
1700         if (IS_FLG(FLG_UNREADABLE) &&
1701                 (o_ptr->tval < TV_LIFE_BOOK ||
1702                         check_book_realm(player_ptr, o_ptr->tval, o_ptr->sval)))
1703                 return FALSE;
1704
1705         /*** First realm spellbooks ***/
1706         if (IS_FLG(FLG_REALM1) &&
1707                 (REALM1_BOOK != o_ptr->tval ||
1708                         player_ptr->pclass == CLASS_SORCERER ||
1709                         player_ptr->pclass == CLASS_RED_MAGE))
1710                 return FALSE;
1711
1712         /*** Second realm spellbooks ***/
1713         if (IS_FLG(FLG_REALM2) &&
1714                 (REALM2_BOOK != o_ptr->tval ||
1715                         player_ptr->pclass == CLASS_SORCERER ||
1716                         player_ptr->pclass == CLASS_RED_MAGE))
1717                 return FALSE;
1718
1719         /*** First rank spellbooks ***/
1720         if (IS_FLG(FLG_FIRST) &&
1721                 (o_ptr->tval < TV_LIFE_BOOK || 0 != o_ptr->sval))
1722                 return FALSE;
1723
1724         /*** Second rank spellbooks ***/
1725         if (IS_FLG(FLG_SECOND) &&
1726                 (o_ptr->tval < TV_LIFE_BOOK || 1 != o_ptr->sval))
1727                 return FALSE;
1728
1729         /*** Third rank spellbooks ***/
1730         if (IS_FLG(FLG_THIRD) &&
1731                 (o_ptr->tval < TV_LIFE_BOOK || 2 != o_ptr->sval))
1732                 return FALSE;
1733
1734         /*** Fourth rank spellbooks ***/
1735         if (IS_FLG(FLG_FOURTH) &&
1736                 (o_ptr->tval < TV_LIFE_BOOK || 3 != o_ptr->sval))
1737                 return FALSE;
1738
1739         /*** Items ***/
1740         if (IS_FLG(FLG_WEAPONS))
1741         {
1742                 if (!object_is_weapon(o_ptr))
1743                         return FALSE;
1744         }
1745         else if (IS_FLG(FLG_FAVORITE_WEAPONS))
1746         {
1747                 if (!object_is_favorite(o_ptr))
1748                         return FALSE;
1749         }
1750         else if (IS_FLG(FLG_ARMORS))
1751         {
1752                 if (!object_is_armour(o_ptr))
1753                         return FALSE;
1754         }
1755         else if (IS_FLG(FLG_MISSILES))
1756         {
1757                 if (!object_is_ammo(o_ptr)) return FALSE;
1758         }
1759         else if (IS_FLG(FLG_DEVICES))
1760         {
1761                 switch (o_ptr->tval)
1762                 {
1763                 case TV_SCROLL: case TV_STAFF: case TV_WAND: case TV_ROD:
1764                         break;
1765                 default: return FALSE;
1766                 }
1767         }
1768         else if (IS_FLG(FLG_LIGHTS))
1769         {
1770                 if (!(o_ptr->tval == TV_LITE))
1771                         return FALSE;
1772         }
1773         else if (IS_FLG(FLG_JUNKS))
1774         {
1775                 switch (o_ptr->tval)
1776                 {
1777                 case TV_SKELETON: case TV_BOTTLE:
1778                 case TV_JUNK: case TV_STATUE:
1779                         break;
1780                 default: return FALSE;
1781                 }
1782         }
1783         else if (IS_FLG(FLG_CORPSES))
1784         {
1785                 if (o_ptr->tval != TV_CORPSE && o_ptr->tval != TV_SKELETON)
1786                         return FALSE;
1787         }
1788         else if (IS_FLG(FLG_SPELLBOOKS))
1789         {
1790                 if (!(o_ptr->tval >= TV_LIFE_BOOK))
1791                         return FALSE;
1792         }
1793         else if (IS_FLG(FLG_HAFTED))
1794         {
1795                 if (!(o_ptr->tval == TV_HAFTED))
1796                         return FALSE;
1797         }
1798         else if (IS_FLG(FLG_SHIELDS))
1799         {
1800                 if (!(o_ptr->tval == TV_SHIELD))
1801                         return FALSE;
1802         }
1803         else if (IS_FLG(FLG_BOWS))
1804         {
1805                 if (!(o_ptr->tval == TV_BOW))
1806                         return FALSE;
1807         }
1808         else if (IS_FLG(FLG_RINGS))
1809         {
1810                 if (!(o_ptr->tval == TV_RING))
1811                         return FALSE;
1812         }
1813         else if (IS_FLG(FLG_AMULETS))
1814         {
1815                 if (!(o_ptr->tval == TV_AMULET))
1816                         return FALSE;
1817         }
1818         else if (IS_FLG(FLG_SUITS))
1819         {
1820                 if (!(o_ptr->tval == TV_DRAG_ARMOR ||
1821                         o_ptr->tval == TV_HARD_ARMOR ||
1822                         o_ptr->tval == TV_SOFT_ARMOR))
1823                         return FALSE;
1824         }
1825         else if (IS_FLG(FLG_CLOAKS))
1826         {
1827                 if (!(o_ptr->tval == TV_CLOAK))
1828                         return FALSE;
1829         }
1830         else if (IS_FLG(FLG_HELMS))
1831         {
1832                 if (!(o_ptr->tval == TV_CROWN || o_ptr->tval == TV_HELM))
1833                         return FALSE;
1834         }
1835         else if (IS_FLG(FLG_GLOVES))
1836         {
1837                 if (!(o_ptr->tval == TV_GLOVES))
1838                         return FALSE;
1839         }
1840         else if (IS_FLG(FLG_BOOTS))
1841         {
1842                 if (!(o_ptr->tval == TV_BOOTS))
1843                         return FALSE;
1844         }
1845
1846         /* Keyword don't match */
1847         if (*ptr == '^')
1848         {
1849                 ptr++;
1850                 if (strncmp(o_name, ptr, strlen(ptr))) return FALSE;
1851         }
1852         else
1853         {
1854                 if (!my_strstr(o_name, ptr)) return FALSE;
1855         }
1856
1857         /* TRUE when it need not to be 'collecting' */
1858         if (!IS_FLG(FLG_COLLECTING)) return TRUE;
1859
1860         /* Check if there is a same item */
1861         for (int j = 0; j < INVEN_PACK; j++)
1862         {
1863                 /*
1864                  * 'Collecting' means the item must be absorbed
1865                  * into an inventory slot.
1866                  * But an item can not be absorbed into itself!
1867                  */
1868                 if ((&player_ptr->inventory_list[j] != o_ptr) &&
1869                         object_similar(&player_ptr->inventory_list[j], o_ptr))
1870                         return TRUE;
1871         }
1872
1873         return FALSE;
1874 }
1875
1876
1877 /*
1878  * A function for Auto-picker/destroyer
1879  * Examine whether the object matches to the list of keywords or not.
1880  */
1881 int is_autopick(player_type *player_ptr, object_type *o_ptr)
1882 {
1883         GAME_TEXT o_name[MAX_NLEN];
1884
1885         if (o_ptr->tval == TV_GOLD) return -1;
1886
1887         /* Prepare object name string first */
1888         object_desc(o_name, o_ptr, (OD_NO_FLAVOR | OD_OMIT_PREFIX | OD_NO_PLURAL));
1889
1890         /* Convert the string to lower case */
1891         str_tolower(o_name);
1892
1893         /* Look for a matching entry in the list */
1894         for (int i = 0; i < max_autopick; i++)
1895         {
1896                 autopick_type *entry = &autopick_list[i];
1897
1898                 if (is_autopick_aux(player_ptr, o_ptr, entry, o_name)) return i;
1899         }
1900
1901         return -1;
1902 }
1903
1904
1905 /*
1906  *  Auto inscription
1907  */
1908 static void auto_inscribe_item(player_type *player_ptr, object_type *o_ptr, int idx)
1909 {
1910         /* Are there auto-inscription? */
1911         if (idx < 0 || !autopick_list[idx].insc) return;
1912
1913         if (!o_ptr->inscription)
1914                 o_ptr->inscription = quark_add(autopick_list[idx].insc);
1915
1916         /* Redraw inscription */
1917         player_ptr->window |= (PW_EQUIP | PW_INVEN);
1918
1919         /* {.} and {$} effect player_ptr->warning and TRC_TELEPORT_SELF */
1920         player_ptr->update |= (PU_BONUS);
1921 }
1922
1923
1924 /*
1925  * Automatically destroy items in this grid.
1926  */
1927 static bool is_opt_confirm_destroy(player_type *player_ptr, object_type *o_ptr)
1928 {
1929         if (!destroy_items) return FALSE;
1930
1931         /* Known to be worthless? */
1932         if (leave_worth)
1933                 if (object_value(o_ptr) > 0) return FALSE;
1934
1935         if (leave_equip)
1936                 if (object_is_weapon_armour_ammo(o_ptr)) return FALSE;
1937
1938         if (leave_chest)
1939                 if ((o_ptr->tval == TV_CHEST) && o_ptr->pval) return FALSE;
1940
1941         if (leave_wanted)
1942         {
1943                 if (object_is_bounty(o_ptr)) return FALSE;
1944         }
1945
1946         if (leave_corpse)
1947                 if (o_ptr->tval == TV_CORPSE) return FALSE;
1948
1949         if (leave_junk)
1950                 if ((o_ptr->tval == TV_SKELETON) || (o_ptr->tval == TV_BOTTLE) || (o_ptr->tval == TV_JUNK) || (o_ptr->tval == TV_STATUE)) return FALSE;
1951
1952         if (leave_special)
1953         {
1954                 if (player_ptr->prace == RACE_DEMON)
1955                 {
1956                         if (o_ptr->tval == TV_CORPSE &&
1957                                 o_ptr->sval == SV_CORPSE &&
1958                                 my_strchr("pht", r_info[o_ptr->pval].d_char))
1959                                 return FALSE;
1960                 }
1961
1962                 if (player_ptr->pclass == CLASS_ARCHER)
1963                 {
1964                         if (o_ptr->tval == TV_SKELETON ||
1965                                 (o_ptr->tval == TV_CORPSE && o_ptr->sval == SV_SKELETON))
1966                                 return FALSE;
1967                 }
1968                 else if (player_ptr->pclass == CLASS_NINJA)
1969                 {
1970                         if (o_ptr->tval == TV_LITE &&
1971                                 o_ptr->name2 == EGO_LITE_DARKNESS && object_is_known(o_ptr))
1972                                 return FALSE;
1973                 }
1974                 else if (player_ptr->pclass == CLASS_BEASTMASTER ||
1975                         player_ptr->pclass == CLASS_CAVALRY)
1976                 {
1977                         if (o_ptr->tval == TV_WAND &&
1978                                 o_ptr->sval == SV_WAND_HEAL_MONSTER && object_is_aware(o_ptr))
1979                                 return FALSE;
1980                 }
1981         }
1982
1983         if (o_ptr->tval == TV_GOLD) return FALSE;
1984
1985         return TRUE;
1986 }
1987
1988
1989 static void auto_destroy_item(player_type *player_ptr, object_type *o_ptr, int autopick_idx)
1990 {
1991         bool destroy = FALSE;
1992
1993         /* Easy-Auto-Destroyer (3rd priority) */
1994         if (is_opt_confirm_destroy(player_ptr, o_ptr)) destroy = TRUE;
1995
1996         /* Protected by auto-picker (2nd priotity) */
1997         if (autopick_idx >= 0 &&
1998                 !(autopick_list[autopick_idx].action & DO_AUTODESTROY))
1999                 destroy = FALSE;
2000
2001         /* Auto-destroyer works only when !always_pickup */
2002         if (!always_pickup)
2003         {
2004                 /* Auto-picker/destroyer (1st priority) */
2005                 if (autopick_idx >= 0 &&
2006                         (autopick_list[autopick_idx].action & DO_AUTODESTROY))
2007                         destroy = TRUE;
2008         }
2009
2010         /* Not to be destroyed */
2011         if (!destroy) return;
2012
2013         /* Now decided to destroy */
2014
2015         disturb(player_ptr, FALSE, FALSE);
2016
2017         /* Artifact? */
2018         if (!can_player_destroy_object(o_ptr))
2019         {
2020                 GAME_TEXT o_name[MAX_NLEN];
2021
2022                 /* Describe the object (with {terrible/special}) */
2023                 object_desc(o_name, o_ptr, 0);
2024
2025                 msg_format(_("%sは破壊不能だ。", "You cannot auto-destroy %s."), o_name);
2026
2027                 return;
2028         }
2029
2030         /* Record name of destroyed item */
2031         (void)COPY(&autopick_last_destroyed_object, o_ptr, object_type);
2032
2033         /* Destroy Later */
2034         o_ptr->marked |= OM_AUTODESTROY;
2035         player_ptr->update |= PU_AUTODESTROY;
2036 }
2037
2038
2039 /*
2040  *  Auto-destroy marked item
2041  */
2042 static void autopick_delayed_alter_aux(player_type *player_ptr, INVENTORY_IDX item)
2043 {
2044         object_type *o_ptr;
2045         o_ptr = REF_ITEM(player_ptr, player_ptr->current_floor_ptr, item);
2046
2047         if (o_ptr->k_idx == 0 || !(o_ptr->marked & OM_AUTODESTROY)) return;
2048
2049         GAME_TEXT o_name[MAX_NLEN];
2050
2051         /* Describe the object (with {terrible/special}) */
2052         object_desc(o_name, o_ptr, 0);
2053
2054         /* Eliminate the item (from the pack) */
2055         if (item >= 0)
2056         {
2057                 inven_item_increase(player_ptr, item, -(o_ptr->number));
2058                 inven_item_optimize(player_ptr, item);
2059         }
2060
2061         /* Eliminate the item (from the floor) */
2062         else
2063         {
2064                 delete_object_idx(player_ptr->current_floor_ptr, 0 - item);
2065         }
2066
2067         msg_format(_("%sを自動破壊します。", "Auto-destroying %s."), o_name);
2068 }
2069
2070
2071 /*
2072  *  Auto-destroy marked items in inventry and on floor
2073  */
2074 void autopick_delayed_alter(player_type *owner_ptr)
2075 {
2076         INVENTORY_IDX item;
2077
2078         /*
2079          * Scan inventry in reverse order to prevent
2080          * skipping after inven_item_optimize()
2081          */
2082         for (item = INVEN_TOTAL - 1; item >= 0; item--)
2083                 autopick_delayed_alter_aux(owner_ptr, item);
2084
2085         /* Scan the pile of objects */
2086         floor_type *floor_ptr = owner_ptr->current_floor_ptr;
2087         item = floor_ptr->grid_array[owner_ptr->y][owner_ptr->x].o_idx;
2088         while (item)
2089         {
2090                 OBJECT_IDX next = floor_ptr->o_list[item].next_o_idx;
2091                 autopick_delayed_alter_aux(owner_ptr, -item);
2092                 item = next;
2093         }
2094 }
2095
2096
2097 /*
2098  * Auto-inscription and/or destroy
2099  *
2100  * Auto-destroyer works only on inventory or on floor stack only when
2101  * requested.
2102  */
2103 void autopick_alter_item(player_type *player_ptr, INVENTORY_IDX item, bool destroy)
2104 {
2105         object_type *o_ptr;
2106         int idx;
2107
2108         o_ptr = REF_ITEM(player_ptr, player_ptr->current_floor_ptr, item);
2109
2110         /* Get the index in the auto-pick/destroy list */
2111         idx = is_autopick(player_ptr, o_ptr);
2112
2113         /* Do auto-inscription */
2114         auto_inscribe_item(player_ptr, o_ptr, idx);
2115
2116         /* Do auto-destroy if needed */
2117         if (destroy && item <= INVEN_PACK)
2118                 auto_destroy_item(player_ptr, o_ptr, idx);
2119 }
2120
2121
2122 /*
2123  * Automatically pickup/destroy items in this grid.
2124  */
2125 void autopick_pickup_items(player_type* player_ptr, grid_type *g_ptr)
2126 {
2127         OBJECT_IDX this_o_idx, next_o_idx = 0;
2128
2129         /* Scan the pile of objects */
2130         for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
2131         {
2132                 int idx;
2133                 object_type *o_ptr = &player_ptr->current_floor_ptr->o_list[this_o_idx];
2134                 next_o_idx = o_ptr->next_o_idx;
2135
2136                 idx = is_autopick(player_ptr, o_ptr);
2137
2138                 /* Item index for floor -1,-2,-3,...  */
2139                 auto_inscribe_item(player_ptr, o_ptr, idx);
2140
2141                 bool is_auto_pickup = idx >= 0;
2142                 is_auto_pickup &= autopick_list[idx].action & (DO_AUTOPICK | DO_QUERY_AUTOPICK);
2143                 if (!is_auto_pickup)
2144                 {
2145                         auto_destroy_item(player_ptr, o_ptr, idx);
2146                         continue;
2147                 }
2148
2149                 disturb(player_ptr, FALSE, FALSE);
2150
2151                 if (!inven_carry_okay(o_ptr))
2152                 {
2153                         GAME_TEXT o_name[MAX_NLEN];
2154
2155                         object_desc(o_name, o_ptr, 0);
2156
2157                         msg_format(_("ザックには%sを入れる隙間がない。", "You have no room for %s."), o_name);
2158                         /* Hack - remember that the item has given a message here. */
2159                         o_ptr->marked |= OM_NOMSG;
2160                         continue;
2161                 }
2162
2163                 if (!(autopick_list[idx].action & DO_QUERY_AUTOPICK))
2164                 {
2165                         py_pickup_aux(player_ptr, this_o_idx);
2166                         continue;
2167                 }
2168
2169                 char out_val[MAX_NLEN + 20];
2170                 GAME_TEXT o_name[MAX_NLEN];
2171
2172                 if (o_ptr->marked & OM_NO_QUERY)
2173                 {
2174                         /* Already answered as 'No' */
2175                         continue;
2176                 }
2177
2178                 object_desc(o_name, o_ptr, 0);
2179
2180                 sprintf(out_val, _("%sを拾いますか? ", "Pick up %s? "), o_name);
2181
2182                 if (!get_check(out_val))
2183                 {
2184                         /* Hack - remember that the item has given a message here. */
2185                         o_ptr->marked |= OM_NOMSG | OM_NO_QUERY;
2186                         continue;
2187                 }
2188
2189                 py_pickup_aux(player_ptr, this_o_idx);
2190         }
2191 }
2192
2193
2194 static const char autoregister_header[] = "?:$AUTOREGISTER";
2195
2196 /*
2197  *  Clear auto registered lines in the picktype.prf .
2198  */
2199 static bool clear_auto_register(player_type *player_ptr)
2200 {
2201         char tmp_file[1024];
2202         char pref_file[1024];
2203         char buf[1024];
2204         FILE *pref_fff;
2205         FILE *tmp_fff;
2206         int num = 0;
2207         bool autoregister = FALSE;
2208         bool okay = TRUE;
2209
2210         path_build(pref_file, sizeof(pref_file), ANGBAND_DIR_USER, pickpref_filename(player_ptr, PT_WITH_PNAME));
2211         pref_fff = my_fopen(pref_file, "r");
2212
2213         if (!pref_fff)
2214         {
2215                 path_build(pref_file, sizeof(pref_file), ANGBAND_DIR_USER, pickpref_filename(player_ptr, PT_DEFAULT));
2216                 pref_fff = my_fopen(pref_file, "r");
2217         }
2218
2219         if (!pref_fff)
2220         {
2221                 /* No file yet */
2222                 return TRUE;
2223         }
2224
2225         /* Open a new (temporary) file */
2226         tmp_fff = my_fopen_temp(tmp_file, sizeof(tmp_file));
2227
2228         if (!tmp_fff)
2229         {
2230                 /* Close the preference file */
2231                 fclose(pref_fff);
2232                 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
2233                 msg_print(NULL);
2234                 return FALSE;
2235         }
2236
2237         while (TRUE)
2238         {
2239                 if (my_fgets(pref_fff, buf, sizeof(buf))) break;
2240
2241                 if (autoregister)
2242                 {
2243                         if (buf[0] != '#' && buf[0] != '?') num++;
2244                         continue;
2245                 }
2246
2247                 if (streq(buf, autoregister_header))
2248                 {
2249                         autoregister = TRUE;
2250                 }
2251                 else
2252                 {
2253                         fprintf(tmp_fff, "%s\n", buf);
2254                 }
2255         }
2256
2257         my_fclose(pref_fff);
2258         my_fclose(tmp_fff);
2259
2260         if (num)
2261         {
2262                 msg_format(_("以前のキャラクター用の自動設定(%d行)が残っています。",
2263                         "Auto registered lines (%d lines) for previous character are remaining."), num);
2264                 strcpy(buf, _("古い設定行は削除します。よろしいですか?", "These lines will be deleted.  Are you sure? "));
2265
2266                 /* You can cancel it */
2267                 if (!get_check(buf))
2268                 {
2269                         okay = FALSE;
2270                         autoregister = FALSE;
2271
2272                         msg_print(_("エディタのカット&ペースト等を使って必要な行を避難してください。",
2273                                 "Use cut & paste of auto picker editor (_) to keep old prefs."));
2274                 }
2275         }
2276
2277         if (autoregister)
2278         {
2279                 tmp_fff = my_fopen(tmp_file, "r");
2280                 pref_fff = my_fopen(pref_file, "w");
2281
2282                 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
2283                         fprintf(pref_fff, "%s\n", buf);
2284
2285                 my_fclose(pref_fff);
2286                 my_fclose(tmp_fff);
2287         }
2288
2289         fd_kill(tmp_file);
2290         return okay;
2291 }
2292
2293
2294 /*
2295  *  Automatically register an auto-destroy preference line
2296  */
2297 bool autopick_autoregister(player_type *player_ptr, object_type *o_ptr)
2298 {
2299         char buf[1024];
2300         char pref_file[1024];
2301         FILE *pref_fff;
2302         autopick_type an_entry, *entry = &an_entry;
2303
2304         int match_autopick = is_autopick(player_ptr, o_ptr);
2305
2306         /* Already registered */
2307         if (match_autopick != -1)
2308         {
2309                 concptr what;
2310                 byte act = autopick_list[match_autopick].action;
2311
2312                 if (act & DO_AUTOPICK) what = _("自動で拾う", "auto-pickup");
2313                 else if (act & DO_AUTODESTROY) what = _("自動破壊する", "auto-destroy");
2314                 else if (act & DONT_AUTOPICK) what = _("放置する", "leave on floor");
2315                 else /* if (act & DO_QUERY_AUTOPICK) */ what = _("確認して拾う", "query auto-pickup");
2316
2317                 msg_format(_("そのアイテムは既に%sように設定されています。", "The object is already registered to %s."), what);
2318                 return FALSE;
2319         }
2320
2321         /* Known to be an artifact? */
2322         if ((object_is_known(o_ptr) && object_is_artifact(o_ptr)) ||
2323                 ((o_ptr->ident & IDENT_SENSE) &&
2324                 (o_ptr->feeling == FEEL_TERRIBLE || o_ptr->feeling == FEEL_SPECIAL)))
2325         {
2326                 GAME_TEXT o_name[MAX_NLEN];
2327
2328                 /* Describe the object (with {terrible/special}) */
2329                 object_desc(o_name, o_ptr, 0);
2330
2331                 msg_format(_("%sは破壊不能だ。", "You cannot auto-destroy %s."), o_name);
2332
2333                 return FALSE;
2334         }
2335
2336         if (!player_ptr->autopick_autoregister)
2337         {
2338                 /* Clear old auto registered lines */
2339                 if (!clear_auto_register(player_ptr)) return FALSE;
2340         }
2341
2342         /* Try a filename with player name */
2343         path_build(pref_file, sizeof(pref_file), ANGBAND_DIR_USER, pickpref_filename(player_ptr, PT_WITH_PNAME));
2344         pref_fff = my_fopen(pref_file, "r");
2345
2346         if (!pref_fff)
2347         {
2348                 /* Use default name */
2349                 path_build(pref_file, sizeof(pref_file), ANGBAND_DIR_USER, pickpref_filename(player_ptr, PT_DEFAULT));
2350                 pref_fff = my_fopen(pref_file, "r");
2351         }
2352
2353         /* Check the header */
2354         while (TRUE)
2355         {
2356                 /* Read a line */
2357                 if (my_fgets(pref_fff, buf, sizeof(buf)))
2358                 {
2359                         /* No header found */
2360                         player_ptr->autopick_autoregister = FALSE;
2361
2362                         break;
2363                 }
2364
2365                 if (streq(buf, autoregister_header))
2366                 {
2367                         /* Found the header */
2368                         player_ptr->autopick_autoregister = TRUE;
2369
2370                         break;
2371                 }
2372         }
2373
2374         /* Close read only FILE* */
2375         fclose(pref_fff);
2376
2377         /* Open for append */
2378         pref_fff = my_fopen(pref_file, "a");
2379
2380         /* Failure */
2381         if (!pref_fff) {
2382                 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), pref_file);
2383                 msg_print(NULL);
2384
2385                 /* Failed */
2386                 return FALSE;
2387         }
2388
2389         if (!player_ptr->autopick_autoregister)
2390         {
2391                 /* Add the header */
2392                 fprintf(pref_fff, "%s\n", autoregister_header);
2393
2394                 fprintf(pref_fff, "%s\n", _("# *警告!!* 以降の行は自動登録されたものです。",
2395                         "# *Warning!* The lines below will be deleated later."));
2396                 fprintf(pref_fff, "%s\n", _("# 後で自動的に削除されますので、必要な行は上の方へ移動しておいてください。",
2397                         "# Keep it by cut & paste if you need these lines for future characters."));
2398
2399                 /* Now auto register is in-use */
2400                 player_ptr->autopick_autoregister = TRUE;
2401         }
2402
2403         /* Get a preference entry */
2404         autopick_entry_from_object(player_ptr, entry, o_ptr);
2405
2406         /* Set to auto-destroy (with no-display) */
2407         entry->action = DO_AUTODESTROY;
2408
2409         /* Load the new line as preference */
2410         add_autopick_list(entry);
2411
2412         /* Add a line to the file */
2413         /* Don't kill "entry" */
2414         fprintf(pref_fff, "%s\n", autopick_line_from_entry(entry));
2415         fclose(pref_fff);
2416
2417         return TRUE;
2418 }
2419
2420
2421 /*
2422  * Describe which kind of object is Auto-picked/destroyed
2423  */
2424 static void describe_autopick(char *buff, autopick_type *entry)
2425 {
2426         concptr str = entry->name;
2427         byte act = entry->action;
2428         concptr insc = entry->insc;
2429         int i;
2430
2431         bool top = FALSE;
2432
2433 #ifdef JP
2434         concptr before_str[100], body_str;
2435         int before_n = 0;
2436
2437         body_str = "アイテム";
2438
2439         /*** Collecting items ***/
2440         /*** Which can be absorbed into a slot as a bundle ***/
2441         if (IS_FLG(FLG_COLLECTING))
2442                 before_str[before_n++] = "収集中で既に持っているスロットにまとめられる";
2443
2444         /*** Unaware items ***/
2445         if (IS_FLG(FLG_UNAWARE))
2446                 before_str[before_n++] = "未鑑定でその効果も判明していない";
2447
2448         /*** Unidentified ***/
2449         if (IS_FLG(FLG_UNIDENTIFIED))
2450                 before_str[before_n++] = "未鑑定の";
2451
2452         /*** Identified ***/
2453         if (IS_FLG(FLG_IDENTIFIED))
2454                 before_str[before_n++] = "鑑定済みの";
2455
2456         /*** *Identified* ***/
2457         if (IS_FLG(FLG_STAR_IDENTIFIED))
2458                 before_str[before_n++] = "完全に鑑定済みの";
2459
2460         /*** Dice boosted (weapon of slaying) ***/
2461         if (IS_FLG(FLG_BOOSTED))
2462         {
2463                 before_str[before_n++] = "ダメージダイスが通常より大きい";
2464                 body_str = "武器";
2465         }
2466
2467         /*** Weapons whose dd*ds is more than nn ***/
2468         if (IS_FLG(FLG_MORE_DICE))
2469         {
2470                 static char more_than_desc_str[] = "___";
2471                 before_str[before_n++] = "ダメージダイスの最大値が";
2472                 body_str = "武器";
2473
2474                 sprintf(more_than_desc_str, "%d", entry->dice);
2475                 before_str[before_n++] = more_than_desc_str;
2476                 before_str[before_n++] = "以上の";
2477         }
2478
2479         /*** Items whose magical bonus is more than nn ***/
2480         if (IS_FLG(FLG_MORE_BONUS))
2481         {
2482                 static char more_bonus_desc_str[] = "___";
2483                 before_str[before_n++] = "修正値が(+";
2484
2485                 sprintf(more_bonus_desc_str, "%d", entry->bonus);
2486                 before_str[before_n++] = more_bonus_desc_str;
2487                 before_str[before_n++] = ")以上の";
2488         }
2489
2490         /*** Worthless items ***/
2491         if (IS_FLG(FLG_WORTHLESS))
2492                 before_str[before_n++] = "店で無価値と判定される";
2493
2494         /*** Artifact ***/
2495         if (IS_FLG(FLG_ARTIFACT))
2496         {
2497                 before_str[before_n++] = "アーティファクトの";
2498                 body_str = "装備";
2499         }
2500
2501         /*** Ego ***/
2502         if (IS_FLG(FLG_EGO))
2503         {
2504                 before_str[before_n++] = "エゴアイテムの";
2505                 body_str = "装備";
2506         }
2507
2508         /*** Good ***/
2509         if (IS_FLG(FLG_GOOD))
2510         {
2511                 before_str[before_n++] = "上質の";
2512                 body_str = "装備";
2513         }
2514
2515         /*** Nameless ***/
2516         if (IS_FLG(FLG_NAMELESS))
2517         {
2518                 before_str[before_n++] = "エゴでもアーティファクトでもない";
2519                 body_str = "装備";
2520         }
2521
2522         /*** Average ***/
2523         if (IS_FLG(FLG_AVERAGE))
2524         {
2525                 before_str[before_n++] = "並の";
2526                 body_str = "装備";
2527         }
2528
2529         /*** Rare equipments ***/
2530         if (IS_FLG(FLG_RARE))
2531         {
2532                 before_str[before_n++] = "ドラゴン装備やカオス・ブレード等を含む珍しい";
2533                 body_str = "装備";
2534         }
2535
2536         /*** Common equipments ***/
2537         if (IS_FLG(FLG_COMMON))
2538         {
2539                 before_str[before_n++] = "ありふれた(ドラゴン装備やカオス・ブレード等の珍しい物ではない)";
2540                 body_str = "装備";
2541         }
2542
2543         /*** Wanted monster's corpse/skeletons ***/
2544         if (IS_FLG(FLG_WANTED))
2545         {
2546                 before_str[before_n++] = "ハンター事務所で賞金首とされている";
2547                 body_str = "死体や骨";
2548         }
2549
2550         /*** Human corpse/skeletons (for Daemon magic) ***/
2551         if (IS_FLG(FLG_HUMAN))
2552         {
2553                 before_str[before_n++] = "悪魔魔法で使うための人間やヒューマノイドの";
2554                 body_str = "死体や骨";
2555         }
2556
2557         /*** Unique monster's corpse/skeletons/statues ***/
2558         if (IS_FLG(FLG_UNIQUE))
2559         {
2560                 before_str[before_n++] = "ユニークモンスターの";
2561                 body_str = "死体や骨";
2562         }
2563
2564         /*** Unreadable spellbooks ***/
2565         if (IS_FLG(FLG_UNREADABLE))
2566         {
2567                 before_str[before_n++] = "あなたが読めない領域の";
2568                 body_str = "魔法書";
2569         }
2570
2571         /*** First realm spellbooks ***/
2572         if (IS_FLG(FLG_REALM1))
2573         {
2574                 before_str[before_n++] = "第一領域の";
2575                 body_str = "魔法書";
2576         }
2577
2578         /*** Second realm spellbooks ***/
2579         if (IS_FLG(FLG_REALM2))
2580         {
2581                 before_str[before_n++] = "第二領域の";
2582                 body_str = "魔法書";
2583         }
2584
2585         /*** First rank spellbooks ***/
2586         if (IS_FLG(FLG_FIRST))
2587         {
2588                 before_str[before_n++] = "全4冊の内の1冊目の";
2589                 body_str = "魔法書";
2590         }
2591
2592         /*** Second rank spellbooks ***/
2593         if (IS_FLG(FLG_SECOND))
2594         {
2595                 before_str[before_n++] = "全4冊の内の2冊目の";
2596                 body_str = "魔法書";
2597         }
2598
2599         /*** Third rank spellbooks ***/
2600         if (IS_FLG(FLG_THIRD))
2601         {
2602                 before_str[before_n++] = "全4冊の内の3冊目の";
2603                 body_str = "魔法書";
2604         }
2605
2606         /*** Fourth rank spellbooks ***/
2607         if (IS_FLG(FLG_FOURTH))
2608         {
2609                 before_str[before_n++] = "全4冊の内の4冊目の";
2610                 body_str = "魔法書";
2611         }
2612
2613         /*** Items ***/
2614         if (IS_FLG(FLG_ITEMS))
2615                 ; /* Nothing to do */
2616         else if (IS_FLG(FLG_WEAPONS))
2617                 body_str = "武器";
2618         else if (IS_FLG(FLG_FAVORITE_WEAPONS))
2619                 body_str = "得意武器";
2620         else if (IS_FLG(FLG_ARMORS))
2621                 body_str = "防具";
2622         else if (IS_FLG(FLG_MISSILES))
2623                 body_str = "弾や矢やクロスボウの矢";
2624         else if (IS_FLG(FLG_DEVICES))
2625                 body_str = "巻物や魔法棒や杖やロッド";
2626         else if (IS_FLG(FLG_LIGHTS))
2627                 body_str = "光源用のアイテム";
2628         else if (IS_FLG(FLG_JUNKS))
2629                 body_str = "折れた棒等のガラクタ";
2630         else if (IS_FLG(FLG_CORPSES))
2631                 body_str = "死体や骨";
2632         else if (IS_FLG(FLG_SPELLBOOKS))
2633                 body_str = "魔法書";
2634         else if (IS_FLG(FLG_HAFTED))
2635                 body_str = "鈍器";
2636         else if (IS_FLG(FLG_SHIELDS))
2637                 body_str = "盾";
2638         else if (IS_FLG(FLG_BOWS))
2639                 body_str = "スリングや弓やクロスボウ";
2640         else if (IS_FLG(FLG_RINGS))
2641                 body_str = "指輪";
2642         else if (IS_FLG(FLG_AMULETS))
2643                 body_str = "アミュレット";
2644         else if (IS_FLG(FLG_SUITS))
2645                 body_str = "鎧";
2646         else if (IS_FLG(FLG_CLOAKS))
2647                 body_str = "クローク";
2648         else if (IS_FLG(FLG_HELMS))
2649                 body_str = "ヘルメットや冠";
2650         else if (IS_FLG(FLG_GLOVES))
2651                 body_str = "籠手";
2652         else if (IS_FLG(FLG_BOOTS))
2653                 body_str = "ブーツ";
2654
2655         *buff = '\0';
2656         if (!before_n)
2657                 strcat(buff, "全ての");
2658         else for (i = 0; i < before_n && before_str[i]; i++)
2659                 strcat(buff, before_str[i]);
2660
2661         strcat(buff, body_str);
2662
2663         if (*str)
2664         {
2665                 if (*str == '^')
2666                 {
2667                         str++;
2668                         top = TRUE;
2669                 }
2670
2671                 strcat(buff, "で、名前が「");
2672                 strncat(buff, str, 80);
2673                 if (top)
2674                         strcat(buff, "」で始まるもの");
2675                 else
2676                         strcat(buff, "」を含むもの");
2677         }
2678
2679         if (insc)
2680         {
2681                 strncat(buff, format("に「%s」", insc), 80);
2682
2683                 if (my_strstr(insc, "%%all"))
2684                         strcat(buff, "(%%allは全能力を表す英字の記号で置換)");
2685                 else if (my_strstr(insc, "%all"))
2686                         strcat(buff, "(%allは全能力を表す記号で置換)");
2687                 else if (my_strstr(insc, "%%"))
2688                         strcat(buff, "(%%は追加能力を表す英字の記号で置換)");
2689                 else if (my_strstr(insc, "%"))
2690                         strcat(buff, "(%は追加能力を表す記号で置換)");
2691
2692                 strcat(buff, "と刻んで");
2693         }
2694         else
2695                 strcat(buff, "を");
2696
2697         if (act & DONT_AUTOPICK)
2698                 strcat(buff, "放置する。");
2699         else if (act & DO_AUTODESTROY)
2700                 strcat(buff, "破壊する。");
2701         else if (act & DO_QUERY_AUTOPICK)
2702                 strcat(buff, "確認の後に拾う。");
2703         else
2704                 strcat(buff, "拾う。");
2705
2706         if (act & DO_DISPLAY)
2707         {
2708                 if (act & DONT_AUTOPICK)
2709                         strcat(buff, "全体マップ('M')で'N'を押したときに表示する。");
2710                 else if (act & DO_AUTODESTROY)
2711                         strcat(buff, "全体マップ('M')で'K'を押したときに表示する。");
2712                 else
2713                         strcat(buff, "全体マップ('M')で'M'を押したときに表示する。");
2714         }
2715         else
2716                 strcat(buff, "全体マップには表示しない。");
2717
2718 #else /* JP */
2719
2720         concptr before_str[20], after_str[20], which_str[20], whose_str[20], body_str;
2721         int before_n = 0, after_n = 0, which_n = 0, whose_n = 0;
2722
2723         body_str = "items";
2724
2725         /*** Collecting items ***/
2726         /*** Which can be absorbed into a slot as a bundle ***/
2727         if (IS_FLG(FLG_COLLECTING))
2728                 which_str[which_n++] = "can be absorbed into an existing inventory list slot";
2729
2730         /*** Unaware items ***/
2731         if (IS_FLG(FLG_UNAWARE))
2732         {
2733                 before_str[before_n++] = "unidentified";
2734                 whose_str[whose_n++] = "basic abilities are not known";
2735         }
2736
2737         /*** Unidentified ***/
2738         if (IS_FLG(FLG_UNIDENTIFIED))
2739                 before_str[before_n++] = "unidentified";
2740
2741         /*** Identified ***/
2742         if (IS_FLG(FLG_IDENTIFIED))
2743                 before_str[before_n++] = "identified";
2744
2745         /*** *Identified* ***/
2746         if (IS_FLG(FLG_STAR_IDENTIFIED))
2747                 before_str[before_n++] = "fully identified";
2748
2749         /*** Rare equipments ***/
2750         if (IS_FLG(FLG_RARE))
2751         {
2752                 before_str[before_n++] = "very rare";
2753                 body_str = "equipments";
2754                 after_str[after_n++] = "such as Dragon armor, Blades of Chaos, etc.";
2755         }
2756
2757         /*** Common equipments ***/
2758         if (IS_FLG(FLG_COMMON))
2759         {
2760                 before_str[before_n++] = "relatively common";
2761                 body_str = "equipments";
2762                 after_str[after_n++] = "compared to very rare Dragon armor, Blades of Chaos, etc.";
2763         }
2764
2765         /*** Worthless items ***/
2766         if (IS_FLG(FLG_WORTHLESS))
2767         {
2768                 before_str[before_n++] = "worthless";
2769                 which_str[which_n++] = "can not be sold at stores";
2770         }
2771
2772         /*** Artifacto ***/
2773         if (IS_FLG(FLG_ARTIFACT))
2774         {
2775                 before_str[before_n++] = "artifact";
2776         }
2777
2778         /*** Ego ***/
2779         if (IS_FLG(FLG_EGO))
2780         {
2781                 before_str[before_n++] = "ego";
2782         }
2783
2784         /*** Good ***/
2785         if (IS_FLG(FLG_GOOD))
2786         {
2787                 body_str = "equipment";
2788                 which_str[which_n++] = "have good quality";
2789         }
2790
2791         /*** Nameless ***/
2792         if (IS_FLG(FLG_NAMELESS))
2793         {
2794                 body_str = "equipment";
2795                 which_str[which_n++] = "is neither ego-item nor artifact";
2796         }
2797
2798         /*** Average ***/
2799         if (IS_FLG(FLG_AVERAGE))
2800         {
2801                 body_str = "equipment";
2802                 which_str[which_n++] = "have average quality";
2803         }
2804
2805         /*** Dice boosted (weapon of slaying) ***/
2806         if (IS_FLG(FLG_BOOSTED))
2807         {
2808                 body_str = "weapons";
2809                 whose_str[whose_n++] = "damage dice is bigger than normal";
2810         }
2811
2812         /*** Weapons whose dd*ds is more than nn ***/
2813         if (IS_FLG(FLG_MORE_DICE))
2814         {
2815                 static char more_than_desc_str[] =
2816                         "maximum damage from dice is bigger than __";
2817                 body_str = "weapons";
2818
2819                 sprintf(more_than_desc_str + sizeof(more_than_desc_str) - 3,
2820                         "%d", entry->dice);
2821                 whose_str[whose_n++] = more_than_desc_str;
2822         }
2823
2824         /*** Items whose magical bonus is more than nn ***/
2825         if (IS_FLG(FLG_MORE_BONUS))
2826         {
2827                 static char more_bonus_desc_str[] =
2828                         "magical bonus is bigger than (+__)";
2829
2830                 sprintf(more_bonus_desc_str + sizeof(more_bonus_desc_str) - 4,
2831                         "%d)", entry->bonus);
2832                 whose_str[whose_n++] = more_bonus_desc_str;
2833         }
2834
2835         /*** Wanted monster's corpse/skeletons ***/
2836         if (IS_FLG(FLG_WANTED))
2837         {
2838                 body_str = "corpse or skeletons";
2839                 which_str[which_n++] = "is wanted at the Hunter's Office";
2840         }
2841
2842         /*** Human corpse/skeletons (for Daemon magic) ***/
2843         if (IS_FLG(FLG_HUMAN))
2844         {
2845                 before_str[before_n++] = "humanoid";
2846                 body_str = "corpse or skeletons";
2847                 which_str[which_n++] = "can be used for Daemon magic";
2848         }
2849
2850         /*** Unique monster's corpse/skeletons/statues ***/
2851         if (IS_FLG(FLG_UNIQUE))
2852         {
2853                 before_str[before_n++] = "unique monster's";
2854                 body_str = "corpse or skeletons";
2855         }
2856
2857         /*** Unreadable spellbooks ***/
2858         if (IS_FLG(FLG_UNREADABLE))
2859         {
2860                 body_str = "spellbooks";
2861                 after_str[after_n++] = "of different realms from yours";
2862         }
2863
2864         /*** First realm spellbooks ***/
2865         if (IS_FLG(FLG_REALM1))
2866         {
2867                 body_str = "spellbooks";
2868                 after_str[after_n++] = "of your first realm";
2869         }
2870
2871         /*** Second realm spellbooks ***/
2872         if (IS_FLG(FLG_REALM2))
2873         {
2874                 body_str = "spellbooks";
2875                 after_str[after_n++] = "of your second realm";
2876         }
2877
2878         /*** First rank spellbooks ***/
2879         if (IS_FLG(FLG_FIRST))
2880         {
2881                 before_str[before_n++] = "first one of four";
2882                 body_str = "spellbooks";
2883         }
2884
2885         /*** Second rank spellbooks ***/
2886         if (IS_FLG(FLG_SECOND))
2887         {
2888                 before_str[before_n++] = "second one of four";
2889                 body_str = "spellbooks";
2890         }
2891
2892         /*** Third rank spellbooks ***/
2893         if (IS_FLG(FLG_THIRD))
2894         {
2895                 before_str[before_n++] = "third one of four";
2896                 body_str = "spellbooks";
2897         }
2898
2899         /*** Fourth rank spellbooks ***/
2900         if (IS_FLG(FLG_FOURTH))
2901         {
2902                 before_str[before_n++] = "fourth one of four";
2903                 body_str = "spellbooks";
2904         }
2905
2906         /*** Items ***/
2907         if (IS_FLG(FLG_ITEMS))
2908                 ; /* Nothing to do */
2909         else if (IS_FLG(FLG_WEAPONS))
2910                 body_str = "weapons";
2911         else if (IS_FLG(FLG_FAVORITE_WEAPONS))
2912                 body_str = "favorite weapons";
2913         else if (IS_FLG(FLG_ARMORS))
2914                 body_str = "armors";
2915         else if (IS_FLG(FLG_MISSILES))
2916                 body_str = "shots, arrows or crossbow bolts";
2917         else if (IS_FLG(FLG_DEVICES))
2918                 body_str = "scrolls, wands, staves or rods";
2919         else if (IS_FLG(FLG_LIGHTS))
2920                 body_str = "light sources";
2921         else if (IS_FLG(FLG_JUNKS))
2922                 body_str = "junk such as broken sticks";
2923         else if (IS_FLG(FLG_CORPSES))
2924                 body_str = "corpses or skeletons";
2925         else if (IS_FLG(FLG_SPELLBOOKS))
2926                 body_str = "spellbooks";
2927         else if (IS_FLG(FLG_HAFTED))
2928                 body_str = "hafted weapons";
2929         else if (IS_FLG(FLG_SHIELDS))
2930                 body_str = "shields";
2931         else if (IS_FLG(FLG_BOWS))
2932                 body_str = "slings, bows or crossbows";
2933         else if (IS_FLG(FLG_RINGS))
2934                 body_str = "rings";
2935         else if (IS_FLG(FLG_AMULETS))
2936                 body_str = "amulets";
2937         else if (IS_FLG(FLG_SUITS))
2938                 body_str = "body armors";
2939         else if (IS_FLG(FLG_CLOAKS))
2940                 body_str = "cloaks";
2941         else if (IS_FLG(FLG_HELMS))
2942                 body_str = "helms or crowns";
2943         else if (IS_FLG(FLG_GLOVES))
2944                 body_str = "gloves";
2945         else if (IS_FLG(FLG_BOOTS))
2946                 body_str = "boots";
2947
2948         /* Prepare a string for item name */
2949         if (*str)
2950         {
2951                 if (*str == '^')
2952                 {
2953                         str++;
2954                         top = TRUE;
2955                         whose_str[whose_n++] = "name is beginning with \"";
2956                 }
2957                 else
2958                         which_str[which_n++] = "have \"";
2959         }
2960
2961
2962         /* Describe action flag */
2963         if (act & DONT_AUTOPICK)
2964                 strcpy(buff, "Leave on floor ");
2965         else if (act & DO_AUTODESTROY)
2966                 strcpy(buff, "Destroy ");
2967         else if (act & DO_QUERY_AUTOPICK)
2968                 strcpy(buff, "Ask to pick up ");
2969         else
2970                 strcpy(buff, "Pickup ");
2971
2972         /* Auto-insctiption */
2973         if (insc)
2974         {
2975                 strncat(buff, format("and inscribe \"%s\"", insc), 80);
2976
2977                 if (my_strstr(insc, "%all"))
2978                         strcat(buff, ", replacing %all with code string representing all abilities,");
2979                 else if (my_strstr(insc, "%"))
2980                         strcat(buff, ", replacing % with code string representing extra random abilities,");
2981
2982                 strcat(buff, " on ");
2983         }
2984
2985         /* Adjective */
2986         if (!before_n)
2987                 strcat(buff, "all ");
2988         else for (i = 0; i < before_n && before_str[i]; i++)
2989         {
2990                 strcat(buff, before_str[i]);
2991                 strcat(buff, " ");
2992         }
2993
2994         /* Item class */
2995         strcat(buff, body_str);
2996
2997         /* of ... */
2998         for (i = 0; i < after_n && after_str[i]; i++)
2999         {
3000                 strcat(buff, " ");
3001                 strcat(buff, after_str[i]);
3002         }
3003
3004         /* which ... */
3005         for (i = 0; i < whose_n && whose_str[i]; i++)
3006         {
3007                 if (i == 0)
3008                         strcat(buff, " whose ");
3009                 else
3010                         strcat(buff, ", and ");
3011
3012                 strcat(buff, whose_str[i]);
3013         }
3014
3015         /* Item name ; whose name is beginning with "str" */
3016         if (*str && top)
3017         {
3018                 strcat(buff, str);
3019                 strcat(buff, "\"");
3020         }
3021
3022         /* whose ..., and which .... */
3023         if (whose_n && which_n)
3024                 strcat(buff, ", and ");
3025
3026         /* which ... */
3027         for (i = 0; i < which_n && which_str[i]; i++)
3028         {
3029                 if (i == 0)
3030                         strcat(buff, " which ");
3031                 else
3032                         strcat(buff, ", and ");
3033
3034                 strcat(buff, which_str[i]);
3035         }
3036
3037         /* Item name ; which have "str" as part of its name */
3038         if (*str && !top)
3039         {
3040                 strncat(buff, str, 80);
3041                 strcat(buff, "\" as part of its name");
3042         }
3043         strcat(buff, ".");
3044
3045         /* Describe whether it will be displayed on the full map or not */
3046         if (act & DO_DISPLAY)
3047         {
3048                 if (act & DONT_AUTOPICK)
3049                         strcat(buff, "  Display these items when you press the N key in the full 'M'ap.");
3050                 else if (act & DO_AUTODESTROY)
3051                         strcat(buff, "  Display these items when you press the K key in the full 'M'ap.");
3052                 else
3053                         strcat(buff, "  Display these items when you press the M key in the full 'M'ap.");
3054         }
3055         else
3056                 strcat(buff, " Not displayed in the full map.");
3057 #endif /* JP */
3058
3059 }
3060
3061
3062 /*
3063  * Read whole lines of a file to memory
3064  */
3065 static concptr *read_text_lines(concptr filename)
3066 {
3067         concptr *lines_list = NULL;
3068         FILE *fff;
3069
3070         int lines = 0;
3071         char buf[1024];
3072
3073         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, filename);
3074         fff = my_fopen(buf, "r");
3075         if (!fff) return NULL;
3076
3077         /* Allocate list of pointers */
3078         C_MAKE(lines_list, MAX_LINES, concptr);
3079
3080         /* Parse it */
3081         while (my_fgets(fff, buf, sizeof(buf)) == 0)
3082         {
3083                 lines_list[lines++] = string_make(buf);
3084                 if (lines >= MAX_LINES - 1) break;
3085         }
3086
3087         if (lines == 0)
3088                 lines_list[0] = string_make("");
3089
3090         my_fclose(fff);
3091         return lines_list;
3092 }
3093
3094
3095 /*
3096  * Copy the default autopick file to the user directory
3097  */
3098 static void prepare_default_pickpref(player_type *player_ptr)
3099 {
3100         const concptr messages[] = {
3101                 _("あなたは「自動拾いエディタ」を初めて起動しました。", "You have activated the Auto-Picker Editor for the first time."),
3102                 _("自動拾いのユーザー設定ファイルがまだ書かれていないので、", "Since user pref file for autopick is not yet created,"),
3103                 _("基本的な自動拾い設定ファイルをlib/pref/picktype.prfからコピーします。", "the default setting is loaded from lib/pref/pickpref.prf ."),
3104                 NULL
3105         };
3106
3107         concptr filename = pickpref_filename(player_ptr, PT_DEFAULT);
3108
3109         /* Display messages */
3110         for (int i = 0; messages[i]; i++)
3111         {
3112                 msg_print(messages[i]);
3113         }
3114
3115         msg_print(NULL);
3116
3117         /* Open new file */
3118         char buf[1024];
3119         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, filename);
3120         FILE *user_fp;
3121         user_fp = my_fopen(buf, "w");
3122
3123         /* Failed */
3124         if (!user_fp) return;
3125
3126         /* Write header messages for a notification */
3127         fprintf(user_fp, "#***\n");
3128         for (int i = 0; messages[i]; i++)
3129         {
3130                 fprintf(user_fp, "#***  %s\n", messages[i]);
3131         }
3132
3133         fprintf(user_fp, "#***\n\n\n");
3134
3135         /* Open the default file */
3136         path_build(buf, sizeof(buf), ANGBAND_DIR_PREF, filename);
3137         FILE *pref_fp;
3138         pref_fp = my_fopen(buf, "r");
3139
3140         /* Failed */
3141         if (!pref_fp)
3142         {
3143                 my_fclose(user_fp);
3144                 return;
3145         }
3146
3147         /* Copy the contents of default file */
3148         while (!my_fgets(pref_fp, buf, sizeof(buf)))
3149         {
3150                 fprintf(user_fp, "%s\n", buf);
3151         }
3152
3153         my_fclose(user_fp);
3154         my_fclose(pref_fp);
3155 }
3156
3157 /*
3158  * Read an autopick prefence file to memory
3159  * Prepare default if no user file is found
3160  */
3161 static concptr *read_pickpref_text_lines(player_type *player_ptr, int *filename_mode_p)
3162 {
3163         /* Try a filename with player name */
3164         *filename_mode_p = PT_WITH_PNAME;
3165         char buf[1024];
3166         strcpy(buf, pickpref_filename(player_ptr, *filename_mode_p));
3167         concptr *lines_list;
3168         lines_list = read_text_lines(buf);
3169
3170         if (!lines_list)
3171         {
3172                 *filename_mode_p = PT_DEFAULT;
3173                 strcpy(buf, pickpref_filename(player_ptr, *filename_mode_p));
3174                 lines_list = read_text_lines(buf);
3175         }
3176
3177         if (!lines_list)
3178         {
3179                 prepare_default_pickpref(player_ptr);
3180                 lines_list = read_text_lines(buf);
3181         }
3182
3183         if (!lines_list)
3184         {
3185                 C_MAKE(lines_list, MAX_LINES, concptr);
3186                 lines_list[0] = string_make("");
3187         }
3188
3189         return lines_list;
3190 }
3191
3192
3193 /*
3194  * Write whole lines of memory to a file.
3195  */
3196 static bool write_text_lines(concptr filename, concptr *lines_list)
3197 {
3198         char buf[1024];
3199         path_build(buf, sizeof(buf), ANGBAND_DIR_USER, filename);
3200         FILE *fff;
3201         fff = my_fopen(buf, "w");
3202         if (!fff) return FALSE;
3203
3204         for (int lines = 0; lines_list[lines]; lines++)
3205         {
3206                 my_fputs(fff, lines_list[lines], 1024);
3207         }
3208
3209         my_fclose(fff);
3210         return TRUE;
3211 }
3212
3213
3214 /*
3215  * Free memory of lines_list.
3216  */
3217 static void free_text_lines(concptr *lines_list)
3218 {
3219         for (int lines = 0; lines_list[lines]; lines++)
3220         {
3221                 string_free(lines_list[lines]);
3222         }
3223
3224         /* free list of pointers */
3225         C_KILL(lines_list, MAX_LINES, concptr);
3226 }
3227
3228
3229 /*
3230  * Delete or insert string
3231  */
3232 static void toggle_keyword(text_body_type *tb, BIT_FLAGS flg)
3233 {
3234         int by1, by2;
3235         bool add = TRUE;
3236         bool fixed = FALSE;
3237
3238         /* Some lines are selected */
3239         if (tb->mark)
3240         {
3241                 by1 = MIN(tb->my, tb->cy);
3242                 by2 = MAX(tb->my, tb->cy);
3243         }
3244
3245         /* No mark -- Select current line */
3246         else /* if (!tb->mark) */
3247         {
3248                 by1 = by2 = tb->cy;
3249         }
3250
3251
3252         /* Set/Reset flag of each line */
3253         for (int y = by1; y <= by2; y++)
3254         {
3255                 autopick_type an_entry, *entry = &an_entry;
3256
3257                 if (!autopick_new_entry(entry, tb->lines_list[y], !fixed)) continue;
3258
3259                 string_free(tb->lines_list[y]);
3260
3261                 if (!fixed)
3262                 {
3263                         /* Add? or Remove? */
3264                         if (!IS_FLG(flg)) add = TRUE;
3265                         else add = FALSE;
3266
3267                         /* No more change */
3268                         fixed = TRUE;
3269                 }
3270
3271                 /* You can use only one noun flag */
3272                 if (FLG_NOUN_BEGIN <= flg && flg <= FLG_NOUN_END)
3273                 {
3274                         int i;
3275                         for (i = FLG_NOUN_BEGIN; i <= FLG_NOUN_END; i++)
3276                                 REM_FLG(i);
3277                 }
3278
3279                 /* You can use only one identify state flag */
3280                 else if (FLG_UNAWARE <= flg && flg <= FLG_STAR_IDENTIFIED)
3281                 {
3282                         int i;
3283                         for (i = FLG_UNAWARE; i <= FLG_STAR_IDENTIFIED; i++)
3284                                 REM_FLG(i);
3285                 }
3286
3287                 /* You can use only one flag in artifact/ego/nameless */
3288                 else if (FLG_ARTIFACT <= flg && flg <= FLG_AVERAGE)
3289                 {
3290                         int i;
3291                         for (i = FLG_ARTIFACT; i <= FLG_AVERAGE; i++)
3292                                 REM_FLG(i);
3293                 }
3294
3295                 /* You can use only one flag in rare/common */
3296                 else if (FLG_RARE <= flg && flg <= FLG_COMMON)
3297                 {
3298                         int i;
3299                         for (i = FLG_RARE; i <= FLG_COMMON; i++)
3300                                 REM_FLG(i);
3301                 }
3302
3303                 if (add) ADD_FLG(flg);
3304                 else REM_FLG(flg);
3305
3306                 tb->lines_list[y] = autopick_line_from_entry_kill(entry);
3307
3308                 /* Now dirty */
3309                 tb->dirty_flags |= DIRTY_ALL;
3310
3311                 /* Text is changed */
3312                 tb->changed = TRUE;
3313         }
3314 }
3315
3316
3317 /*
3318  * Change command letter
3319  */
3320 static void toggle_command_letter(text_body_type *tb, byte flg)
3321 {
3322         autopick_type an_entry, *entry = &an_entry;
3323         int by1, by2, y;
3324         bool add = TRUE;
3325         bool fixed = FALSE;
3326
3327         /* Some lines are selected */
3328         if (tb->mark)
3329         {
3330                 by1 = MIN(tb->my, tb->cy);
3331                 by2 = MAX(tb->my, tb->cy);
3332         }
3333
3334         /* No mark -- Select current line */
3335         else /* if (!tb->mark) */
3336         {
3337                 by1 = by2 = tb->cy;
3338         }
3339
3340
3341         /* Set/Reset flag of each line */
3342         for (y = by1; y <= by2; y++)
3343         {
3344                 int wid = 0;
3345
3346                 if (!autopick_new_entry(entry, tb->lines_list[y], FALSE)) continue;
3347
3348                 string_free(tb->lines_list[y]);
3349
3350                 if (!fixed)
3351                 {
3352                         /* Add? or Remove? */
3353                         if (!(entry->action & flg)) add = TRUE;
3354                         else add = FALSE;
3355
3356                         /* No more change */
3357                         fixed = TRUE;
3358                 }
3359
3360                 /* Count number of letter (by negative number) */
3361                 if (entry->action & DONT_AUTOPICK) wid--;
3362                 else if (entry->action & DO_AUTODESTROY) wid--;
3363                 else if (entry->action & DO_QUERY_AUTOPICK) wid--;
3364                 if (!(entry->action & DO_DISPLAY)) wid--;
3365
3366                 /* Set/Reset the flag */
3367                 if (flg != DO_DISPLAY)
3368                 {
3369                         entry->action &= ~(DO_AUTOPICK | DONT_AUTOPICK | DO_AUTODESTROY | DO_QUERY_AUTOPICK);
3370                         if (add) entry->action |= flg;
3371                         else entry->action |= DO_AUTOPICK;
3372                 }
3373                 else
3374                 {
3375                         entry->action &= ~(DO_DISPLAY);
3376                         if (add) entry->action |= flg;
3377                 }
3378
3379                 /* Correct cursor location */
3380                 if (tb->cy == y)
3381                 {
3382                         if (entry->action & DONT_AUTOPICK) wid++;
3383                         else if (entry->action & DO_AUTODESTROY) wid++;
3384                         else if (entry->action & DO_QUERY_AUTOPICK) wid++;
3385                         if (!(entry->action & DO_DISPLAY)) wid++;
3386
3387                         if (wid > 0) tb->cx++;
3388                         if (wid < 0 && tb->cx > 0) tb->cx--;
3389                 }
3390
3391                 tb->lines_list[y] = autopick_line_from_entry_kill(entry);
3392
3393                 /* Now dirty */
3394                 tb->dirty_flags |= DIRTY_ALL;
3395
3396                 /* Text is changed */
3397                 tb->changed = TRUE;
3398         }
3399 }
3400
3401 /*
3402  * Delete or insert string
3403  */
3404 static void add_keyword(text_body_type *tb, BIT_FLAGS flg)
3405 {
3406         int by1, by2;
3407
3408         /* Some lines are selected */
3409         if (tb->mark)
3410         {
3411                 by1 = MIN(tb->my, tb->cy);
3412                 by2 = MAX(tb->my, tb->cy);
3413         }
3414
3415         /* No mark -- Select current line */
3416         else /* if (!tb->mark) */
3417         {
3418                 by1 = by2 = tb->cy;
3419         }
3420
3421         /* Set/Reset flag of each line */
3422         for (int y = by1; y <= by2; y++)
3423         {
3424                 autopick_type an_entry, *entry = &an_entry;
3425
3426                 if (!autopick_new_entry(entry, tb->lines_list[y], FALSE)) continue;
3427
3428                 if (IS_FLG(flg))
3429                 {
3430                         autopick_free_entry(entry);
3431                         continue;
3432                 }
3433
3434                 string_free(tb->lines_list[y]);
3435
3436                 /* Remove all noun flag */
3437                 if (FLG_NOUN_BEGIN <= flg && flg <= FLG_NOUN_END)
3438                 {
3439                         int i;
3440                         for (i = FLG_NOUN_BEGIN; i <= FLG_NOUN_END; i++)
3441                                 REM_FLG(i);
3442                 }
3443
3444                 ADD_FLG(flg);
3445
3446                 tb->lines_list[y] = autopick_line_from_entry_kill(entry);
3447
3448                 /* Now dirty */
3449                 tb->dirty_flags |= DIRTY_ALL;
3450
3451                 /* Text is changed */
3452                 tb->changed = TRUE;
3453         }
3454 }
3455
3456
3457 /*
3458  * Check if this line is expression or not.
3459  * And update it if it is.
3460  */
3461 static void check_expression_line(text_body_type *tb, int y)
3462 {
3463         concptr s = tb->lines_list[y];
3464
3465         if ((s[0] == '?' && s[1] == ':') ||
3466                 (tb->states[y] & LSTAT_BYPASS))
3467         {
3468                 /* Expressions need re-evaluation */
3469                 tb->dirty_flags |= DIRTY_EXPRESSION;
3470         }
3471 }
3472
3473
3474 /*
3475  * Add an empty line at the last of the file
3476  */
3477 static bool add_empty_line(text_body_type *tb)
3478 {
3479         int k;
3480
3481         for (k = 0; tb->lines_list[k]; k++)
3482                 /* count number of lines */;
3483
3484         /* Too many lines! */
3485         if (k >= MAX_LINES - 2) return FALSE;
3486
3487         /* The last line is already empty */
3488         if (!tb->lines_list[k - 1][0]) return FALSE;
3489
3490         /* Create new empty line */
3491         tb->lines_list[k] = string_make("");
3492
3493         /* Expressions need re-evaluation */
3494         tb->dirty_flags |= DIRTY_EXPRESSION;
3495
3496         /* Text is changed */
3497         tb->changed = TRUE;
3498
3499         /* A line is added */
3500         return TRUE;
3501 }
3502
3503
3504 /*
3505  * Insert return code and split the line
3506  */
3507 static bool insert_return_code(text_body_type *tb)
3508 {
3509         char buf[MAX_LINELEN];
3510         int i, j, k;
3511
3512         for (k = 0; tb->lines_list[k]; k++)
3513                 /* count number of lines */;
3514
3515         if (k >= MAX_LINES - 2) return FALSE;
3516         k--;
3517
3518         /* Move down lines */
3519         for (; tb->cy < k; k--)
3520         {
3521                 tb->lines_list[k + 1] = tb->lines_list[k];
3522                 tb->states[k + 1] = tb->states[k];
3523         }
3524
3525         /* Split current line */
3526         for (i = j = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
3527         {
3528 #ifdef JP
3529                 if (iskanji(tb->lines_list[tb->cy][i]))
3530                         buf[j++] = tb->lines_list[tb->cy][i++];
3531 #endif
3532                 buf[j++] = tb->lines_list[tb->cy][i];
3533         }
3534
3535         buf[j] = '\0';
3536         tb->lines_list[tb->cy + 1] = string_make(&tb->lines_list[tb->cy][i]);
3537         string_free(tb->lines_list[tb->cy]);
3538         tb->lines_list[tb->cy] = string_make(buf);
3539
3540         /* Expressions need re-evaluation */
3541         tb->dirty_flags |= DIRTY_EXPRESSION;
3542
3543         /* Text is changed */
3544         tb->changed = TRUE;
3545         return TRUE;
3546 }
3547
3548
3549 /*
3550  * Choose an item and get auto-picker entry from it.
3551  */
3552 static bool entry_from_choosed_object(player_type *player_ptr, autopick_type *entry)
3553 {
3554         concptr q = _("どのアイテムを登録しますか? ", "Enter which item? ");
3555         concptr s = _("アイテムを持っていない。", "You have nothing to enter.");
3556         object_type *o_ptr;
3557         o_ptr = choose_object(player_ptr, NULL, q, s, USE_INVEN | USE_FLOOR | USE_EQUIP, 0);
3558         if (!o_ptr) return FALSE;
3559
3560         autopick_entry_from_object(player_ptr, entry, o_ptr);
3561         return TRUE;
3562 }
3563
3564
3565 /*
3566  * Choose an item for search
3567  */
3568 static bool get_object_for_search(player_type *player_ptr, object_type **o_handle, concptr *search_strp)
3569 {
3570         concptr q = _("どのアイテムを検索しますか? ", "Enter which item? ");
3571         concptr s = _("アイテムを持っていない。", "You have nothing to enter.");
3572         object_type *o_ptr;
3573         o_ptr = choose_object(player_ptr, NULL, q, s, USE_INVEN | USE_FLOOR | USE_EQUIP, 0);
3574         if (!o_ptr) return FALSE;
3575
3576         *o_handle = o_ptr;
3577
3578         string_free(*search_strp);
3579         char buf[MAX_NLEN + 20];
3580         object_desc(buf, *o_handle, (OD_NO_FLAVOR | OD_OMIT_PREFIX | OD_NO_PLURAL));
3581         *search_strp = string_make(format("<%s>", buf));
3582         return TRUE;
3583 }
3584
3585
3586 /*
3587  * Prepare for search by destroyed object
3588  */
3589 static bool get_destroyed_object_for_search(object_type **o_handle, concptr *search_strp)
3590 {
3591         if (!autopick_last_destroyed_object.k_idx) return FALSE;
3592
3593         *o_handle = &autopick_last_destroyed_object;
3594
3595         string_free(*search_strp);
3596         char buf[MAX_NLEN + 20];
3597         object_desc(buf, *o_handle, (OD_NO_FLAVOR | OD_OMIT_PREFIX | OD_NO_PLURAL));
3598         *search_strp = string_make(format("<%s>", buf));
3599         return TRUE;
3600 }
3601
3602
3603 /*
3604  * Choose an item or string for search
3605  */
3606 static byte get_string_for_search(player_type *player_ptr, object_type **o_handle, concptr *search_strp)
3607 {
3608         /*
3609          * Text color
3610          * TERM_YELLOW : Overwrite mode
3611          * TERM_WHITE : Insert mode
3612          */
3613         byte color = TERM_YELLOW;
3614         char buf[MAX_NLEN + 20];
3615         const int len = 80;
3616
3617         char prompt[] = _("検索(^I:持ち物 ^L:破壊された物): ", "Search key(^I:inven ^L:destroyed): ");
3618         int col = sizeof(prompt) - 1;
3619
3620         /* Prepare string buffer for edit */
3621         if (*search_strp) strcpy(buf, *search_strp);
3622         else buf[0] = '\0';
3623
3624         /* Object searching mode */
3625         if (*o_handle) color = TERM_L_GREEN;
3626
3627         /* Display prompt */
3628         prt(prompt, 0, 0);
3629
3630         /* Process input */
3631         int pos = 0;
3632         while (TRUE)
3633         {
3634                 bool back = FALSE;
3635                 int skey;
3636
3637                 /* Display the string */
3638                 Term_erase(col, 0, 255);
3639                 Term_putstr(col, 0, -1, color, buf);
3640
3641                 /* Place cursor */
3642                 Term_gotoxy(col + pos, 0);
3643
3644                 /* Get a special key code */
3645                 skey = inkey_special(TRUE);
3646
3647                 /* Analyze the key */
3648                 switch (skey)
3649                 {
3650                 case SKEY_LEFT:
3651                 case KTRL('b'):
3652                 {
3653                         int i = 0;
3654
3655                         /* Now on insert mode */
3656                         color = TERM_WHITE;
3657
3658                         /* No move at beginning of line */
3659                         if (0 == pos) break;
3660
3661                         while (TRUE)
3662                         {
3663                                 int next_pos = i + 1;
3664
3665 #ifdef JP
3666                                 if (iskanji(buf[i])) next_pos++;
3667 #endif
3668
3669                                 /* Is there the cursor at next position? */
3670                                 if (next_pos >= pos) break;
3671
3672                                 /* Move to next */
3673                                 i = next_pos;
3674                         }
3675
3676                         /* Get previous position */
3677                         pos = i;
3678
3679                         break;
3680                 }
3681
3682                 case SKEY_RIGHT:
3683                 case KTRL('f'):
3684                         /* Now on insert mode */
3685                         color = TERM_WHITE;
3686
3687                         /* No move at end of line */
3688                         if ('\0' == buf[pos]) break;
3689
3690 #ifdef JP
3691                         /* Move right */
3692                         if (iskanji(buf[pos])) pos += 2;
3693                         else pos++;
3694 #else
3695                         pos++;
3696 #endif
3697
3698                         break;
3699
3700                 case ESCAPE:
3701                         return 0;
3702
3703                 case KTRL('r'):
3704                         back = TRUE;
3705                         /* Fall through */
3706
3707                 case '\n':
3708                 case '\r':
3709                 case KTRL('s'):
3710                         if (*o_handle) return (back ? -1 : 1);
3711                         string_free(*search_strp);
3712                         *search_strp = string_make(buf);
3713                         *o_handle = NULL;
3714                         return (back ? -1 : 1);
3715
3716                 case KTRL('i'):
3717                         return get_object_for_search(player_ptr, o_handle, search_strp);
3718
3719                 case KTRL('l'):
3720                         /* Prepare string for destroyed object if there is one. */
3721                         if (get_destroyed_object_for_search(o_handle, search_strp))
3722                                 return 1;
3723                         break;
3724
3725                 case '\010':
3726                 {
3727                         /* Backspace */
3728
3729                         int i = 0;
3730
3731                         /* Now on insert mode */
3732                         color = TERM_WHITE;
3733
3734                         /* No move at beginning of line */
3735                         if (0 == pos) break;
3736
3737                         while (TRUE)
3738                         {
3739                                 int next_pos = i + 1;
3740
3741 #ifdef JP
3742                                 if (iskanji(buf[i])) next_pos++;
3743 #endif
3744
3745                                 /* Is there the cursor at next position? */
3746                                 if (next_pos >= pos) break;
3747
3748                                 /* Move to next */
3749                                 i = next_pos;
3750                         }
3751
3752                         /* Get previous position */
3753                         pos = i;
3754
3755                         /* Fall through to 'Delete key' */
3756                 }
3757
3758                 case 0x7F:
3759                 case KTRL('d'):
3760                         /* Delete key */
3761                 {
3762                         int dst, src;
3763
3764                         /* Now on insert mode */
3765                         color = TERM_WHITE;
3766
3767                         /* No move at end of line */
3768                         if ('\0' == buf[pos]) break;
3769
3770                         /* Position of next character */
3771                         src = pos + 1;
3772
3773 #ifdef JP
3774                         /* Next character is one more byte away */
3775                         if (iskanji(buf[pos])) src++;
3776 #endif
3777
3778                         dst = pos;
3779
3780                         /* Move characters at src to dst */
3781                         while ('\0' != (buf[dst++] = buf[src++]))
3782                                 /* loop */;
3783
3784                         break;
3785                 }
3786
3787                 default:
3788                 {
3789                         /* Insert a character */
3790
3791                         char tmp[100];
3792                         char c;
3793
3794                         /* Ignore special keys */
3795                         if (skey & SKEY_MASK) break;
3796
3797                         /* Get a character code */
3798                         c = (char)skey;
3799
3800                         /* Was non insert mode? */
3801                         if (color != TERM_WHITE)
3802                         {
3803                                 /* Was object searching mode */
3804                                 if (color == TERM_L_GREEN)
3805                                 {
3806                                         /* Cancel the mode */
3807                                         *o_handle = NULL;
3808
3809                                         /* Remove indicating string */
3810                                         string_free(*search_strp);
3811                                         *search_strp = NULL;
3812                                 }
3813
3814                                 /* Overwrite default string */
3815                                 buf[0] = '\0';
3816
3817                                 /* Go to insert mode */
3818                                 color = TERM_WHITE;
3819                         }
3820
3821                         /* Save right part of string */
3822                         strcpy(tmp, buf + pos);
3823 #ifdef JP
3824                         if (iskanji(c))
3825                         {
3826                                 char next;
3827
3828                                 /* Bypass macro processing */
3829                                 inkey_base = TRUE;
3830                                 next = inkey();
3831
3832                                 if (pos + 1 < len)
3833                                 {
3834                                         buf[pos++] = c;
3835                                         buf[pos++] = next;
3836                                 }
3837                                 else
3838                                 {
3839                                         bell();
3840                                 }
3841                         }
3842                         else
3843 #endif
3844                         {
3845 #ifdef JP
3846                                 if (pos < len && (isprint(c) || iskana(c)))
3847 #else
3848                                 if (pos < len && isprint(c))
3849 #endif
3850                                 {
3851                                         buf[pos++] = c;
3852                                 }
3853                                 else
3854                                 {
3855                                         bell();
3856                                 }
3857                         }
3858
3859                         /* Terminate */
3860                         buf[pos] = '\0';
3861
3862                         /* Write back the left part of string */
3863                         my_strcat(buf, tmp, len + 1);
3864
3865                         break;
3866                 } /* default: */
3867
3868                 }
3869
3870                 /* Object searching mode was cancelled? */
3871                 if (*o_handle == NULL || color == TERM_L_GREEN) continue;
3872
3873                 *o_handle = NULL;
3874                 buf[0] = '\0';
3875                 string_free(*search_strp);
3876                 *search_strp = NULL;
3877         }
3878 }
3879
3880
3881 /*
3882  * Search next line matches for o_ptr
3883  */
3884 static void search_for_object(player_type *player_ptr, text_body_type *tb, object_type *o_ptr, bool forward)
3885 {
3886         autopick_type an_entry, *entry = &an_entry;
3887         GAME_TEXT o_name[MAX_NLEN];
3888         int bypassed_cy = -1;
3889
3890         /* Start searching from current cursor position */
3891         int i = tb->cy;
3892
3893         /* Prepare object name string first */
3894         object_desc(o_name, o_ptr, (OD_NO_FLAVOR | OD_OMIT_PREFIX | OD_NO_PLURAL));
3895
3896         /* Convert the string to lower case */
3897         str_tolower(o_name);
3898
3899         while (TRUE)
3900         {
3901                 bool match;
3902
3903                 /* End of list? */
3904                 if (forward)
3905                 {
3906                         if (!tb->lines_list[++i]) break;
3907                 }
3908                 else
3909                 {
3910                         if (--i < 0) break;
3911                 }
3912
3913                 /* Is this line is a correct entry? */
3914                 if (!autopick_new_entry(entry, tb->lines_list[i], FALSE)) continue;
3915
3916                 /* Does this line match to the object? */
3917                 match = is_autopick_aux(player_ptr, o_ptr, entry, o_name);
3918                 autopick_free_entry(entry);
3919                 if (!match)     continue;
3920
3921                 /* Found a line but it's inactive */
3922                 if (tb->states[i] & LSTAT_BYPASS)
3923                 {
3924                         /* If it is first found, remember it */
3925                         if (bypassed_cy == -1) bypassed_cy = i;
3926                         continue;
3927                 }
3928
3929                 /* Move to this line */
3930                 tb->cx = 0;
3931                 tb->cy = i;
3932
3933                 if (bypassed_cy != -1)
3934                 {
3935                         /* Mark as some lines are skipped */
3936                         tb->dirty_flags |= DIRTY_SKIP_INACTIVE;
3937                 }
3938
3939                 return;
3940         }
3941
3942         if (bypassed_cy == -1)
3943         {
3944                 tb->dirty_flags |= DIRTY_NOT_FOUND;
3945                 return;
3946         }
3947
3948         tb->cx = 0;
3949         tb->cy = bypassed_cy;
3950         tb->dirty_flags |= DIRTY_INACTIVE;
3951 }
3952
3953
3954 /*
3955  * Search next line matches to the string
3956  */
3957 static void search_for_string(text_body_type *tb, concptr search_str, bool forward)
3958 {
3959         int bypassed_cy = -1;
3960         int bypassed_cx = 0;
3961
3962         /* Start searching from current cursor position */
3963         int i = tb->cy;
3964
3965         while (TRUE)
3966         {
3967                 concptr pos;
3968
3969                 /* End of list? */
3970                 if (forward)
3971                 {
3972                         if (!tb->lines_list[++i]) break;
3973                 }
3974                 else
3975                 {
3976                         if (--i < 0) break;
3977                 }
3978
3979                 /* Look for the string pattern */
3980                 pos = my_strstr(tb->lines_list[i], search_str);
3981
3982                 /* Not found! */
3983                 if (!pos) continue;
3984
3985                 /* Found a line but it's inactive */
3986                 if ((tb->states[i] & LSTAT_BYPASS) &&
3987                         !(tb->states[i] & LSTAT_EXPRESSION))
3988                 {
3989                         /* If it is first found, remember it */
3990                         if (bypassed_cy == -1)
3991                         {
3992                                 bypassed_cy = i;
3993                                 bypassed_cx = (int)(pos - tb->lines_list[i]);
3994                         }
3995
3996                         continue;
3997                 }
3998
3999                 tb->cx = (int)(pos - tb->lines_list[i]);
4000                 tb->cy = i;
4001
4002                 if (bypassed_cy != -1)
4003                 {
4004                         /* Mark as some lines are skipped */
4005                         tb->dirty_flags |= DIRTY_SKIP_INACTIVE;
4006                 }
4007
4008                 return;
4009         }
4010
4011         if (bypassed_cy == -1)
4012         {
4013                 tb->dirty_flags |= DIRTY_NOT_FOUND;
4014                 return;
4015         }
4016
4017         tb->cx = bypassed_cx;
4018         tb->cy = bypassed_cy;
4019         tb->dirty_flags |= DIRTY_INACTIVE;
4020 }
4021
4022
4023 /*
4024  * Find a command by 'key'.
4025  */
4026 static int get_com_id(char key)
4027 {
4028         for (int i = 0; menu_data[i].name; i++)
4029         {
4030                 if (menu_data[i].key == key)
4031                 {
4032                         return menu_data[i].com_id;
4033                 }
4034         }
4035
4036         return 0;
4037 }
4038
4039
4040 /*
4041  * Display the menu, and get a command
4042  */
4043 static int do_command_menu(int level, int start)
4044 {
4045         int max_len = 0;
4046         int max_menu_wid;
4047         int col0 = 5 + level * 7;
4048         int row0 = 1 + level * 3;
4049         byte menu_key = 0;
4050         int menu_id_list[26];
4051         bool redraw = TRUE;
4052         char linestr[MAX_LINELEN];
4053
4054         /* Get max length */
4055         menu_key = 0;
4056         for (int i = start; menu_data[i].level >= level; i++)
4057         {
4058                 int len;
4059
4060                 /* Ignore lower level sub menus */
4061                 if (menu_data[i].level > level) continue;
4062
4063                 len = strlen(menu_data[i].name);
4064                 if (len > max_len) max_len = len;
4065
4066                 menu_id_list[menu_key] = i;
4067                 menu_key++;
4068         }
4069
4070         while (menu_key < 26)
4071         {
4072                 menu_id_list[menu_key] = -1;
4073                 menu_key++;
4074         }
4075
4076         /* Extra space for displaying menu key and command key */
4077         max_menu_wid = max_len + 3 + 3;
4078
4079         /* Prepare box line */
4080         linestr[0] = '\0';
4081         strcat(linestr, "+");
4082         for (int i = 0; i < max_menu_wid + 2; i++)
4083         {
4084                 strcat(linestr, "-");
4085         }
4086
4087         strcat(linestr, "+");
4088
4089         while (TRUE)
4090         {
4091                 int com_id;
4092                 char key;
4093                 int menu_id;
4094
4095                 if (redraw)
4096                 {
4097                         int row1 = row0 + 1;
4098
4099                         /* Draw top line */
4100                         Term_putstr(col0, row0, -1, TERM_WHITE, linestr);
4101
4102                         /* Draw menu items */
4103                         menu_key = 0;
4104                         for (int i = start; menu_data[i].level >= level; i++)
4105                         {
4106                                 char com_key_str[3];
4107                                 concptr str;
4108
4109                                 /* Ignore lower level sub menus */
4110                                 if (menu_data[i].level > level) continue;
4111
4112                                 if (menu_data[i].com_id == -1)
4113                                 {
4114                                         strcpy(com_key_str, _("▼", ">"));
4115                                 }
4116                                 else if (menu_data[i].key != -1)
4117                                 {
4118                                         com_key_str[0] = '^';
4119                                         com_key_str[1] = menu_data[i].key + '@';
4120                                         com_key_str[2] = '\0';
4121                                 }
4122                                 else
4123                                 {
4124                                         com_key_str[0] = '\0';
4125                                 }
4126
4127                                 str = format("| %c) %-*s %2s | ", menu_key + 'a', max_len, menu_data[i].name, com_key_str);
4128
4129                                 Term_putstr(col0, row1++, -1, TERM_WHITE, str);
4130
4131                                 menu_key++;
4132                         }
4133
4134                         /* Draw bottom line */
4135                         Term_putstr(col0, row1, -1, TERM_WHITE, linestr);
4136
4137                         /* The menu was shown */
4138                         redraw = FALSE;
4139                 }
4140
4141                 prt(format(_("(a-%c) コマンド:", "(a-%c) Command:"), menu_key + 'a' - 1), 0, 0);
4142                 key = inkey();
4143
4144                 if (key == ESCAPE) return 0;
4145
4146                 bool is_alphabet = key >= 'a' && key <= 'z';
4147                 if (!is_alphabet)
4148                 {
4149                         com_id = get_com_id(key);
4150                         if (com_id)
4151                         {
4152                                 return com_id;
4153                         }
4154
4155                         continue;
4156                 }
4157
4158                 menu_id = menu_id_list[key - 'a'];
4159
4160                 if (menu_id < 0) continue;
4161
4162                 com_id = menu_data[menu_id].com_id;
4163
4164                 if (com_id == -1)
4165                 {
4166                         com_id = do_command_menu(level + 1, menu_id + 1);
4167
4168                         if (com_id) return com_id;
4169                         else redraw = TRUE;
4170                 }
4171                 else if (com_id)
4172                 {
4173                         return com_id;
4174                 }
4175         }
4176 }
4177
4178
4179 static chain_str_type *new_chain_str(concptr str)
4180 {
4181         chain_str_type *chain;
4182         size_t len = strlen(str);
4183         chain = (chain_str_type *)ralloc(sizeof(chain_str_type) + len * sizeof(char));
4184         strcpy(chain->s, str);
4185         chain->next = NULL;
4186         return chain;
4187 }
4188
4189
4190 static void kill_yank_chain(text_body_type *tb)
4191 {
4192         chain_str_type *chain = tb->yank;
4193         tb->yank = NULL;
4194         tb->yank_eol = TRUE;
4195
4196         while (chain)
4197         {
4198                 chain_str_type *next = chain->next;
4199                 size_t len = strlen(chain->s);
4200
4201                 rnfree(chain, sizeof(chain_str_type) + len * sizeof(char));
4202
4203                 chain = next;
4204         }
4205 }
4206
4207
4208 static void add_str_to_yank(text_body_type *tb, concptr str)
4209 {
4210         tb->yank_eol = FALSE;
4211         if (NULL == tb->yank)
4212         {
4213                 tb->yank = new_chain_str(str);
4214                 return;
4215         }
4216
4217         chain_str_type *chain;
4218         chain = tb->yank;
4219
4220         while (TRUE)
4221         {
4222                 if (!chain->next)
4223                 {
4224                         chain->next = new_chain_str(str);
4225                         return;
4226                 }
4227
4228                 /* Go to next */
4229                 chain = chain->next;
4230         }
4231 }
4232
4233
4234 /*
4235  * Do work for the copy editor-command
4236  */
4237 static void copy_text_to_yank(text_body_type *tb)
4238 {
4239         int len = strlen(tb->lines_list[tb->cy]);
4240
4241         /* Correct cursor location */
4242         if (tb->cx > len) tb->cx = len;
4243
4244         /* Use single line? */
4245         if (!tb->mark)
4246         {
4247                 /* Select a single line */
4248                 tb->cx = 0;
4249                 tb->my = tb->cy;
4250                 tb->mx = len;
4251         }
4252
4253         kill_yank_chain(tb);
4254
4255         if (tb->my != tb->cy)
4256         {
4257                 int by1 = MIN(tb->my, tb->cy);
4258                 int by2 = MAX(tb->my, tb->cy);
4259
4260                 for (int y = by1; y <= by2; y++)
4261                 {
4262                         add_str_to_yank(tb, tb->lines_list[y]);
4263                 }
4264
4265                 add_str_to_yank(tb, "");
4266                 tb->mark = 0;
4267                 tb->dirty_flags |= DIRTY_ALL;
4268                 return;
4269         }
4270
4271         char buf[MAX_LINELEN];
4272         int bx1 = MIN(tb->mx, tb->cx);
4273         int bx2 = MAX(tb->mx, tb->cx);
4274
4275         /* Correct fake cursor position */
4276         if (bx2 > len) bx2 = len;
4277
4278         if (bx1 == 0 && bx2 == len)
4279         {
4280                 add_str_to_yank(tb, tb->lines_list[tb->cy]);
4281                 add_str_to_yank(tb, "");
4282         }
4283         else
4284         {
4285                 int end = bx2 - bx1;
4286                 for (int i = 0; i < bx2 - bx1; i++)
4287                 {
4288                         buf[i] = tb->lines_list[tb->cy][bx1 + i];
4289                 }
4290
4291                 buf[end] = '\0';
4292                 add_str_to_yank(tb, buf);
4293         }
4294
4295         tb->mark = 0;
4296         tb->dirty_flags |= DIRTY_ALL;
4297 }
4298
4299
4300 /*
4301  * Draw text
4302  */
4303 static void draw_text_editor(player_type *player_ptr, text_body_type *tb)
4304 {
4305         int i;
4306         int by1 = 0, by2 = 0;
4307
4308         Term_get_size(&tb->wid, &tb->hgt);
4309
4310         /*
4311          * Top line (-1), description line (-3), separator (-1)
4312          *  == -5
4313          */
4314         tb->hgt -= 2 + DESCRIPT_HGT;
4315
4316 #ifdef JP
4317         /* Don't let cursor at second byte of kanji */
4318         for (i = 0; tb->lines_list[tb->cy][i]; i++)
4319                 if (iskanji(tb->lines_list[tb->cy][i]))
4320                 {
4321                         i++;
4322                         if (i == tb->cx)
4323                         {
4324                                 /*
4325                                  * Move to a correct position in the
4326                                  * left or right
4327                                  */
4328                                 if (i & 1) tb->cx--;
4329                                 else tb->cx++;
4330                                 break;
4331                         }
4332                 }
4333 #endif
4334
4335         /* Scroll if necessary */
4336         if (tb->cy < tb->upper || tb->upper + tb->hgt <= tb->cy)
4337                 tb->upper = tb->cy - (tb->hgt) / 2;
4338         if (tb->upper < 0)
4339                 tb->upper = 0;
4340         if ((tb->cx < tb->left + 10 && tb->left > 0) || tb->left + tb->wid - 5 <= tb->cx)
4341                 tb->left = tb->cx - (tb->wid) * 2 / 3;
4342         if (tb->left < 0)
4343                 tb->left = 0;
4344
4345         /* Redraw whole window after resize */
4346         if (tb->old_wid != tb->wid || tb->old_hgt != tb->hgt)
4347                 tb->dirty_flags |= DIRTY_SCREEN;
4348
4349         /* Redraw all text after scroll */
4350         else if (tb->old_upper != tb->upper || tb->old_left != tb->left)
4351                 tb->dirty_flags |= DIRTY_ALL;
4352
4353
4354         if (tb->dirty_flags & DIRTY_SCREEN)
4355         {
4356                 tb->dirty_flags |= (DIRTY_ALL | DIRTY_MODE);
4357                 Term_clear();
4358         }
4359
4360         /* Redraw mode line */
4361         if (tb->dirty_flags & DIRTY_MODE)
4362         {
4363                 char buf[MAX_LINELEN];
4364
4365                 int sepa_length = tb->wid;
4366
4367                 /* Separator */
4368                 for (i = 0; i < sepa_length; i++)
4369                         buf[i] = '-';
4370                 buf[i] = '\0';
4371
4372                 Term_putstr(0, tb->hgt + 1, sepa_length, TERM_WHITE, buf);
4373         }
4374
4375         if (tb->dirty_flags & DIRTY_EXPRESSION)
4376         {
4377                 int y;
4378                 byte state = 0;
4379
4380                 for (y = 0; tb->lines_list[y]; y++)
4381                 {
4382                         char f;
4383                         concptr v;
4384                         concptr s = tb->lines_list[y];
4385                         char *ss, *s_keep;
4386                         int s_len;
4387
4388                         /* Update this line's state */
4389                         tb->states[y] = state;
4390
4391                         if (*s++ != '?') continue;
4392                         if (*s++ != ':') continue;
4393
4394                         /* Lines below this line are auto-registered */
4395                         if (streq(s, "$AUTOREGISTER"))
4396                                 state |= LSTAT_AUTOREGISTER;
4397
4398                         s_len = strlen(s);
4399                         ss = (char *)string_make(s);
4400                         s_keep = ss;
4401
4402                         /* Parse the expr */
4403                         v = process_pref_file_expr(player_ptr, &ss, &f);
4404
4405                         /* Set flag */
4406                         if (streq(v, "0")) state |= LSTAT_BYPASS;
4407                         else state &= ~LSTAT_BYPASS;
4408
4409                         /* Cannot use string_free() because the string was "destroyed" */
4410                         C_KILL(s_keep, s_len + 1, char);
4411
4412                         /* Re-update this line's state */
4413                         tb->states[y] = state | LSTAT_EXPRESSION;
4414                 }
4415
4416                 tb->dirty_flags |= DIRTY_ALL;
4417         }
4418
4419         if (tb->mark)
4420         {
4421                 tb->dirty_flags |= DIRTY_ALL;
4422
4423                 by1 = MIN(tb->my, tb->cy);
4424                 by2 = MAX(tb->my, tb->cy);
4425         }
4426
4427         /* Dump up to tb->hgt lines of messages */
4428         for (i = 0; i < tb->hgt; i++)
4429         {
4430                 int j;
4431                 int leftcol = 0;
4432                 concptr msg;
4433                 byte color;
4434                 int y = tb->upper + i;
4435
4436                 /* clean or dirty? */
4437                 if (!(tb->dirty_flags & DIRTY_ALL) && (tb->dirty_line != y))
4438                         continue;
4439
4440                 msg = tb->lines_list[y];
4441                 if (!msg) break;
4442
4443                 /* Apply horizontal scroll */
4444                 for (j = 0; *msg; msg++, j++)
4445                 {
4446                         if (j == tb->left) break;
4447 #ifdef JP
4448                         if (j > tb->left)
4449                         {
4450                                 leftcol = 1;
4451                                 break;
4452                         }
4453                         if (iskanji(*msg))
4454                         {
4455                                 msg++;
4456                                 j++;
4457                         }
4458 #endif
4459                 }
4460
4461                 /* Erase line */
4462                 Term_erase(0, i + 1, tb->wid);
4463
4464                 if (tb->states[y] & LSTAT_AUTOREGISTER)
4465                 {
4466                         /* Warning color -- These lines will be deleted later */
4467                         color = TERM_L_RED;
4468                 }
4469                 else
4470                 {
4471                         /* Bypassed line will be displayed by darker color */
4472                         if (tb->states[y] & LSTAT_BYPASS) color = TERM_SLATE;
4473                         else color = TERM_WHITE;
4474                 }
4475
4476                 /* No mark or Out of mark */
4477                 if (!tb->mark || (y < by1 || by2 < y))
4478                 {
4479                         /* Dump the messages, bottom to top */
4480                         Term_putstr(leftcol, i + 1, tb->wid - 1, color, msg);
4481                 }
4482
4483                 /* Multiple lines selected */
4484                 else if (by1 != by2)
4485                 {
4486                         /* Dump the messages, bottom to top */
4487                         Term_putstr(leftcol, i + 1, tb->wid - 1, TERM_YELLOW, msg);
4488                 }
4489
4490                 /* Single line selected */
4491                 else
4492                 {
4493                         int x0 = leftcol + tb->left;
4494                         int len = strlen(tb->lines_list[tb->cy]);
4495                         int bx1 = MIN(tb->mx, tb->cx);
4496                         int bx2 = MAX(tb->mx, tb->cx);
4497
4498                         /* Correct cursor location */
4499                         if (bx2 > len) bx2 = len;
4500
4501                         Term_gotoxy(leftcol, i + 1);
4502                         if (x0 < bx1) Term_addstr(bx1 - x0, color, msg);
4503                         if (x0 < bx2) Term_addstr(bx2 - bx1, TERM_YELLOW, msg + (bx1 - x0));
4504                         Term_addstr(-1, color, msg + (bx2 - x0));
4505                 }
4506         }
4507
4508         for (; i < tb->hgt; i++)
4509         {
4510                 /* Erase line */
4511                 Term_erase(0, i + 1, tb->wid);
4512         }
4513
4514         bool is_updated = tb->old_cy != tb->cy || (tb->dirty_flags & (DIRTY_ALL | DIRTY_NOT_FOUND | DIRTY_NO_SEARCH)) || tb->dirty_line == tb->cy;
4515         if (is_updated) return;
4516
4517         autopick_type an_entry, *entry = &an_entry;
4518         concptr str1 = NULL, str2 = NULL;
4519
4520
4521         /* Clear information line */
4522         for (i = 0; i < DESCRIPT_HGT; i++)
4523         {
4524                 /* Erase line */
4525                 Term_erase(0, tb->hgt + 2 + i, tb->wid);
4526         }
4527
4528         /* Display information */
4529         if (tb->dirty_flags & DIRTY_NOT_FOUND)
4530         {
4531                 str1 = format(_("パターンが見つかりません: %s", "Pattern not found: %s"), tb->search_str);
4532         }
4533         else if (tb->dirty_flags & DIRTY_SKIP_INACTIVE)
4534         {
4535                 str1 = format(_("無効状態の行をスキップしました。(%sを検索中)",
4536                         "Some inactive lines are skipped. (Searching %s)"), tb->search_str);
4537         }
4538         else if (tb->dirty_flags & DIRTY_INACTIVE)
4539         {
4540                 str1 = format(_("無効状態の行だけが見付かりました。(%sを検索中)",
4541                         "Found only an inactive line. (Searching %s)"), tb->search_str);
4542         }
4543         else if (tb->dirty_flags & DIRTY_NO_SEARCH)
4544         {
4545                 str1 = _("検索するパターンがありません(^S で検索)。", "No pattern to search. (Press ^S to search.)");
4546         }
4547         else if (tb->lines_list[tb->cy][0] == '#')
4548         {
4549                 str1 = _("この行はコメントです。", "This line is a comment.");
4550         }
4551         else if (tb->lines_list[tb->cy][0] && tb->lines_list[tb->cy][1] == ':')
4552         {
4553                 switch (tb->lines_list[tb->cy][0])
4554                 {
4555                 case '?':
4556                         str1 = _("この行は条件分岐式です。", "This line is a Conditional Expression.");
4557                         break;
4558                 case 'A':
4559                         str1 = _("この行はマクロの実行内容を定義します。", "This line defines a Macro action.");
4560                         break;
4561                 case 'P':
4562                         str1 = _("この行はマクロのトリガー・キーを定義します。", "This line defines a Macro trigger key.");
4563                         break;
4564                 case 'C':
4565                         str1 = _("この行はキー配置を定義します。", "This line defines a Keymap.");
4566                         break;
4567                 }
4568
4569                 switch (tb->lines_list[tb->cy][0])
4570                 {
4571                 case '?':
4572                         if (tb->states[tb->cy] & LSTAT_BYPASS)
4573                         {
4574                                 str2 = _("現在の式の値は「偽(=0)」です。", "The expression is 'False'(=0) currently.");
4575                         }
4576                         else
4577                         {
4578                                 str2 = _("現在の式の値は「真(=1)」です。", "The expression is 'True'(=1) currently.");
4579                         }
4580                         break;
4581
4582                 default:
4583                         if (tb->states[tb->cy] & LSTAT_AUTOREGISTER)
4584                         {
4585                                 str2 = _("この行は後で削除されます。", "This line will be delete later.");
4586                         }
4587
4588                         else if (tb->states[tb->cy] & LSTAT_BYPASS)
4589                         {
4590                                 str2 = _("この行は現在は無効な状態です。", "This line is bypassed currently.");
4591                         }
4592                         break;
4593                 }
4594         }
4595
4596         /* Get description of an autopicker preference line */
4597         else if (autopick_new_entry(entry, tb->lines_list[tb->cy], FALSE))
4598         {
4599                 char buf[MAX_LINELEN];
4600                 char temp[MAX_LINELEN];
4601                 concptr t;
4602
4603                 describe_autopick(buf, entry);
4604
4605                 if (tb->states[tb->cy] & LSTAT_AUTOREGISTER)
4606                 {
4607                         strcat(buf, _("この行は後で削除されます。", "  This line will be delete later."));
4608                 }
4609
4610                 if (tb->states[tb->cy] & LSTAT_BYPASS)
4611                 {
4612                         strcat(buf, _("この行は現在は無効な状態です。", "  This line is bypassed currently."));
4613                 }
4614
4615                 roff_to_buf(buf, 81, temp, sizeof(temp));
4616                 t = temp;
4617                 for (i = 0; i < 3; i++)
4618                 {
4619                         if (t[0] == 0)
4620                                 break;
4621                         else
4622                         {
4623                                 prt(t, tb->hgt + 1 + 1 + i, 0);
4624                                 t += strlen(t) + 1;
4625                         }
4626                 }
4627                 autopick_free_entry(entry);
4628         }
4629
4630         /* Draw the first line */
4631         if (str1) prt(str1, tb->hgt + 1 + 1, 0);
4632
4633         /* Draw the second line */
4634         if (str2) prt(str2, tb->hgt + 1 + 2, 0);
4635 }
4636
4637
4638 /*
4639  * Kill segment of a line
4640  */
4641 static void kill_line_segment(text_body_type *tb, int y, int x0, int x1, bool whole)
4642 {
4643         /* Kill whole line? */
4644         concptr s = tb->lines_list[y];
4645         if (whole && x0 == 0 && s[x1] == '\0' && tb->lines_list[y + 1])
4646         {
4647                 string_free(tb->lines_list[y]);
4648
4649                 /* Shift lines up */
4650                 int i;
4651                 for (i = y; tb->lines_list[i + 1]; i++)
4652                         tb->lines_list[i] = tb->lines_list[i + 1];
4653                 tb->lines_list[i] = NULL;
4654
4655                 /* Expressions need re-evaluation */
4656                 tb->dirty_flags |= DIRTY_EXPRESSION;
4657
4658                 return;
4659         }
4660
4661         if (x0 == x1) return;
4662
4663         char buf[MAX_LINELEN];
4664         char *d = buf;
4665         for (int x = 0; x < x0; x++)
4666                 *(d++) = s[x];
4667
4668         for (int x = x1; s[x]; x++)
4669                 *(d++) = s[x];
4670
4671         *d = '\0';
4672
4673         string_free(tb->lines_list[y]);
4674         tb->lines_list[y] = string_make(buf);
4675
4676         check_expression_line(tb, y);
4677
4678         tb->changed = TRUE;
4679 }
4680
4681
4682 /*
4683  * Get a trigger key and insert ASCII string for the trigger
4684  */
4685 static bool insert_macro_line(text_body_type *tb)
4686 {
4687         int i, n = 0;
4688
4689         /* Flush */
4690         flush();
4691
4692         /* Do not process macros */
4693         inkey_base = TRUE;
4694
4695         /* First key */
4696         i = inkey();
4697
4698         /* Read the pattern */
4699         char buf[1024];
4700         while (i)
4701         {
4702                 /* Save the key */
4703                 buf[n++] = (char)i;
4704
4705                 /* Do not process macros */
4706                 inkey_base = TRUE;
4707
4708                 /* Do not wait for keys */
4709                 inkey_scan = TRUE;
4710
4711                 /* Attempt to read a key */
4712                 i = inkey();
4713         }
4714
4715         /* Terminate */
4716         buf[n] = '\0';
4717
4718         flush();
4719
4720         /* Convert the trigger */
4721         char tmp[1024];
4722         ascii_to_text(tmp, buf);
4723
4724         /* Null */
4725         if (!tmp[0]) return FALSE;
4726
4727         tb->cx = 0;
4728
4729         /* Insert preference string */
4730         insert_return_code(tb);
4731         string_free(tb->lines_list[tb->cy]);
4732         tb->lines_list[tb->cy] = string_make(format("P:%s", tmp));
4733
4734         /* Acquire action */
4735         i = macro_find_exact(buf);
4736
4737         if (i == -1)
4738         {
4739                 /* Nothing defined */
4740                 tmp[0] = '\0';
4741         }
4742         else
4743         {
4744                 /* Analyze the current action */
4745                 ascii_to_text(tmp, macro__act[i]);
4746         }
4747
4748         /* Insert blank action preference line */
4749         insert_return_code(tb);
4750         string_free(tb->lines_list[tb->cy]);
4751         tb->lines_list[tb->cy] = string_make(format("A:%s", tmp));
4752
4753         return TRUE;
4754 }
4755
4756
4757 /*
4758  * Get a command key and insert ASCII string for the key
4759  */
4760 static bool insert_keymap_line(text_body_type *tb)
4761 {
4762         /* Roguelike */
4763         BIT_FLAGS mode;
4764         if (rogue_like_commands)
4765         {
4766                 mode = KEYMAP_MODE_ROGUE;
4767         }
4768
4769         /* Original */
4770         else
4771         {
4772                 mode = KEYMAP_MODE_ORIG;
4773         }
4774
4775         flush();
4776
4777         char buf[2];
4778         buf[0] = inkey();
4779         buf[1] = '\0';
4780
4781         flush();
4782
4783         /* Convert the trigger */
4784         char tmp[1024];
4785         ascii_to_text(tmp, buf);
4786
4787         /* Null */
4788         if (!tmp[0]) return FALSE;
4789
4790         tb->cx = 0;
4791
4792         /* Insert preference string */
4793         insert_return_code(tb);
4794         string_free(tb->lines_list[tb->cy]);
4795         tb->lines_list[tb->cy] = string_make(format("C:%d:%s", mode, tmp));
4796
4797         /* Look up the keymap */
4798         concptr act = keymap_act[mode][(byte)(buf[0])];
4799         if (act)
4800         {
4801                 /* Analyze the current action */
4802                 ascii_to_text(tmp, act);
4803         }
4804
4805         /* Insert blank action preference line */
4806         insert_return_code(tb);
4807         string_free(tb->lines_list[tb->cy]);
4808         tb->lines_list[tb->cy] = string_make(format("A:%s", tmp));
4809
4810         return TRUE;
4811 }
4812
4813
4814 /*
4815  * Execute a single editor command
4816  */
4817 static bool do_editor_command(player_type *player_ptr, text_body_type *tb, int com_id)
4818 {
4819         switch (com_id)
4820         {
4821         case EC_QUIT:
4822                 if (tb->changed)
4823                 {
4824                         if (!get_check(_("全ての変更を破棄してから終了します。よろしいですか? ",
4825                                 "Discard all changes and quit. Are you sure? "))) break;
4826                 }
4827
4828                 return QUIT_WITHOUT_SAVE;
4829
4830         case EC_SAVEQUIT:
4831                 return QUIT_AND_SAVE;
4832
4833         case EC_REVERT:
4834                 /* Revert to original */
4835                 if (!get_check(_("全ての変更を破棄して元の状態に戻します。よろしいですか? ",
4836                         "Discard all changes and revert to original file. Are you sure? "))) break;
4837
4838                 free_text_lines(tb->lines_list);
4839                 tb->lines_list = read_pickpref_text_lines(player_ptr, &tb->filename_mode);
4840                 tb->dirty_flags |= DIRTY_ALL | DIRTY_MODE | DIRTY_EXPRESSION;
4841                 tb->cx = tb->cy = 0;
4842                 tb->mark = 0;
4843
4844                 /* Text is not changed */
4845                 tb->changed = FALSE;
4846                 break;
4847
4848         case EC_HELP:
4849                 /* Peruse the main help file */
4850                 (void)show_file(player_ptr, TRUE, _("jeditor.txt", "editor.txt"), NULL, 0, 0);
4851                 /* Redraw all */
4852                 tb->dirty_flags |= DIRTY_SCREEN;
4853
4854                 break;
4855
4856         case EC_RETURN:
4857                 /* Split a line or insert end of line */
4858
4859                 /* Ignore selection */
4860                 if (tb->mark)
4861                 {
4862                         tb->mark = 0;
4863
4864                         /* Now dirty */
4865                         tb->dirty_flags |= DIRTY_ALL;
4866                 }
4867
4868                 insert_return_code(tb);
4869                 tb->cy++;
4870                 tb->cx = 0;
4871
4872                 /* Now dirty */
4873                 tb->dirty_flags |= DIRTY_ALL;
4874                 break;
4875
4876         case EC_LEFT:
4877         {
4878                 /* Back */
4879                 if (0 < tb->cx)
4880                 {
4881                         int len;
4882 #ifdef JP
4883                         int i;
4884 #endif
4885
4886                         tb->cx--;
4887                         len = strlen(tb->lines_list[tb->cy]);
4888                         if (len < tb->cx) tb->cx = len;
4889
4890 #ifdef JP
4891                         /* Don't let cursor at second byte of kanji */
4892                         for (i = 0; tb->lines_list[tb->cy][i]; i++)
4893                         {
4894                                 if (iskanji(tb->lines_list[tb->cy][i]))
4895                                 {
4896                                         i++;
4897                                         if (i == tb->cx)
4898                                         {
4899                                                 /* Move to the left */
4900                                                 tb->cx--;
4901                                                 break;
4902                                         }
4903                                 }
4904                         }
4905 #endif
4906                 }
4907                 else if (tb->cy > 0)
4908                 {
4909                         tb->cy--;
4910                         tb->cx = strlen(tb->lines_list[tb->cy]);
4911                 }
4912
4913                 break;
4914         }
4915
4916         case EC_DOWN:
4917                 /* Next line */
4918
4919                 /* Is this the last line? */
4920                 if (!tb->lines_list[tb->cy + 1])
4921                 {
4922                         /* Add one more empty line if possible */
4923                         if (!add_empty_line(tb)) break;
4924                 }
4925
4926                 /* Go down */
4927                 tb->cy++;
4928
4929                 break;
4930
4931         case EC_UP:
4932                 /* Previous line */
4933                 if (tb->cy > 0) tb->cy--;
4934                 break;
4935
4936         case EC_RIGHT:
4937         {
4938 #ifdef JP
4939                 if (iskanji(tb->lines_list[tb->cy][tb->cx])) tb->cx++;
4940 #endif
4941                 tb->cx++;
4942                 int len = strlen(tb->lines_list[tb->cy]);
4943                 if (len < tb->cx)
4944                 {
4945                         /* Correct the cursor position */
4946                         tb->cx = len;
4947
4948                         /* Is this the last line? */
4949                         if (!tb->lines_list[tb->cy + 1])
4950                         {
4951                                 /* Add one more empty line if possible */
4952                                 if (!add_empty_line(tb)) break;
4953                         }
4954
4955                         /* Move to the beginning of next line */
4956                         tb->cy++;
4957                         tb->cx = 0;
4958                 }
4959
4960                 break;
4961         }
4962
4963         case EC_BOL:
4964                 /* Beginning of line */
4965                 tb->cx = 0;
4966                 break;
4967
4968         case EC_EOL:
4969                 /* End of line */
4970                 tb->cx = strlen(tb->lines_list[tb->cy]);
4971                 break;
4972
4973         case EC_PGUP:
4974                 while (0 < tb->cy && tb->upper <= tb->cy)
4975                         tb->cy--;
4976                 while (0 < tb->upper && tb->cy + 1 < tb->upper + tb->hgt)
4977                         tb->upper--;
4978                 break;
4979
4980         case EC_PGDOWN:
4981                 /* Page down */
4982                 while (tb->cy < tb->upper + tb->hgt)
4983                 {
4984                         /* Is this the last line? */
4985                         if (!tb->lines_list[tb->cy + 1])
4986                         {
4987                                 /* Add one more empty line if possible */
4988                                 if (!add_empty_line(tb)) break;
4989                         }
4990
4991                         tb->cy++;
4992                 }
4993
4994                 tb->upper = tb->cy;
4995                 break;
4996
4997         case EC_TOP:
4998                 tb->cy = 0;
4999                 break;
5000
5001         case EC_BOTTOM:
5002                 while (TRUE)
5003                 {
5004                         /* Is this the last line? */
5005                         if (!tb->lines_list[tb->cy + 1])
5006                         {
5007                                 /* Add one more empty line if possible */
5008                                 if (!add_empty_line(tb)) break;
5009                         }
5010
5011                         tb->cy++;
5012                 }
5013
5014                 /* Always at the biginning of the last line */
5015                 tb->cx = 0;
5016                 break;
5017
5018         case EC_CUT:
5019         {
5020                 /* Copy the text first */
5021                 copy_text_to_yank(tb);
5022
5023                 /* Single line case */
5024                 if (tb->my == tb->cy)
5025                 {
5026                         int bx1 = MIN(tb->mx, tb->cx);
5027                         int bx2 = MAX(tb->mx, tb->cx);
5028                         int len = strlen(tb->lines_list[tb->cy]);
5029
5030                         /* Correct fake cursor position */
5031                         if (bx2 > len) bx2 = len;
5032
5033                         kill_line_segment(tb, tb->cy, bx1, bx2, TRUE);
5034
5035                         /* New cursor position */
5036                         tb->cx = bx1;
5037                 }
5038
5039                 /* Multiple lines case */
5040                 else /* if (tb->my != tb->cy) */
5041                 {
5042                         int y;
5043
5044                         int by1 = MIN(tb->my, tb->cy);
5045                         int by2 = MAX(tb->my, tb->cy);
5046
5047                         /* Kill lines in reverse order */
5048                         for (y = by2; y >= by1; y--)
5049                         {
5050                                 int len = strlen(tb->lines_list[y]);
5051
5052                                 kill_line_segment(tb, y, 0, len, TRUE);
5053                         }
5054
5055                         /* New cursor position */
5056                         tb->cy = by1;
5057                         tb->cx = 0;
5058                 }
5059
5060                 /* Disable selection */
5061                 tb->mark = 0;
5062
5063                 /* Now dirty */
5064                 tb->dirty_flags |= DIRTY_ALL;
5065
5066                 /* Text is changed */
5067                 tb->changed = TRUE;
5068
5069                 break;
5070         }
5071
5072         case EC_COPY:
5073                 copy_text_to_yank(tb);
5074
5075                 /*
5076                  * Move cursor position to the end of the selection
5077                  *
5078                  * Pressing ^C ^V correctly duplicates the selection.
5079                  */
5080                 if (tb->my != tb->cy)
5081                 {
5082                         tb->cy = MAX(tb->cy, tb->my);
5083                         if (!tb->lines_list[tb->cy + 1])
5084                         {
5085                                 if (!add_empty_line(tb)) break;
5086                         }
5087
5088                         tb->cy++;
5089                         break;
5090                 }
5091
5092                 tb->cx = MAX(tb->cx, tb->mx);
5093                 if (!tb->lines_list[tb->cy][tb->cx])
5094                 {
5095                         if (!tb->lines_list[tb->cy + 1])
5096                         {
5097                                 if (!add_empty_line(tb)) break;
5098                         }
5099
5100                         tb->cy++;
5101                         tb->cx = 0;
5102                 }
5103
5104                 break;
5105
5106         case EC_PASTE:
5107         {
5108                 /* Paste killed text */
5109
5110                 chain_str_type *chain = tb->yank;
5111                 int len = strlen(tb->lines_list[tb->cy]);
5112
5113                 /* Nothing to do? */
5114                 if (!chain) break;
5115
5116                 /* Correct cursor location */
5117                 if (tb->cx > len) tb->cx = len;
5118
5119                 /* Ignore selection */
5120                 if (tb->mark)
5121                 {
5122                         tb->mark = 0;
5123
5124                         /* Now dirty */
5125                         tb->dirty_flags |= DIRTY_ALL;
5126                 }
5127
5128                 /* Paste text */
5129                 while (chain)
5130                 {
5131                         concptr yank_str = chain->s;
5132
5133                         char buf[MAX_LINELEN];
5134                         int i;
5135                         char rest[MAX_LINELEN], *rest_ptr = rest;
5136
5137                         /* Save preceding string */
5138                         for (i = 0; i < tb->cx; i++)
5139                                 buf[i] = tb->lines_list[tb->cy][i];
5140
5141                         strcpy(rest, &(tb->lines_list[tb->cy][i]));
5142
5143                         /* Paste yank buffer */
5144                         while (*yank_str && i < MAX_LINELEN - 1)
5145                         {
5146                                 buf[i++] = *yank_str++;
5147                         }
5148
5149                         /* Terminate */
5150                         buf[i] = '\0';
5151
5152                         chain = chain->next;
5153
5154                         if (chain || tb->yank_eol)
5155                         {
5156                                 /* There is an end of line between chain nodes */
5157
5158                                 insert_return_code(tb);
5159
5160                                 /* Replace this line with new one */
5161                                 string_free(tb->lines_list[tb->cy]);
5162                                 tb->lines_list[tb->cy] = string_make(buf);
5163
5164                                 /* Move to next line */
5165                                 tb->cx = 0;
5166                                 tb->cy++;
5167
5168                                 continue;
5169                         }
5170
5171                         /* Final line doesn't have end of line */
5172
5173                         tb->cx = strlen(buf);
5174
5175                         /* Rest of original line */
5176                         while (*rest_ptr && i < MAX_LINELEN - 1)
5177                         {
5178                                 buf[i++] = *rest_ptr++;
5179                         }
5180
5181                         /* Terminate */
5182                         buf[i] = '\0';
5183
5184                         /* Replace this line with new one */
5185                         string_free(tb->lines_list[tb->cy]);
5186                         tb->lines_list[tb->cy] = string_make(buf);
5187
5188                         /* Finish */
5189                         break;
5190                 }
5191
5192                 tb->dirty_flags |= DIRTY_ALL;
5193                 tb->dirty_flags |= DIRTY_EXPRESSION;
5194                 tb->changed = TRUE;
5195                 break;
5196         }
5197
5198         case EC_BLOCK:
5199         {
5200                 if (tb->mark)
5201                 {
5202                         tb->mark = 0;
5203                         tb->dirty_flags |= DIRTY_ALL;
5204                         break;
5205                 }
5206
5207                 tb->mark = MARK_MARK;
5208
5209                 /* Repeating this command swaps cursor position */
5210                 if (com_id == tb->old_com_id)
5211                 {
5212                         int tmp = tb->cy;
5213                         tb->cy = tb->my;
5214                         tb->my = tmp;
5215                         tmp = tb->cx;
5216                         tb->cx = tb->mx;
5217                         tb->mx = tmp;
5218                         tb->dirty_flags |= DIRTY_ALL;
5219                         break;
5220                 }
5221
5222                 int len = strlen(tb->lines_list[tb->cy]);
5223
5224                 tb->my = tb->cy;
5225                 tb->mx = tb->cx;
5226                 if (tb->cx > len) tb->mx = len;
5227                 break;
5228         }
5229
5230         case EC_KILL_LINE:
5231         {
5232                 /* Kill rest of line */
5233
5234                 int len = strlen(tb->lines_list[tb->cy]);
5235
5236                 /* Correct cursor location */
5237                 if (tb->cx > len) tb->cx = len;
5238
5239                 /* Ignore selection */
5240                 if (tb->mark)
5241                 {
5242                         tb->mark = 0;
5243
5244                         /* Now dirty */
5245                         tb->dirty_flags |= DIRTY_ALL;
5246                 }
5247
5248                 /* Append only if this command is repeated. */
5249                 if (tb->old_com_id != com_id)
5250                 {
5251                         kill_yank_chain(tb);
5252                         tb->yank = NULL;
5253                 }
5254
5255                 /* Really deleted some text */
5256                 if (tb->cx < len)
5257                 {
5258                         /* Add deleted string to yank buffer */
5259                         add_str_to_yank(tb, &(tb->lines_list[tb->cy][tb->cx]));
5260
5261                         kill_line_segment(tb, tb->cy, tb->cx, len, FALSE);
5262
5263                         /* Now dirty */
5264                         tb->dirty_line = tb->cy;
5265
5266                         /* Leave end of line character */
5267                         break;
5268                 }
5269
5270                 /* Cut the end of line character only */
5271                 if (tb->yank_eol) add_str_to_yank(tb, "");
5272
5273                 /* Cut end of line */
5274                 tb->yank_eol = TRUE;
5275
5276                 do_editor_command(player_ptr, tb, EC_DELETE_CHAR);
5277                 break;
5278         }
5279
5280         case EC_DELETE_CHAR:
5281         {
5282                 if (tb->mark)
5283                 {
5284                         tb->mark = 0;
5285
5286                         /* Now dirty */
5287                         tb->dirty_flags |= DIRTY_ALL;
5288                 }
5289
5290 #ifdef JP
5291                 if (iskanji(tb->lines_list[tb->cy][tb->cx])) tb->cx++;
5292 #endif
5293                 tb->cx++;
5294
5295                 /* Pass through the end of line to next line */
5296                 int len = strlen(tb->lines_list[tb->cy]);
5297                 if (len >= tb->cx)
5298                 {
5299                         do_editor_command(player_ptr, tb, EC_BACKSPACE);
5300                         break;
5301                 }
5302
5303                 if (tb->lines_list[tb->cy + 1])
5304                 {
5305                         tb->cy++;
5306                         tb->cx = 0;
5307                 }
5308                 else
5309                 {
5310                         tb->cx = len;
5311                         break;
5312                 }
5313
5314                 do_editor_command(player_ptr, tb, EC_BACKSPACE);
5315                 break;
5316         }
5317
5318         case EC_BACKSPACE:
5319         {
5320                 /* BACK SPACE */
5321
5322                 int len, i, j, k;
5323                 char buf[MAX_LINELEN];
5324
5325                 /* Ignore selection */
5326                 if (tb->mark)
5327                 {
5328                         tb->mark = 0;
5329
5330                         /* Now dirty */
5331                         tb->dirty_flags |= DIRTY_ALL;
5332                 }
5333
5334                 /* Move to correct collumn */
5335                 len = strlen(tb->lines_list[tb->cy]);
5336                 if (len < tb->cx) tb->cx = len;
5337
5338                 if (tb->cx == 0)
5339                 {
5340                         /* delete a return code and union two lines */
5341                         if (tb->cy == 0) break;
5342                         tb->cx = strlen(tb->lines_list[tb->cy - 1]);
5343                         strcpy(buf, tb->lines_list[tb->cy - 1]);
5344                         strcat(buf, tb->lines_list[tb->cy]);
5345                         string_free(tb->lines_list[tb->cy - 1]);
5346                         string_free(tb->lines_list[tb->cy]);
5347                         tb->lines_list[tb->cy - 1] = string_make(buf);
5348
5349                         for (i = tb->cy; tb->lines_list[i + 1]; i++)
5350                                 tb->lines_list[i] = tb->lines_list[i + 1];
5351
5352                         tb->lines_list[i] = NULL;
5353                         tb->cy--;
5354
5355                         /* Now dirty */
5356                         tb->dirty_flags |= DIRTY_ALL;
5357
5358                         /* Expressions need re-evaluation */
5359                         tb->dirty_flags |= DIRTY_EXPRESSION;
5360
5361                         /* Text is changed */
5362                         tb->changed = TRUE;
5363
5364                         break;
5365                 }
5366
5367                 for (i = j = k = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
5368                 {
5369                         k = j;
5370 #ifdef JP
5371                         if (iskanji(tb->lines_list[tb->cy][i]))
5372                                 buf[j++] = tb->lines_list[tb->cy][i++];
5373 #endif
5374                         buf[j++] = tb->lines_list[tb->cy][i];
5375                 }
5376
5377                 while (j > k)
5378                 {
5379                         tb->cx--;
5380                         j--;
5381                 }
5382
5383                 for (; tb->lines_list[tb->cy][i]; i++)
5384                 {
5385                         buf[j++] = tb->lines_list[tb->cy][i];
5386                 }
5387
5388                 buf[j] = '\0';
5389                 string_free(tb->lines_list[tb->cy]);
5390                 tb->lines_list[tb->cy] = string_make(buf);
5391                 tb->dirty_line = tb->cy;
5392                 check_expression_line(tb, tb->cy);
5393                 tb->changed = TRUE;
5394                 break;
5395         }
5396
5397         case EC_SEARCH_STR:
5398         {
5399                 byte search_dir;
5400
5401                 /* Become dirty because of item/equip menu */
5402                 tb->dirty_flags |= DIRTY_SCREEN;
5403
5404                 search_dir = get_string_for_search(player_ptr, &tb->search_o_ptr, &tb->search_str);
5405
5406                 if (!search_dir) break;
5407
5408                 if (search_dir == 1) do_editor_command(player_ptr, tb, EC_SEARCH_FORW);
5409                 else do_editor_command(player_ptr, tb, EC_SEARCH_BACK);
5410                 break;
5411         }
5412
5413         case EC_SEARCH_FORW:
5414                 if (tb->search_o_ptr)
5415                 {
5416                         search_for_object(player_ptr, tb, tb->search_o_ptr, TRUE);
5417                         break;
5418                 }
5419
5420                 if (tb->search_str && tb->search_str[0])
5421                 {
5422                         search_for_string(tb, tb->search_str, TRUE);
5423                         break;
5424                 }
5425
5426                 tb->dirty_flags |= DIRTY_NO_SEARCH;
5427                 break;
5428
5429         case EC_SEARCH_BACK:
5430                 if (tb->search_o_ptr)
5431                 {
5432                         search_for_object(player_ptr, tb, tb->search_o_ptr, FALSE);
5433                         break;
5434                 }
5435
5436                 if (tb->search_str && tb->search_str[0])
5437                 {
5438                         search_for_string(tb, tb->search_str, FALSE);
5439                         break;
5440                 }
5441
5442                 tb->dirty_flags |= DIRTY_NO_SEARCH;
5443                 break;
5444
5445         case EC_SEARCH_OBJ:
5446                 /* Become dirty because of item/equip menu */
5447                 tb->dirty_flags |= DIRTY_SCREEN;
5448
5449                 if (!get_object_for_search(player_ptr, &tb->search_o_ptr, &tb->search_str)) break;
5450
5451                 do_editor_command(player_ptr, tb, EC_SEARCH_FORW);
5452                 break;
5453
5454         case EC_SEARCH_DESTROYED:
5455                 if (!get_destroyed_object_for_search(&tb->search_o_ptr, &tb->search_str))
5456                 {
5457                         /* There is no object to search */
5458                         tb->dirty_flags |= DIRTY_NO_SEARCH;
5459
5460                         break;
5461                 }
5462
5463                 do_editor_command(player_ptr, tb, EC_SEARCH_FORW);
5464                 break;
5465
5466         case EC_INSERT_OBJECT:
5467         {
5468                 /* Insert choosen item name */
5469
5470                 autopick_type an_entry, *entry = &an_entry;
5471
5472                 if (!entry_from_choosed_object(player_ptr, entry))
5473                 {
5474                         /* Now dirty because of item/equip menu */
5475                         tb->dirty_flags |= DIRTY_SCREEN;
5476                         break;
5477                 }
5478
5479                 tb->cx = 0;
5480                 insert_return_code(tb);
5481                 string_free(tb->lines_list[tb->cy]);
5482                 tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
5483
5484                 /* Now dirty because of item/equip menu */
5485                 tb->dirty_flags |= DIRTY_SCREEN;
5486
5487                 break;
5488         }
5489
5490         case EC_INSERT_DESTROYED:
5491                 if (!tb->last_destroyed) break;
5492
5493                 tb->cx = 0;
5494                 insert_return_code(tb);
5495                 string_free(tb->lines_list[tb->cy]);
5496                 tb->lines_list[tb->cy] = string_make(tb->last_destroyed);
5497
5498                 /* Now dirty */
5499                 tb->dirty_flags |= DIRTY_ALL;
5500
5501                 /* Text is changed */
5502                 tb->changed = TRUE;
5503                 break;
5504
5505         case EC_INSERT_BLOCK:
5506         {
5507                 /* Insert a conditinal expression line */
5508                 char expression[80];
5509
5510                 /* Conditional Expression for Class and Race */
5511                 sprintf(expression, "?:[AND [EQU $RACE %s] [EQU $CLASS %s] [GEQ $LEVEL %02d]]",
5512 #ifdef JP
5513                         rp_ptr->E_title, cp_ptr->E_title,
5514 #else
5515                         rp_ptr->title, cp_ptr->title,
5516 #endif
5517                         player_ptr->lev);
5518
5519                 tb->cx = 0;
5520                 insert_return_code(tb);
5521                 string_free(tb->lines_list[tb->cy]);
5522                 tb->lines_list[tb->cy] = string_make(expression);
5523                 tb->cy++;
5524                 insert_return_code(tb);
5525                 string_free(tb->lines_list[tb->cy]);
5526                 tb->lines_list[tb->cy] = string_make("?:1");
5527
5528                 /* Now dirty */
5529                 tb->dirty_flags |= DIRTY_ALL;
5530
5531                 /* Text is changed */
5532                 tb->changed = TRUE;
5533
5534                 break;
5535         }
5536
5537         case EC_INSERT_MACRO:
5538                 /* Draw_everythig (delete menu) */
5539                 draw_text_editor(player_ptr, tb);
5540
5541                 /* Erase line */
5542                 Term_erase(0, tb->cy - tb->upper + 1, tb->wid);
5543
5544                 /* Prompt */
5545                 Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW, _("P:<トリガーキー>: ", "P:<Trigger key>: "));
5546                 if (!insert_macro_line(tb)) break;
5547
5548                 /* Prepare to input action */
5549                 tb->cx = 2;
5550                 tb->dirty_flags |= DIRTY_ALL;
5551                 tb->changed = TRUE;
5552                 break;
5553
5554         case EC_INSERT_KEYMAP:
5555                 /* Draw_everythig (delete menu) */
5556                 draw_text_editor(player_ptr, tb);
5557
5558                 /* Erase line */
5559                 Term_erase(0, tb->cy - tb->upper + 1, tb->wid);
5560
5561                 /* Prompt */
5562                 Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW,
5563                         format(_("C:%d:<コマンドキー>: ", "C:%d:<Keypress>: "), (rogue_like_commands ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG)));
5564
5565                 if (!insert_keymap_line(tb)) break;
5566
5567                 /* Prepare to input action */
5568                 tb->cx = 2;
5569                 tb->dirty_flags |= DIRTY_ALL;
5570                 tb->changed = TRUE;
5571                 break;
5572
5573         case EC_CL_AUTOPICK: toggle_command_letter(tb, DO_AUTOPICK); break;
5574         case EC_CL_DESTROY: toggle_command_letter(tb, DO_AUTODESTROY); break;
5575         case EC_CL_LEAVE: toggle_command_letter(tb, DONT_AUTOPICK); break;
5576         case EC_CL_QUERY: toggle_command_letter(tb, DO_QUERY_AUTOPICK); break;
5577         case EC_CL_NO_DISP: toggle_command_letter(tb, DO_DISPLAY); break;
5578
5579         case EC_IK_UNAWARE: toggle_keyword(tb, FLG_UNAWARE); break;
5580         case EC_IK_UNIDENTIFIED: toggle_keyword(tb, FLG_UNIDENTIFIED); break;
5581         case EC_IK_IDENTIFIED: toggle_keyword(tb, FLG_IDENTIFIED); break;
5582         case EC_IK_STAR_IDENTIFIED: toggle_keyword(tb, FLG_STAR_IDENTIFIED); break;
5583         case EC_KK_WEAPONS: toggle_keyword(tb, FLG_WEAPONS); break;
5584         case EC_KK_FAVORITE_WEAPONS: toggle_keyword(tb, FLG_FAVORITE_WEAPONS); break;
5585         case EC_KK_ARMORS: toggle_keyword(tb, FLG_ARMORS); break;
5586         case EC_KK_MISSILES: toggle_keyword(tb, FLG_MISSILES); break;
5587         case EC_KK_DEVICES: toggle_keyword(tb, FLG_DEVICES); break;
5588         case EC_KK_LIGHTS: toggle_keyword(tb, FLG_LIGHTS); break;
5589         case EC_KK_JUNKS: toggle_keyword(tb, FLG_JUNKS); break;
5590         case EC_KK_CORPSES: toggle_keyword(tb, FLG_CORPSES); break;
5591         case EC_KK_SPELLBOOKS: toggle_keyword(tb, FLG_SPELLBOOKS); break;
5592         case EC_KK_SHIELDS: toggle_keyword(tb, FLG_SHIELDS); break;
5593         case EC_KK_BOWS: toggle_keyword(tb, FLG_BOWS); break;
5594         case EC_KK_RINGS: toggle_keyword(tb, FLG_RINGS); break;
5595         case EC_KK_AMULETS: toggle_keyword(tb, FLG_AMULETS); break;
5596         case EC_KK_SUITS: toggle_keyword(tb, FLG_SUITS); break;
5597         case EC_KK_CLOAKS: toggle_keyword(tb, FLG_CLOAKS); break;
5598         case EC_KK_HELMS: toggle_keyword(tb, FLG_HELMS); break;
5599         case EC_KK_GLOVES: toggle_keyword(tb, FLG_GLOVES); break;
5600         case EC_KK_BOOTS: toggle_keyword(tb, FLG_BOOTS); break;
5601         case EC_OK_COLLECTING: toggle_keyword(tb, FLG_COLLECTING); break;
5602         case EC_OK_BOOSTED: toggle_keyword(tb, FLG_BOOSTED); break;
5603         case EC_OK_MORE_DICE: toggle_keyword(tb, FLG_MORE_DICE); break;
5604         case EC_OK_MORE_BONUS: toggle_keyword(tb, FLG_MORE_BONUS); break;
5605         case EC_OK_WORTHLESS: toggle_keyword(tb, FLG_WORTHLESS); break;
5606         case EC_OK_ARTIFACT: toggle_keyword(tb, FLG_ARTIFACT); break;
5607         case EC_OK_EGO: toggle_keyword(tb, FLG_EGO); break;
5608         case EC_OK_GOOD: toggle_keyword(tb, FLG_GOOD); break;
5609         case EC_OK_NAMELESS: toggle_keyword(tb, FLG_NAMELESS); break;
5610         case EC_OK_AVERAGE: toggle_keyword(tb, FLG_AVERAGE); break;
5611         case EC_OK_RARE: toggle_keyword(tb, FLG_RARE); break;
5612         case EC_OK_COMMON: toggle_keyword(tb, FLG_COMMON); break;
5613         case EC_OK_WANTED: toggle_keyword(tb, FLG_WANTED); break;
5614         case EC_OK_UNIQUE: toggle_keyword(tb, FLG_UNIQUE); break;
5615         case EC_OK_HUMAN: toggle_keyword(tb, FLG_HUMAN); break;
5616         case EC_OK_UNREADABLE:
5617                 toggle_keyword(tb, FLG_UNREADABLE);
5618                 add_keyword(tb, FLG_SPELLBOOKS);
5619                 break;
5620         case EC_OK_REALM1:
5621                 toggle_keyword(tb, FLG_REALM1);
5622                 add_keyword(tb, FLG_SPELLBOOKS);
5623                 break;
5624         case EC_OK_REALM2:
5625                 toggle_keyword(tb, FLG_REALM2);
5626                 add_keyword(tb, FLG_SPELLBOOKS);
5627                 break;
5628         case EC_OK_FIRST:
5629                 toggle_keyword(tb, FLG_FIRST);
5630                 add_keyword(tb, FLG_SPELLBOOKS);
5631                 break;
5632         case EC_OK_SECOND:
5633                 toggle_keyword(tb, FLG_SECOND);
5634                 add_keyword(tb, FLG_SPELLBOOKS);
5635                 break;
5636         case EC_OK_THIRD:
5637                 toggle_keyword(tb, FLG_THIRD);
5638                 add_keyword(tb, FLG_SPELLBOOKS);
5639                 break;
5640         case EC_OK_FOURTH:
5641                 toggle_keyword(tb, FLG_FOURTH);
5642                 add_keyword(tb, FLG_SPELLBOOKS);
5643                 break;
5644         }
5645
5646         tb->old_com_id = com_id;
5647         return FALSE;
5648 }
5649
5650
5651 /*
5652  * Insert single letter at cursor position.
5653  */
5654 static void insert_single_letter(text_body_type *tb, int key)
5655 {
5656         int i, j, len;
5657         char buf[MAX_LINELEN];
5658
5659         /* Save preceding string */
5660         for (i = j = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
5661         {
5662                 buf[j++] = tb->lines_list[tb->cy][i];
5663         }
5664
5665 #ifdef JP
5666         if (iskanji(key))
5667         {
5668                 int next;
5669
5670                 inkey_base = TRUE;
5671                 next = inkey();
5672                 if (j + 2 < MAX_LINELEN)
5673                 {
5674                         buf[j++] = (char)key;
5675                         buf[j++] = (char)next;
5676                         tb->cx += 2;
5677                 }
5678                 else
5679                         bell();
5680         }
5681         else
5682 #endif
5683         {
5684                 if (j + 1 < MAX_LINELEN)
5685                         buf[j++] = (char)key;
5686                 tb->cx++;
5687         }
5688
5689         /* Add following */
5690         for (; tb->lines_list[tb->cy][i] && j + 1 < MAX_LINELEN; i++)
5691                 buf[j++] = tb->lines_list[tb->cy][i];
5692         buf[j] = '\0';
5693
5694         /* Replace current line with new line */
5695         string_free(tb->lines_list[tb->cy]);
5696         tb->lines_list[tb->cy] = string_make(buf);
5697
5698         /* Move to correct collumn */
5699         len = strlen(tb->lines_list[tb->cy]);
5700         if (len < tb->cx) tb->cx = len;
5701
5702         /* Now dirty */
5703         tb->dirty_line = tb->cy;
5704
5705         /* Expressions may need re-evaluation */
5706         check_expression_line(tb, tb->cy);
5707
5708         /* Text is changed */
5709         tb->changed = TRUE;
5710 }
5711
5712
5713 /*
5714  * Check special key code and get a movement command id
5715  */
5716 static int analyze_move_key(text_body_type *tb, int skey)
5717 {
5718         int com_id;
5719
5720         /* Not a special key */
5721         if (!(skey & SKEY_MASK)) return 0;
5722
5723         /* Convert from a special key code to an editor command */
5724         switch (skey & ~SKEY_MOD_MASK)
5725         {
5726         case SKEY_DOWN:   com_id = EC_DOWN;   break;
5727         case SKEY_LEFT:   com_id = EC_LEFT;   break;
5728         case SKEY_RIGHT:  com_id = EC_RIGHT;  break;
5729         case SKEY_UP:     com_id = EC_UP;     break;
5730         case SKEY_PGUP:   com_id = EC_PGUP;   break;
5731         case SKEY_PGDOWN: com_id = EC_PGDOWN; break;
5732         case SKEY_TOP:    com_id = EC_TOP;    break;
5733         case SKEY_BOTTOM: com_id = EC_BOTTOM; break;
5734
5735         default:
5736                 /* Not a special movement key */
5737                 return 0;
5738         }
5739
5740         if (!(skey & SKEY_MOD_SHIFT))
5741         {
5742                 /*
5743                  * Un-shifted cursor keys cancells
5744                  * selection created by shift+cursor.
5745                  */
5746                 if (tb->mark & MARK_BY_SHIFT)
5747                 {
5748                         tb->mark = 0;
5749
5750                         /* Now dirty */
5751                         tb->dirty_flags |= DIRTY_ALL;
5752                 }
5753
5754                 return com_id;
5755         }
5756
5757         if (tb->mark) return com_id;
5758
5759         int len = strlen(tb->lines_list[tb->cy]);
5760
5761         tb->mark = MARK_MARK | MARK_BY_SHIFT;
5762         tb->my = tb->cy;
5763         tb->mx = tb->cx;
5764
5765         /* Correct cursor location */
5766         if (tb->cx > len) tb->mx = len;
5767
5768         /* Need to redraw text */
5769         if (com_id == EC_UP || com_id == EC_DOWN)
5770         {
5771                 /* Redraw all text */
5772                 tb->dirty_flags |= DIRTY_ALL;
5773         }
5774         else
5775         {
5776                 tb->dirty_line = tb->cy;
5777         }
5778
5779         return com_id;
5780 }
5781
5782 /*
5783  * In-game editor of Object Auto-picker/Destoryer
5784  * @param player_ptr プレーヤーへの参照ポインタ
5785  */
5786 void do_cmd_edit_autopick(player_type *player_ptr)
5787 {
5788         static int cx_save = 0;
5789         static int cy_save = 0;
5790
5791         text_body_type text_body, *tb = &text_body;
5792
5793         autopick_type an_entry, *entry = &an_entry;
5794         char buf[MAX_LINELEN];
5795
5796         int i;
5797         int key = -1;
5798
5799         static s32b old_autosave_turn = 0L;
5800         byte quit = 0;
5801
5802         tb->changed = FALSE;
5803         tb->cx = cx_save;
5804         tb->cy = cy_save;
5805         tb->upper = tb->left = 0;
5806         tb->mark = 0;
5807         tb->mx = tb->my = 0;
5808         tb->old_cy = tb->old_upper = tb->old_left = -1;
5809         tb->old_wid = tb->old_hgt = -1;
5810         tb->old_com_id = 0;
5811
5812         tb->yank = NULL;
5813         tb->search_o_ptr = NULL;
5814         tb->search_str = NULL;
5815         tb->last_destroyed = NULL;
5816         tb->dirty_flags = DIRTY_ALL | DIRTY_MODE | DIRTY_EXPRESSION;
5817         tb->dirty_line = -1;
5818         tb->filename_mode = PT_DEFAULT;
5819
5820         if (current_world_ptr->game_turn < old_autosave_turn)
5821         {
5822                 while (old_autosave_turn > current_world_ptr->game_turn) old_autosave_turn -= TURNS_PER_TICK * TOWN_DAWN;
5823         }
5824
5825         /* Autosave */
5826         if (current_world_ptr->game_turn > old_autosave_turn + 100L)
5827         {
5828                 do_cmd_save_game(player_ptr, TRUE);
5829                 old_autosave_turn = current_world_ptr->game_turn;
5830         }
5831
5832         /* HACK -- Reset current_world_ptr->start_time to stop counting current_world_ptr->play_time while edit */
5833         update_playtime();
5834
5835         /* Free old entries */
5836         init_autopick();
5837
5838         /* Command Description of the 'Last Destroyed Item' */
5839         if (autopick_last_destroyed_object.k_idx)
5840         {
5841                 autopick_entry_from_object(player_ptr, entry, &autopick_last_destroyed_object);
5842                 tb->last_destroyed = autopick_line_from_entry_kill(entry);
5843         }
5844
5845         /* Read or initialize whole text */
5846         tb->lines_list = read_pickpref_text_lines(player_ptr, &tb->filename_mode);
5847
5848         /* Reset cursor position if needed */
5849         for (i = 0; i < tb->cy; i++)
5850         {
5851                 if (!tb->lines_list[i])
5852                 {
5853                         tb->cy = tb->cx = 0;
5854                         break;
5855                 }
5856         }
5857
5858         screen_save();
5859
5860         /* Process requests until done */
5861         while (!quit)
5862         {
5863                 int com_id = 0;
5864
5865                 /* Draw_everythig */
5866                 draw_text_editor(player_ptr, tb);
5867
5868                 /* Display header line */
5869                 prt(_("(^Q:終了 ^W:セーブして終了, ESC:メニュー, その他:入力)",
5870                         "(^Q:Quit, ^W:Save&Quit, ESC:Menu, Other:Input text)"), 0, 0);
5871                 if (!tb->mark)
5872                 {
5873                         /* Display current position */
5874                         prt(format("(%d,%d)", tb->cx, tb->cy), 0, 60);
5875                 }
5876                 else
5877                 {
5878                         /* Display current position and mark position */
5879                         prt(format("(%d,%d)-(%d,%d)", tb->mx, tb->my, tb->cx, tb->cy), 0, 60);
5880                 }
5881
5882                 /* Place cursor */
5883                 Term_gotoxy(tb->cx - tb->left, tb->cy - tb->upper + 1);
5884
5885                 /* Now clean */
5886                 tb->dirty_flags = 0;
5887                 tb->dirty_line = -1;
5888
5889                 /* Save old key and location */
5890                 tb->old_cy = tb->cy;
5891                 tb->old_upper = tb->upper;
5892                 tb->old_left = tb->left;
5893                 tb->old_wid = tb->wid;
5894                 tb->old_hgt = tb->hgt;
5895
5896                 key = inkey_special(TRUE);
5897
5898                 /* Special keys */
5899                 if (key & SKEY_MASK)
5900                 {
5901                         /* Get a movement command */
5902                         com_id = analyze_move_key(tb, key);
5903                 }
5904
5905                 /* Open the menu */
5906                 else if (key == ESCAPE)
5907                 {
5908                         com_id = do_command_menu(0, 0);
5909
5910                         /* Redraw all text later */
5911                         tb->dirty_flags |= DIRTY_SCREEN;
5912                 }
5913
5914                 /* Insert a character */
5915                 else if (!iscntrl((unsigned char)key))
5916                 {
5917                         /* Ignore selection */
5918                         if (tb->mark)
5919                         {
5920                                 tb->mark = 0;
5921
5922                                 /* Now dirty */
5923                                 tb->dirty_flags |= DIRTY_ALL;
5924                         }
5925
5926                         insert_single_letter(tb, key);
5927
5928                         /* Next loop */
5929                         continue;
5930                 }
5931
5932                 /* Other commands */
5933                 else
5934                 {
5935                         com_id = get_com_id((char)key);
5936                 }
5937
5938                 if (com_id) quit = do_editor_command(player_ptr, tb, com_id);
5939         }
5940
5941         screen_load();
5942         strcpy(buf, pickpref_filename(player_ptr, tb->filename_mode));
5943
5944         if (quit == QUIT_AND_SAVE)
5945                 write_text_lines(buf, tb->lines_list);
5946
5947         free_text_lines(tb->lines_list);
5948
5949         string_free(tb->search_str);
5950         string_free(tb->last_destroyed);
5951
5952         /* Destroy string chain */
5953         kill_yank_chain(tb);
5954
5955         /* Reload autopick pref */
5956         process_autopick_file(player_ptr, buf);
5957
5958         /* HACK -- reset current_world_ptr->start_time so that current_world_ptr->play_time is not increase while edit */
5959         current_world_ptr->start_time = (u32b)time(NULL);
5960
5961         /* Save cursor location */
5962         cx_save = tb->cx;
5963         cy_save = tb->cy;
5964 }