OSDN Git Service

[Refactor] #38997 autopick.c の整形修正 / Fixed reshaping autopick.c
[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(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(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(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(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                                                             "# *Waring!* 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 like Dragon armors, 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 armors, 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(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(&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(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                 /* Back */
4878                 if (0 < tb->cx)
4879                 {
4880                         int len;
4881 #ifdef JP
4882                         int i;
4883 #endif
4884
4885                         tb->cx--;
4886                         len = strlen(tb->lines_list[tb->cy]);
4887                         if (len < tb->cx) tb->cx = len;
4888
4889 #ifdef JP
4890                         /* Don't let cursor at second byte of kanji */
4891                         for (i = 0; tb->lines_list[tb->cy][i]; i++)
4892                         {
4893                                 if (iskanji(tb->lines_list[tb->cy][i]))
4894                                 {
4895                                         i++;
4896                                         if (i == tb->cx)
4897                                         {
4898                                                 /* Move to the left */
4899                                                 tb->cx--;
4900                                                 break;
4901                                         }
4902                                 }
4903                         }
4904 #endif
4905                 }
4906                 else if (tb->cy > 0)
4907                 {
4908                         tb->cy--;
4909                         tb->cx = strlen(tb->lines_list[tb->cy]);
4910                 }
4911
4912                 break;
4913
4914         case EC_DOWN:
4915                 /* Next line */
4916
4917                 /* Is this the last line? */
4918                 if (!tb->lines_list[tb->cy + 1])
4919                 {
4920                         /* Add one more empty line if possible */
4921                         if (!add_empty_line(tb)) break;
4922                 }
4923
4924                 /* Go down */
4925                 tb->cy++;
4926
4927                 break;
4928
4929         case EC_UP:
4930                 /* Previous line */
4931                 if (tb->cy > 0) tb->cy--;
4932                 break;
4933
4934         case EC_RIGHT:
4935         {
4936 #ifdef JP
4937                 if (iskanji(tb->lines_list[tb->cy][tb->cx])) tb->cx++;
4938 #endif
4939                 tb->cx++;
4940                 int len = strlen(tb->lines_list[tb->cy]);
4941                 if (len < tb->cx)
4942                 {
4943                         /* Correct the cursor position */
4944                         tb->cx = len;
4945
4946                         /* Is this the last line? */
4947                         if (!tb->lines_list[tb->cy + 1])
4948                         {
4949                                 /* Add one more empty line if possible */
4950                                 if (!add_empty_line(tb)) break;
4951                         }
4952
4953                         /* Move to the beginning of next line */
4954                         tb->cy++;
4955                         tb->cx = 0;
4956                 }
4957
4958                 break;
4959         }
4960
4961         case EC_BOL:
4962                 /* Beginning of line */
4963                 tb->cx = 0;
4964                 break;
4965
4966         case EC_EOL:
4967                 /* End of line */
4968                 tb->cx = strlen(tb->lines_list[tb->cy]);
4969                 break;
4970
4971         case EC_PGUP:
4972                 while (0 < tb->cy && tb->upper <= tb->cy)
4973                         tb->cy--;
4974                 while (0 < tb->upper && tb->cy + 1 < tb->upper + tb->hgt)
4975                         tb->upper--;
4976                 break;
4977
4978         case EC_PGDOWN:
4979                 /* Page down */
4980                 while (tb->cy < tb->upper + tb->hgt)
4981                 {
4982                         /* Is this the last line? */
4983                         if (!tb->lines_list[tb->cy + 1])
4984                         {
4985                                 /* Add one more empty line if possible */
4986                                 if (!add_empty_line(tb)) break;
4987                         }
4988
4989                         tb->cy++;
4990                 }
4991
4992                 tb->upper = tb->cy;
4993                 break;
4994
4995         case EC_TOP:
4996                 tb->cy = 0;
4997                 break;
4998
4999         case EC_BOTTOM:
5000                 while (TRUE)
5001                 {
5002                         /* Is this the last line? */
5003                         if (!tb->lines_list[tb->cy + 1])
5004                         {
5005                                 /* Add one more empty line if possible */
5006                                 if (!add_empty_line(tb)) break;
5007                         }
5008
5009                         tb->cy++;
5010                 }
5011
5012                 /* Always at the biginning of the last line */
5013                 tb->cx = 0;
5014                 break;
5015
5016         case EC_CUT:
5017         {       
5018                 /* Copy the text first */
5019                 copy_text_to_yank(tb);
5020
5021                 /* Single line case */
5022                 if (tb->my == tb->cy)
5023                 {
5024                         int bx1 = MIN(tb->mx, tb->cx);
5025                         int bx2 = MAX(tb->mx, tb->cx);
5026                         int len = strlen(tb->lines_list[tb->cy]);
5027
5028                         /* Correct fake cursor position */
5029                         if (bx2 > len) bx2 = len;
5030
5031                         kill_line_segment(tb, tb->cy, bx1, bx2, TRUE);
5032
5033                         /* New cursor position */
5034                         tb->cx = bx1;
5035                 }
5036
5037                 /* Multiple lines case */
5038                 else /* if (tb->my != tb->cy) */
5039                 {
5040                         int y;
5041
5042                         int by1 = MIN(tb->my, tb->cy);
5043                         int by2 = MAX(tb->my, tb->cy);
5044
5045                         /* Kill lines in reverse order */
5046                         for (y = by2; y >= by1; y--)
5047                         {
5048                                 int len = strlen(tb->lines_list[y]);
5049                                 
5050                                 kill_line_segment(tb, y, 0, len, TRUE);
5051                         }
5052
5053                         /* New cursor position */
5054                         tb->cy = by1;
5055                         tb->cx = 0;
5056                 }
5057
5058                 /* Disable selection */
5059                 tb->mark = 0;
5060
5061                 /* Now dirty */
5062                 tb->dirty_flags |= DIRTY_ALL;
5063
5064                 /* Text is changed */
5065                 tb->changed = TRUE;
5066
5067                 break;
5068         }
5069
5070         case EC_COPY:
5071                 copy_text_to_yank(tb);
5072
5073                 /*
5074                  * Move cursor position to the end of the selection
5075                  *
5076                  * Pressing ^C ^V correctly duplicates the selection.
5077                  */
5078                 if (tb->my != tb->cy)
5079                 {
5080                         tb->cy = MAX(tb->cy, tb->my);
5081                         if (!tb->lines_list[tb->cy + 1])
5082                         {
5083                                 if (!add_empty_line(tb)) break;
5084                         }
5085
5086                         tb->cy++;
5087                         break;
5088                 }
5089
5090                 tb->cx = MAX(tb->cx, tb->mx);
5091                 if (!tb->lines_list[tb->cy][tb->cx])
5092                 {
5093                         if (!tb->lines_list[tb->cy + 1])
5094                         {
5095                                 if (!add_empty_line(tb)) break;
5096                         }
5097
5098                         tb->cy++;
5099                         tb->cx = 0;
5100                 }
5101
5102                 break;
5103
5104         case EC_PASTE:
5105         {
5106                 /* Paste killed text */
5107
5108                 chain_str_type *chain = tb->yank;
5109                 int len = strlen(tb->lines_list[tb->cy]);
5110
5111                 /* Nothing to do? */
5112                 if (!chain) break;
5113
5114                 /* Correct cursor location */
5115                 if (tb->cx > len) tb->cx = len;
5116
5117                 /* Ignore selection */
5118                 if (tb->mark)
5119                 {
5120                         tb->mark = 0;
5121
5122                         /* Now dirty */
5123                         tb->dirty_flags |= DIRTY_ALL;
5124                 }
5125
5126                 /* Paste text */
5127                 while (chain)
5128                 {
5129                         concptr yank_str = chain->s;
5130
5131                         char buf[MAX_LINELEN];
5132                         int i;
5133                         char rest[MAX_LINELEN], *rest_ptr = rest;
5134
5135                         /* Save preceding string */
5136                         for(i = 0; i < tb->cx; i++)
5137                                 buf[i] = tb->lines_list[tb->cy][i];
5138
5139                         strcpy(rest, &(tb->lines_list[tb->cy][i]));
5140
5141                         /* Paste yank buffer */
5142                         while (*yank_str && i < MAX_LINELEN-1)
5143                         {
5144                                 buf[i++] = *yank_str++;
5145                         }
5146
5147                         /* Terminate */
5148                         buf[i] = '\0';
5149
5150                         chain = chain->next;
5151
5152                         if (chain || tb->yank_eol)
5153                         {
5154                                 /* There is an end of line between chain nodes */
5155
5156                                 insert_return_code(tb);
5157
5158                                 /* Replace this line with new one */
5159                                 string_free(tb->lines_list[tb->cy]);
5160                                 tb->lines_list[tb->cy] = string_make(buf);
5161
5162                                 /* Move to next line */
5163                                 tb->cx = 0;
5164                                 tb->cy++;
5165
5166                                 continue;
5167                         }
5168
5169                         /* Final line doesn't have end of line */
5170
5171                         tb->cx = strlen(buf);
5172
5173                         /* Rest of original line */
5174                         while (*rest_ptr && i < MAX_LINELEN-1)
5175                         {
5176                                 buf[i++] = *rest_ptr++;
5177                         }
5178
5179                         /* Terminate */
5180                         buf[i] = '\0';
5181
5182                         /* Replace this line with new one */
5183                         string_free(tb->lines_list[tb->cy]);
5184                         tb->lines_list[tb->cy] = string_make(buf);
5185
5186                         /* Finish */
5187                         break;
5188                 }
5189
5190                 tb->dirty_flags |= DIRTY_ALL;
5191                 tb->dirty_flags |= DIRTY_EXPRESSION;
5192                 tb->changed = TRUE;
5193                 break;
5194         }
5195
5196         case EC_BLOCK:
5197                 if (tb->mark)
5198                 {
5199                         tb->mark = 0;
5200                         tb->dirty_flags |= DIRTY_ALL;
5201                         break;
5202                 }
5203                 
5204                 tb->mark = MARK_MARK;
5205
5206                 /* Repeating this command swaps cursor position */
5207                 if (com_id == tb->old_com_id)
5208                 {
5209                         int tmp = tb->cy;
5210                         tb->cy = tb->my;
5211                         tb->my = tmp;
5212                         tmp = tb->cx;
5213                         tb->cx = tb->mx;
5214                         tb->mx = tmp;
5215                         tb->dirty_flags |= DIRTY_ALL;
5216                         break;
5217                 }
5218
5219                 int len = strlen(tb->lines_list[tb->cy]);
5220
5221                 tb->my = tb->cy;
5222                 tb->mx = tb->cx;
5223                 if (tb->cx > len) tb->mx = len;
5224                 break;
5225
5226         case EC_KILL_LINE:
5227         {
5228                 /* Kill rest of line */
5229
5230                 int len = strlen(tb->lines_list[tb->cy]);
5231
5232                 /* Correct cursor location */
5233                 if (tb->cx > len) tb->cx = len;
5234
5235                 /* Ignore selection */
5236                 if (tb->mark)
5237                 {
5238                         tb->mark = 0;
5239
5240                         /* Now dirty */
5241                         tb->dirty_flags |= DIRTY_ALL;
5242                 }
5243
5244                 /* Append only if this command is repeated. */
5245                 if (tb->old_com_id != com_id)
5246                 {
5247                         kill_yank_chain(tb);
5248                         tb->yank = NULL;
5249                 }
5250
5251                 /* Really deleted some text */
5252                 if (tb->cx < len)
5253                 {
5254                         /* Add deleted string to yank buffer */
5255                         add_str_to_yank(tb, &(tb->lines_list[tb->cy][tb->cx]));
5256
5257                         kill_line_segment(tb, tb->cy, tb->cx, len, FALSE);
5258
5259                         /* Now dirty */
5260                         tb->dirty_line = tb->cy;
5261
5262                         /* Leave end of line character */
5263                         break;
5264                 }
5265
5266                 /* Cut the end of line character only */
5267                 if (tb->yank_eol) add_str_to_yank(tb, "");
5268
5269                 /* Cut end of line */
5270                 tb->yank_eol = TRUE;
5271
5272                 do_editor_command(player_ptr, tb, EC_DELETE_CHAR);
5273                 break;
5274         }
5275
5276         case EC_DELETE_CHAR:
5277         {
5278                 if (tb->mark)
5279                 {
5280                         tb->mark = 0;
5281
5282                         /* Now dirty */
5283                         tb->dirty_flags |= DIRTY_ALL;
5284                 }
5285
5286 #ifdef JP
5287                 if (iskanji(tb->lines_list[tb->cy][tb->cx])) tb->cx++;
5288 #endif
5289                 tb->cx++;
5290
5291                 /* Pass through the end of line to next line */
5292                 int len = strlen(tb->lines_list[tb->cy]);
5293                 if (len < tb->cx)
5294                 {
5295                         if (tb->lines_list[tb->cy + 1])
5296                         {
5297                                 tb->cy++;
5298                                 tb->cx = 0;
5299                         }
5300                         else
5301                         {
5302                                 tb->cx = len;
5303                                 break;
5304                         }
5305                 }
5306
5307                 do_editor_command(player_ptr, tb, EC_BACKSPACE);
5308                 break;
5309         }
5310
5311         case EC_BACKSPACE:
5312         {
5313                 /* BACK SPACE */
5314
5315                 int len, i, j, k;
5316                 char buf[MAX_LINELEN];
5317
5318                 /* Ignore selection */
5319                 if (tb->mark)
5320                 {
5321                         tb->mark = 0;
5322
5323                         /* Now dirty */
5324                         tb->dirty_flags |= DIRTY_ALL;
5325                 }
5326
5327                 /* Move to correct collumn */
5328                 len = strlen(tb->lines_list[tb->cy]);
5329                 if (len < tb->cx) tb->cx = len;
5330
5331                 if (tb->cx == 0)
5332                 {
5333                         /* delete a return code and union two lines */
5334                         if (tb->cy == 0) break;
5335                         tb->cx = strlen(tb->lines_list[tb->cy-1]);
5336                         strcpy(buf, tb->lines_list[tb->cy-1]);
5337                         strcat(buf, tb->lines_list[tb->cy]);
5338                         string_free(tb->lines_list[tb->cy-1]);
5339                         string_free(tb->lines_list[tb->cy]);
5340                         tb->lines_list[tb->cy-1] = string_make(buf);
5341
5342                         for (i = tb->cy; tb->lines_list[i+1]; i++)
5343                                 tb->lines_list[i] = tb->lines_list[i+1];
5344
5345                         tb->lines_list[i] = NULL;
5346                         tb->cy--;
5347
5348                         /* Now dirty */
5349                         tb->dirty_flags |= DIRTY_ALL;
5350
5351                         /* Expressions need re-evaluation */
5352                         tb->dirty_flags |= DIRTY_EXPRESSION;
5353
5354                         /* Text is changed */
5355                         tb->changed = TRUE;
5356
5357                         break;
5358                 }
5359
5360                 for (i = j = k = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
5361                 {
5362                         k = j;
5363 #ifdef JP
5364                         if (iskanji(tb->lines_list[tb->cy][i]))
5365                                 buf[j++] = tb->lines_list[tb->cy][i++];
5366 #endif
5367                         buf[j++] = tb->lines_list[tb->cy][i];
5368                 }
5369
5370                 while (j > k)
5371                 {
5372                         tb->cx--;
5373                         j--;
5374                 }
5375
5376                 for (; tb->lines_list[tb->cy][i]; i++)
5377                 {
5378                         buf[j++] = tb->lines_list[tb->cy][i];
5379                 }
5380
5381                 buf[j] = '\0';
5382                 string_free(tb->lines_list[tb->cy]);
5383                 tb->lines_list[tb->cy] = string_make(buf);
5384                 tb->dirty_line = tb->cy;
5385                 check_expression_line(tb, tb->cy);
5386                 tb->changed = TRUE;
5387                 break;
5388         }
5389
5390         case EC_SEARCH_STR:
5391         {
5392                 byte search_dir;
5393
5394                 /* Become dirty because of item/equip menu */
5395                 tb->dirty_flags |= DIRTY_SCREEN;
5396
5397                 search_dir = get_string_for_search(player_ptr, &tb->search_o_ptr, &tb->search_str);
5398
5399                 if (!search_dir) break;
5400
5401                 if (search_dir == 1) do_editor_command(player_ptr, tb, EC_SEARCH_FORW);
5402                 else do_editor_command(player_ptr, tb, EC_SEARCH_BACK);
5403                 break;
5404         }
5405
5406         case EC_SEARCH_FORW:
5407                 if (tb->search_o_ptr)
5408                 {
5409                         search_for_object(player_ptr, tb, tb->search_o_ptr, TRUE);
5410                         break;
5411                 }
5412                 
5413                 if (tb->search_str && tb->search_str[0])
5414                 {
5415                         search_for_string(tb, tb->search_str, TRUE);
5416                         break;
5417                 }
5418                 
5419                 tb->dirty_flags |= DIRTY_NO_SEARCH;
5420                 break;
5421
5422         case EC_SEARCH_BACK:
5423                 if (tb->search_o_ptr)
5424                 {
5425                         search_for_object(player_ptr, tb, tb->search_o_ptr, FALSE);
5426                         break;
5427                 }
5428                 
5429                 if (tb->search_str && tb->search_str[0])
5430                 {
5431                         search_for_string(tb, tb->search_str, FALSE);
5432                         break;
5433                 }
5434
5435                 tb->dirty_flags |= DIRTY_NO_SEARCH;
5436                 break;
5437
5438         case EC_SEARCH_OBJ:
5439                 /* Become dirty because of item/equip menu */
5440                 tb->dirty_flags |= DIRTY_SCREEN;
5441
5442                 if (!get_object_for_search(player_ptr, &tb->search_o_ptr, &tb->search_str)) break;
5443
5444                 do_editor_command(player_ptr, tb, EC_SEARCH_FORW);
5445                 break;
5446
5447         case EC_SEARCH_DESTROYED:
5448                 if (!get_destroyed_object_for_search(&tb->search_o_ptr, &tb->search_str))
5449                 {
5450                         /* There is no object to search */
5451                         tb->dirty_flags |= DIRTY_NO_SEARCH;
5452
5453                         break;
5454                 }
5455
5456                 do_editor_command(player_ptr, tb, EC_SEARCH_FORW);
5457                 break;
5458
5459         case EC_INSERT_OBJECT:
5460         {
5461                 /* Insert choosen item name */
5462
5463                 autopick_type an_entry, *entry = &an_entry;
5464
5465                 if (!entry_from_choosed_object(player_ptr, entry))
5466                 {
5467                         /* Now dirty because of item/equip menu */
5468                         tb->dirty_flags |= DIRTY_SCREEN;
5469                         break;
5470                 }
5471
5472                 tb->cx = 0;
5473                 insert_return_code(tb);
5474                 string_free(tb->lines_list[tb->cy]);
5475                 tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
5476
5477                 /* Now dirty because of item/equip menu */
5478                 tb->dirty_flags |= DIRTY_SCREEN;
5479
5480                 break;
5481         }
5482
5483         case EC_INSERT_DESTROYED:
5484                 if (!tb->last_destroyed) break;
5485
5486                 tb->cx = 0;
5487                 insert_return_code(tb);
5488                 string_free(tb->lines_list[tb->cy]);
5489                 tb->lines_list[tb->cy] = string_make(tb->last_destroyed);
5490
5491                 /* Now dirty */
5492                 tb->dirty_flags |= DIRTY_ALL;
5493
5494                 /* Text is changed */
5495                 tb->changed = TRUE;
5496                 break;
5497
5498         case EC_INSERT_BLOCK:
5499         {
5500                 /* Insert a conditinal expression line */
5501                 char expression[80];
5502
5503                 /* Conditional Expression for Class and Race */
5504                 sprintf(expression, "?:[AND [EQU $RACE %s] [EQU $CLASS %s] [GEQ $LEVEL %02d]]", 
5505 #ifdef JP
5506                         rp_ptr->E_title, cp_ptr->E_title,
5507 #else
5508                         rp_ptr->title, cp_ptr->title,
5509 #endif
5510                         player_ptr->lev);
5511
5512                 tb->cx = 0;
5513                 insert_return_code(tb);
5514                 string_free(tb->lines_list[tb->cy]);
5515                 tb->lines_list[tb->cy] = string_make(expression);
5516                 tb->cy++;
5517                 insert_return_code(tb);
5518                 string_free(tb->lines_list[tb->cy]);
5519                 tb->lines_list[tb->cy] = string_make("?:1");
5520
5521                 /* Now dirty */
5522                 tb->dirty_flags |= DIRTY_ALL;
5523
5524                 /* Text is changed */
5525                 tb->changed = TRUE;
5526
5527                 break;
5528         }
5529
5530         case EC_INSERT_MACRO:
5531                 /* Draw_everythig (delete menu) */
5532                 draw_text_editor(tb);
5533
5534                 /* Erase line */
5535                 Term_erase(0, tb->cy - tb->upper + 1, tb->wid);
5536
5537                 /* Prompt */
5538                 Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW, _("P:<トリガーキー>: ", "P:<Trigger key>: "));
5539                 if (!insert_macro_line(tb)) break;
5540
5541                 /* Prepare to input action */
5542                 tb->cx = 2;
5543                 tb->dirty_flags |= DIRTY_ALL;
5544                 tb->changed = TRUE;
5545                 break;
5546
5547         case EC_INSERT_KEYMAP:
5548                 /* Draw_everythig (delete menu) */
5549                 draw_text_editor(tb);
5550
5551                 /* Erase line */
5552                 Term_erase(0, tb->cy - tb->upper + 1, tb->wid);
5553
5554                 /* Prompt */
5555                 Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW, 
5556                                         format(_("C:%d:<コマンドキー>: ", "C:%d:<Keypress>: "), (rogue_like_commands ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG)));
5557
5558                 if (!insert_keymap_line(tb)) break;
5559
5560                 /* Prepare to input action */
5561                 tb->cx = 2;
5562                 tb->dirty_flags |= DIRTY_ALL;
5563                 tb->changed = TRUE;
5564                 break;
5565
5566         case EC_CL_AUTOPICK: toggle_command_letter(tb, DO_AUTOPICK); break;
5567         case EC_CL_DESTROY: toggle_command_letter(tb, DO_AUTODESTROY); break;
5568         case EC_CL_LEAVE: toggle_command_letter(tb, DONT_AUTOPICK); break;
5569         case EC_CL_QUERY: toggle_command_letter(tb, DO_QUERY_AUTOPICK); break;
5570         case EC_CL_NO_DISP: toggle_command_letter(tb, DO_DISPLAY); break;
5571
5572         case EC_IK_UNAWARE: toggle_keyword(tb, FLG_UNAWARE); break;
5573         case EC_IK_UNIDENTIFIED: toggle_keyword(tb, FLG_UNIDENTIFIED); break;
5574         case EC_IK_IDENTIFIED: toggle_keyword(tb, FLG_IDENTIFIED); break;
5575         case EC_IK_STAR_IDENTIFIED: toggle_keyword(tb, FLG_STAR_IDENTIFIED); break;
5576         case EC_KK_WEAPONS: toggle_keyword(tb, FLG_WEAPONS); break;
5577         case EC_KK_FAVORITE_WEAPONS: toggle_keyword(tb, FLG_FAVORITE_WEAPONS); break;
5578         case EC_KK_ARMORS: toggle_keyword(tb, FLG_ARMORS); break;
5579         case EC_KK_MISSILES: toggle_keyword(tb, FLG_MISSILES); break;
5580         case EC_KK_DEVICES: toggle_keyword(tb, FLG_DEVICES); break;
5581         case EC_KK_LIGHTS: toggle_keyword(tb, FLG_LIGHTS); break;
5582         case EC_KK_JUNKS: toggle_keyword(tb, FLG_JUNKS); break;
5583         case EC_KK_CORPSES: toggle_keyword(tb, FLG_CORPSES); break;
5584         case EC_KK_SPELLBOOKS: toggle_keyword(tb, FLG_SPELLBOOKS); break;
5585         case EC_KK_SHIELDS: toggle_keyword(tb, FLG_SHIELDS); break;
5586         case EC_KK_BOWS: toggle_keyword(tb, FLG_BOWS); break;
5587         case EC_KK_RINGS: toggle_keyword(tb, FLG_RINGS); break;
5588         case EC_KK_AMULETS: toggle_keyword(tb, FLG_AMULETS); break;
5589         case EC_KK_SUITS: toggle_keyword(tb, FLG_SUITS); break;
5590         case EC_KK_CLOAKS: toggle_keyword(tb, FLG_CLOAKS); break;
5591         case EC_KK_HELMS: toggle_keyword(tb, FLG_HELMS); break;
5592         case EC_KK_GLOVES: toggle_keyword(tb, FLG_GLOVES); break;
5593         case EC_KK_BOOTS: toggle_keyword(tb, FLG_BOOTS); break;
5594         case EC_OK_COLLECTING: toggle_keyword(tb, FLG_COLLECTING); break;
5595         case EC_OK_BOOSTED: toggle_keyword(tb, FLG_BOOSTED); break;
5596         case EC_OK_MORE_DICE: toggle_keyword(tb, FLG_MORE_DICE); break;
5597         case EC_OK_MORE_BONUS: toggle_keyword(tb, FLG_MORE_BONUS); break;
5598         case EC_OK_WORTHLESS: toggle_keyword(tb, FLG_WORTHLESS); break;
5599         case EC_OK_ARTIFACT: toggle_keyword(tb, FLG_ARTIFACT); break;
5600         case EC_OK_EGO: toggle_keyword(tb, FLG_EGO); break;
5601         case EC_OK_GOOD: toggle_keyword(tb, FLG_GOOD); break;
5602         case EC_OK_NAMELESS: toggle_keyword(tb, FLG_NAMELESS); break;
5603         case EC_OK_AVERAGE: toggle_keyword(tb, FLG_AVERAGE); break;
5604         case EC_OK_RARE: toggle_keyword(tb, FLG_RARE); break;
5605         case EC_OK_COMMON: toggle_keyword(tb, FLG_COMMON); break;
5606         case EC_OK_WANTED: toggle_keyword(tb, FLG_WANTED); break;
5607         case EC_OK_UNIQUE: toggle_keyword(tb, FLG_UNIQUE); break;
5608         case EC_OK_HUMAN: toggle_keyword(tb, FLG_HUMAN); break;
5609         case EC_OK_UNREADABLE:
5610                 toggle_keyword(tb, FLG_UNREADABLE);
5611                 add_keyword(tb, FLG_SPELLBOOKS);
5612                 break;
5613         case EC_OK_REALM1:
5614                 toggle_keyword(tb, FLG_REALM1);
5615                 add_keyword(tb, FLG_SPELLBOOKS);
5616                 break;
5617         case EC_OK_REALM2:
5618                 toggle_keyword(tb, FLG_REALM2);
5619                 add_keyword(tb, FLG_SPELLBOOKS);
5620                 break;
5621         case EC_OK_FIRST:
5622                 toggle_keyword(tb, FLG_FIRST);
5623                 add_keyword(tb, FLG_SPELLBOOKS);
5624                 break;
5625         case EC_OK_SECOND:
5626                 toggle_keyword(tb, FLG_SECOND);
5627                 add_keyword(tb, FLG_SPELLBOOKS);
5628                 break;
5629         case EC_OK_THIRD:
5630                 toggle_keyword(tb, FLG_THIRD);
5631                 add_keyword(tb, FLG_SPELLBOOKS);
5632                 break;
5633         case EC_OK_FOURTH:
5634                 toggle_keyword(tb, FLG_FOURTH);
5635                 add_keyword(tb, FLG_SPELLBOOKS);
5636                 break;
5637         }
5638
5639         tb->old_com_id = com_id;
5640         return FALSE;
5641 }
5642
5643
5644 /*
5645  * Insert single letter at cursor position.
5646  */
5647 static void insert_single_letter(text_body_type *tb, int key)
5648 {
5649         int i, j, len;
5650         char buf[MAX_LINELEN];
5651
5652         /* Save preceding string */
5653         for (i = j = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
5654         {
5655                 buf[j++] = tb->lines_list[tb->cy][i];
5656         }
5657
5658 #ifdef JP
5659         if (iskanji(key))
5660         {
5661                 int next;
5662
5663                 inkey_base = TRUE;
5664                 next = inkey();
5665                 if (j+2 < MAX_LINELEN)
5666                 {
5667                         buf[j++] = (char)key;
5668                         buf[j++] = (char)next;
5669                         tb->cx += 2;
5670                 }
5671                 else
5672                         bell();
5673         }
5674         else
5675 #endif
5676         {
5677                 if (j+1 < MAX_LINELEN)
5678                         buf[j++] = (char)key;
5679                 tb->cx++;
5680         }
5681
5682         /* Add following */
5683         for (; tb->lines_list[tb->cy][i] && j + 1 < MAX_LINELEN; i++)
5684                 buf[j++] = tb->lines_list[tb->cy][i];
5685         buf[j] = '\0';
5686
5687         /* Replace current line with new line */
5688         string_free(tb->lines_list[tb->cy]);
5689         tb->lines_list[tb->cy] = string_make(buf);
5690
5691         /* Move to correct collumn */
5692         len = strlen(tb->lines_list[tb->cy]);
5693         if (len < tb->cx) tb->cx = len;
5694
5695         /* Now dirty */
5696         tb->dirty_line = tb->cy;
5697
5698         /* Expressions may need re-evaluation */
5699         check_expression_line(tb, tb->cy);
5700
5701         /* Text is changed */
5702         tb->changed = TRUE;
5703 }
5704
5705
5706 /*
5707  * Check special key code and get a movement command id
5708  */
5709 static int analyze_move_key(text_body_type *tb, int skey)
5710 {
5711         int com_id;
5712
5713         /* Not a special key */
5714         if (!(skey & SKEY_MASK)) return 0;
5715
5716         /* Convert from a special key code to an editor command */
5717         switch(skey & ~SKEY_MOD_MASK)
5718         {
5719         case SKEY_DOWN:   com_id = EC_DOWN;   break;
5720         case SKEY_LEFT:   com_id = EC_LEFT;   break;
5721         case SKEY_RIGHT:  com_id = EC_RIGHT;  break;
5722         case SKEY_UP:     com_id = EC_UP;     break;
5723         case SKEY_PGUP:   com_id = EC_PGUP;   break;
5724         case SKEY_PGDOWN: com_id = EC_PGDOWN; break;
5725         case SKEY_TOP:    com_id = EC_TOP;    break;
5726         case SKEY_BOTTOM: com_id = EC_BOTTOM; break;
5727
5728         default:
5729                 /* Not a special movement key */
5730                 return 0;
5731         }
5732
5733         if (!(skey & SKEY_MOD_SHIFT))
5734         {
5735                 /*
5736                  * Un-shifted cursor keys cancells
5737                  * selection created by shift+cursor.
5738                  */
5739                 if (tb->mark & MARK_BY_SHIFT)
5740                 {
5741                         tb->mark = 0;
5742
5743                         /* Now dirty */
5744                         tb->dirty_flags |= DIRTY_ALL;
5745                 }
5746
5747                 return com_id;
5748         }
5749
5750         if (tb->mark) return com_id;
5751
5752         int len = strlen(tb->lines_list[tb->cy]);
5753
5754         tb->mark = MARK_MARK | MARK_BY_SHIFT;
5755         tb->my = tb->cy;
5756         tb->mx = tb->cx;
5757
5758         /* Correct cursor location */
5759         if (tb->cx > len) tb->mx = len;
5760
5761         /* Need to redraw text */
5762         if (com_id == EC_UP || com_id == EC_DOWN)
5763         {
5764                 /* Redraw all text */
5765                 tb->dirty_flags |= DIRTY_ALL;
5766         }
5767         else
5768         {
5769                 tb->dirty_line = tb->cy;
5770         }
5771
5772         return com_id;
5773 }
5774
5775 /*
5776  * In-game editor of Object Auto-picker/Destoryer
5777  * @param player_ptr プレーヤーへの参照ポインタ
5778  */
5779 void do_cmd_edit_autopick(player_type *player_ptr)
5780 {
5781         static int cx_save = 0;
5782         static int cy_save = 0;
5783
5784         text_body_type text_body, *tb = &text_body;
5785
5786         autopick_type an_entry, *entry = &an_entry;
5787         char buf[MAX_LINELEN];
5788
5789         int i;
5790         int key = -1;
5791
5792         static s32b old_autosave_turn = 0L;
5793         byte quit = 0;
5794
5795         tb->changed = FALSE;
5796         tb->cx = cx_save;
5797         tb->cy = cy_save;
5798         tb->upper = tb->left = 0;
5799         tb->mark = 0;
5800         tb->mx = tb->my = 0;
5801         tb->old_cy = tb->old_upper = tb->old_left = -1;
5802         tb->old_wid = tb->old_hgt = -1;
5803         tb->old_com_id = 0;
5804
5805         tb->yank = NULL;
5806         tb->search_o_ptr = NULL;
5807         tb->search_str = NULL;
5808         tb->last_destroyed = NULL;
5809         tb->dirty_flags = DIRTY_ALL | DIRTY_MODE | DIRTY_EXPRESSION;
5810         tb->dirty_line = -1;
5811         tb->filename_mode = PT_DEFAULT;
5812
5813         if (current_world_ptr->game_turn < old_autosave_turn)
5814         {
5815                 while (old_autosave_turn > current_world_ptr->game_turn) old_autosave_turn -= TURNS_PER_TICK * TOWN_DAWN;
5816         }
5817
5818         /* Autosave */
5819         if (current_world_ptr->game_turn > old_autosave_turn + 100L)
5820         {
5821                 do_cmd_save_game(player_ptr, TRUE);
5822                 old_autosave_turn = current_world_ptr->game_turn;
5823         }
5824
5825         /* HACK -- Reset current_world_ptr->start_time to stop counting current_world_ptr->play_time while edit */
5826         update_playtime();
5827
5828         /* Free old entries */
5829         init_autopick();
5830
5831         /* Command Description of the 'Last Destroyed Item' */
5832         if (autopick_last_destroyed_object.k_idx)
5833         {
5834                 autopick_entry_from_object(player_ptr, entry, &autopick_last_destroyed_object);
5835                 tb->last_destroyed = autopick_line_from_entry_kill(entry);
5836         }
5837
5838         /* Read or initialize whole text */
5839         tb->lines_list = read_pickpref_text_lines(player_ptr, &tb->filename_mode);
5840
5841         /* Reset cursor position if needed */
5842         for (i = 0; i < tb->cy; i++)
5843         {
5844                 if (!tb->lines_list[i])
5845                 {
5846                         tb->cy = tb->cx = 0;
5847                         break;
5848                 }
5849         }
5850
5851         screen_save();
5852
5853         /* Process requests until done */
5854         while (!quit)
5855         {
5856                 int com_id = 0;
5857
5858                 /* Draw_everythig */
5859                 draw_text_editor(tb);
5860
5861                 /* Display header line */
5862                 prt(_("(^Q:終了 ^W:セーブして終了, ESC:メニュー, その他:入力)", 
5863                       "(^Q:Quit, ^W:Save&Quit, ESC:Menu, Other:Input text)"), 0, 0);
5864                 if (!tb->mark)
5865                 {
5866                         /* Display current position */
5867                         prt (format("(%d,%d)", tb->cx, tb->cy), 0, 60);
5868                 }
5869                 else
5870                 {
5871                         /* Display current position and mark position */
5872                         prt (format("(%d,%d)-(%d,%d)", tb->mx, tb->my, tb->cx, tb->cy), 0, 60);
5873                 }
5874
5875                 /* Place cursor */
5876                 Term_gotoxy(tb->cx - tb->left, tb->cy - tb->upper + 1);
5877
5878                 /* Now clean */
5879                 tb->dirty_flags = 0;
5880                 tb->dirty_line = -1;
5881
5882                 /* Save old key and location */
5883                 tb->old_cy = tb->cy;
5884                 tb->old_upper = tb->upper;
5885                 tb->old_left = tb->left;
5886                 tb->old_wid = tb->wid;
5887                 tb->old_hgt = tb->hgt;
5888
5889                 key = inkey_special(TRUE);
5890
5891                 /* Special keys */
5892                 if (key & SKEY_MASK)
5893                 {
5894                         /* Get a movement command */
5895                         com_id = analyze_move_key(tb, key);
5896                 }
5897
5898                 /* Open the menu */
5899                 else if (key == ESCAPE)
5900                 {
5901                         com_id = do_command_menu(0, 0);
5902
5903                         /* Redraw all text later */
5904                         tb->dirty_flags |= DIRTY_SCREEN;
5905                 }
5906
5907                 /* Insert a character */
5908                 else if (!iscntrl((unsigned char)key))
5909                 {
5910                         /* Ignore selection */
5911                         if (tb->mark)
5912                         {
5913                                 tb->mark = 0;
5914
5915                                 /* Now dirty */
5916                                 tb->dirty_flags |= DIRTY_ALL;
5917                         }
5918
5919                         insert_single_letter(tb, key);
5920
5921                         /* Next loop */
5922                         continue;
5923                 }
5924
5925                 /* Other commands */
5926                 else
5927                 {
5928                         com_id = get_com_id((char)key);
5929                 }
5930
5931                 if (com_id) quit = do_editor_command(player_ptr, tb, com_id);
5932         }
5933
5934         screen_load();
5935         strcpy(buf, pickpref_filename(player_ptr, tb->filename_mode));
5936
5937         if (quit == QUIT_AND_SAVE)
5938                 write_text_lines(buf, tb->lines_list);
5939
5940         free_text_lines(tb->lines_list);
5941
5942         string_free(tb->search_str);
5943         string_free(tb->last_destroyed);
5944
5945         /* Destroy string chain */
5946         kill_yank_chain(tb);
5947
5948         /* Reload autopick pref */
5949         process_autopick_file(buf);
5950
5951         /* HACK -- reset current_world_ptr->start_time so that current_world_ptr->play_time is not increase while edit */
5952         current_world_ptr->start_time = (u32b)time(NULL);
5953
5954         /* Save cursor location */
5955         cx_save = tb->cx;
5956         cy_save = tb->cy;
5957 }