3 * @brief 自動拾い機能の実装 / Object Auto-picker/Destroyer
6 * Copyright (c) 2002 Mogami\n
8 * This software may be copied and distributed for educational, research, and\n
9 * not for profit purposes provided that this copyright and statement are\n
10 * included in all such copies.\n
11 * 2014 Deskull rearranged comment for Doxygen.\n
19 #include "core/show-file.h"
20 #include "cmd/cmd-save.h"
21 #include "io/read-pref-file.h"
25 #include "market/store.h"
26 #include "player-status.h"
27 #include "player-move.h"
28 #include "player-class.h"
29 #include "player-race.h"
30 #include "player-inventory.h"
31 #include "view/display-player.h"
32 #include "object/object-kind.h"
33 #include "object-ego.h"
34 #include "object-flavor.h"
35 #include "object-hook.h"
41 #include "monsterrace.h"
42 #include "view-mainwindow.h" // 暫定。後で消す
44 #define MAX_LINELEN 1024
51 #define FLG_UNIDENTIFIED 2
52 #define FLG_IDENTIFIED 3
53 #define FLG_STAR_IDENTIFIED 4
54 #define FLG_COLLECTING 5
55 #define FLG_ARTIFACT 6
58 #define FLG_NAMELESS 11
59 #define FLG_AVERAGE 12
60 #define FLG_WORTHLESS 13
63 #define FLG_BOOSTED 16
64 #define FLG_MORE_DICE 17
65 #define FLG_MORE_BONUS 18
69 #define FLG_UNREADABLE 22
78 #define FLG_WEAPONS 31
79 #define FLG_FAVORITE_WEAPONS 32
81 #define FLG_MISSILES 34
82 #define FLG_DEVICES 35
85 #define FLG_CORPSES 38
86 #define FLG_SPELLBOOKS 39
88 #define FLG_SHIELDS 41
91 #define FLG_AMULETS 44
98 #define FLG_NOUN_BEGIN FLG_ITEMS
99 #define FLG_NOUN_END FLG_BOOTS
103 static GAME_TEXT KEY_ALL[] = "すべての";
104 static GAME_TEXT KEY_UNAWARE[] = "未判明の";
105 static GAME_TEXT KEY_UNIDENTIFIED[] = "未鑑定の";
106 static GAME_TEXT KEY_IDENTIFIED[] = "鑑定済みの";
107 static GAME_TEXT KEY_STAR_IDENTIFIED[] = "*鑑定*済みの";
108 static GAME_TEXT KEY_COLLECTING[] = "収集中の";
109 static GAME_TEXT KEY_ARTIFACT[] = "アーティファクト";
110 static GAME_TEXT KEY_EGO[] = "エゴ";
111 static GAME_TEXT KEY_GOOD[] = "上質の";
112 static GAME_TEXT KEY_NAMELESS[] = "無銘の";
113 static GAME_TEXT KEY_AVERAGE[] = "並の";
114 static GAME_TEXT KEY_WORTHLESS[] = "無価値の";
115 static GAME_TEXT KEY_RARE[] = "レアな";
116 static GAME_TEXT KEY_COMMON[] = "ありふれた";
117 static GAME_TEXT KEY_BOOSTED[] = "ダイス目の違う";
118 static GAME_TEXT KEY_MORE_THAN[] = "ダイス目";
119 static GAME_TEXT KEY_DICE[] = "以上の";
120 static GAME_TEXT KEY_MORE_BONUS[] = "修正値";
121 static GAME_TEXT KEY_MORE_BONUS2[] = "以上の";
122 static GAME_TEXT KEY_WANTED[] = "賞金首の";
123 static GAME_TEXT KEY_UNIQUE[] = "ユニーク・モンスターの";
124 static GAME_TEXT KEY_HUMAN[] = "人間の";
125 static GAME_TEXT KEY_UNREADABLE[] = "読めない";
126 static GAME_TEXT KEY_REALM1[] = "第一領域の";
127 static GAME_TEXT KEY_REALM2[] = "第二領域の";
128 static GAME_TEXT KEY_FIRST[] = "1冊目の";
129 static GAME_TEXT KEY_SECOND[] = "2冊目の";
130 static GAME_TEXT KEY_THIRD[] = "3冊目の";
131 static GAME_TEXT KEY_FOURTH[] = "4冊目の";
132 static GAME_TEXT KEY_ITEMS[] = "アイテム";
133 static GAME_TEXT KEY_WEAPONS[] = "武器";
134 static GAME_TEXT KEY_FAVORITE_WEAPONS[] = "得意武器";
135 static GAME_TEXT KEY_ARMORS[] = "防具";
136 static GAME_TEXT KEY_MISSILES[] = "矢";
137 static GAME_TEXT KEY_DEVICES[] = "魔法アイテム";
138 static GAME_TEXT KEY_LIGHTS[] = "光源";
139 static GAME_TEXT KEY_JUNKS[] = "がらくた";
140 static GAME_TEXT KEY_CORPSES[] = "死体や骨";
141 static GAME_TEXT KEY_SPELLBOOKS[] = "魔法書";
142 static GAME_TEXT KEY_HAFTED[] = "鈍器";
143 static GAME_TEXT KEY_SHIELDS[] = "盾";
144 static GAME_TEXT KEY_BOWS[] = "弓";
145 static GAME_TEXT KEY_RINGS[] = "指輪";
146 static GAME_TEXT KEY_AMULETS[] = "アミュレット";
147 static GAME_TEXT KEY_SUITS[] = "鎧";
148 static GAME_TEXT KEY_CLOAKS[] = "クローク";
149 static GAME_TEXT KEY_HELMS[] = "兜";
150 static GAME_TEXT KEY_GLOVES[] = "籠手";
151 static GAME_TEXT KEY_BOOTS[] = "靴";
155 static GAME_TEXT KEY_ALL[] = "all";
156 static GAME_TEXT KEY_UNAWARE[] = "unaware";
157 static GAME_TEXT KEY_UNIDENTIFIED[] = "unidentified";
158 static GAME_TEXT KEY_IDENTIFIED[] = "identified";
159 static GAME_TEXT KEY_STAR_IDENTIFIED[] = "*identified*";
160 static GAME_TEXT KEY_COLLECTING[] = "collecting";
161 static GAME_TEXT KEY_ARTIFACT[] = "artifact";
162 static GAME_TEXT KEY_EGO[] = "ego";
163 static GAME_TEXT KEY_GOOD[] = "good";
164 static GAME_TEXT KEY_NAMELESS[] = "nameless";
165 static GAME_TEXT KEY_AVERAGE[] = "average";
166 static GAME_TEXT KEY_WORTHLESS[] = "worthless";
167 static GAME_TEXT KEY_RARE[] = "rare";
168 static GAME_TEXT KEY_COMMON[] = "common";
169 static GAME_TEXT KEY_BOOSTED[] = "dice boosted";
170 static GAME_TEXT KEY_MORE_THAN[] = "more than";
171 static GAME_TEXT KEY_DICE[] = " dice";
172 static GAME_TEXT KEY_MORE_BONUS[] = "more bonus than";
173 static GAME_TEXT KEY_MORE_BONUS2[] = "";
174 static GAME_TEXT KEY_WANTED[] = "wanted";
175 static GAME_TEXT KEY_UNIQUE[] = "unique monster's";
176 static GAME_TEXT KEY_HUMAN[] = "human";
177 static GAME_TEXT KEY_UNREADABLE[] = "unreadable";
178 static GAME_TEXT KEY_REALM1[] = "first realm's";
179 static GAME_TEXT KEY_REALM2[] = "second realm's";
180 static GAME_TEXT KEY_FIRST[] = "first";
181 static GAME_TEXT KEY_SECOND[] = "second";
182 static GAME_TEXT KEY_THIRD[] = "third";
183 static GAME_TEXT KEY_FOURTH[] = "fourth";
184 static GAME_TEXT KEY_ITEMS[] = "items";
185 static GAME_TEXT KEY_WEAPONS[] = "weapons";
186 static GAME_TEXT KEY_FAVORITE_WEAPONS[] = "favorite weapons";
187 static GAME_TEXT KEY_ARMORS[] = "armors";
188 static GAME_TEXT KEY_MISSILES[] = "missiles";
189 static GAME_TEXT KEY_DEVICES[] = "magical devices";
190 static GAME_TEXT KEY_LIGHTS[] = "lights";
191 static GAME_TEXT KEY_JUNKS[] = "junks";
192 static GAME_TEXT KEY_CORPSES[] = "corpses or skeletons";
193 static GAME_TEXT KEY_SPELLBOOKS[] = "spellbooks";
194 static GAME_TEXT KEY_HAFTED[] = "hafted weapons";
195 static GAME_TEXT KEY_SHIELDS[] = "shields";
196 static GAME_TEXT KEY_BOWS[] = "bows";
197 static GAME_TEXT KEY_RINGS[] = "rings";
198 static GAME_TEXT KEY_AMULETS[] = "amulets";
199 static GAME_TEXT KEY_SUITS[] = "suits";
200 static GAME_TEXT KEY_CLOAKS[] = "cloaks";
201 static GAME_TEXT KEY_HELMS[] = "helms";
202 static GAME_TEXT KEY_GLOVES[] = "gloves";
203 static GAME_TEXT KEY_BOOTS[] = "boots";
207 #define MAX_AUTOPICK_DEFAULT 200
210 #define PT_WITH_PNAME 1
212 #define MAX_YANK MAX_LINELEN
213 #define MAX_LINES 3000
215 #define MARK_MARK 0x01
216 #define MARK_BY_SHIFT 0x02
218 #define LSTAT_BYPASS 0x01
219 #define LSTAT_EXPRESSION 0x02
220 #define LSTAT_AUTOREGISTER 0x04
222 #define QUIT_WITHOUT_SAVE 1
223 #define QUIT_AND_SAVE 2
226 * Dirty flag for text editor
228 #define DIRTY_ALL 0x0001
229 #define DIRTY_MODE 0x0004
230 #define DIRTY_SCREEN 0x0008
231 #define DIRTY_NOT_FOUND 0x0010
232 #define DIRTY_NO_SEARCH 0x0020
233 #define DIRTY_EXPRESSION 0x0040
234 #define DIRTY_SKIP_INACTIVE 0x0080
235 #define DIRTY_INACTIVE 0x0100
237 #define DESCRIPT_HGT 3
239 #define MATCH_KEY(KEY) (!strncmp(ptr, KEY, sizeof(KEY)-1)\
240 ? (ptr += sizeof(KEY)-1, (' '==*ptr) ? ptr++ : 0, TRUE) : FALSE)
241 #define MATCH_KEY2(KEY) (!strncmp(ptr, KEY, sizeof(KEY)-1)\
242 ? (prev_ptr = ptr, ptr += sizeof(KEY)-1, (' '==*ptr) ? ptr++ : 0, TRUE) : FALSE)
245 #define ADD_KEY(KEY) strcat(ptr, KEY)
247 #define ADD_KEY(KEY) (strcat(ptr, KEY), strcat(ptr, " "))
249 #define ADD_KEY2(KEY) strcat(ptr, KEY)
251 #define ADD_FLG(FLG) (entry->flag[FLG / 32] |= (1L << (FLG % 32)))
252 #define REM_FLG(FLG) (entry->flag[FLG / 32] &= ~(1L << (FLG % 32)))
253 #define ADD_FLG_NOUN(FLG) (ADD_FLG(FLG), prev_flg = FLG)
254 #define IS_FLG(FLG) (entry->flag[FLG / 32] & (1L << (FLG % 32)))
257 static char kanji_colon[] = ":";
261 * 自動拾い/破壊設定のリストに関する変数 / List for auto-picker/destroyer entries
263 int max_autopick = 0; /*!< 現在登録している自動拾い/破壊設定の数 */
264 int max_max_autopick = 0; /*!< 自動拾い/破壊設定の限界数 */
265 autopick_type *autopick_list = NULL; /*!< 自動拾い/破壊設定構造体のポインタ配列 */
268 * Automatically destroy an item if it is to be destroyed
270 * When always_pickup is 'yes', we disable auto-destroyer function of
271 * auto-picker/destroyer, and do only easy-auto-destroyer.
273 static object_type autopick_last_destroyed_object;
276 * Struct for yank buffer
278 typedef struct chain_str {
279 struct chain_str *next;
284 * Data struct for text editor
290 int old_wid, old_hgt;
292 int old_upper, old_left;
296 object_type *search_o_ptr;
298 concptr last_destroyed;
300 chain_str_type *yank;
304 byte states[MAX_LINES];
315 * Editor command id's
318 #define EC_SAVEQUIT 2
336 #define EC_KILL_LINE 20
337 #define EC_DELETE_CHAR 21
338 #define EC_BACKSPACE 22
339 #define EC_SEARCH_STR 23
340 #define EC_SEARCH_FORW 24
341 #define EC_SEARCH_BACK 25
342 #define EC_SEARCH_OBJ 26
343 #define EC_SEARCH_DESTROYED 27
344 #define EC_INSERT_OBJECT 28
345 #define EC_INSERT_DESTROYED 29
346 #define EC_INSERT_BLOCK 30
347 #define EC_INSERT_MACRO 31
348 #define EC_INSERT_KEYMAP 32
349 #define EC_CL_AUTOPICK 33
350 #define EC_CL_DESTROY 34
351 #define EC_CL_LEAVE 35
352 #define EC_CL_QUERY 36
353 #define EC_CL_NO_DISP 37
354 #define EC_OK_COLLECTING 38
355 #define EC_IK_UNAWARE 39
356 #define EC_IK_UNIDENTIFIED 40
357 #define EC_IK_IDENTIFIED 41
358 #define EC_IK_STAR_IDENTIFIED 42
359 #define EC_OK_BOOSTED 43
360 #define EC_OK_MORE_DICE 44
361 #define EC_OK_MORE_BONUS 45
362 #define EC_OK_WORTHLESS 46
363 #define EC_OK_ARTIFACT 47
365 #define EC_OK_GOOD 49
366 #define EC_OK_NAMELESS 50
367 #define EC_OK_AVERAGE 51
368 #define EC_OK_RARE 52
369 #define EC_OK_COMMON 53
370 #define EC_OK_WANTED 54
371 #define EC_OK_UNIQUE 55
372 #define EC_OK_HUMAN 56
373 #define EC_OK_UNREADABLE 57
374 #define EC_OK_REALM1 58
375 #define EC_OK_REALM2 59
376 #define EC_OK_FIRST 60
377 #define EC_OK_SECOND 61
378 #define EC_OK_THIRD 62
379 #define EC_OK_FOURTH 63
380 #define EC_KK_WEAPONS 64
381 #define EC_KK_FAVORITE_WEAPONS 65
382 #define EC_KK_ARMORS 66
383 #define EC_KK_MISSILES 67
384 #define EC_KK_DEVICES 68
385 #define EC_KK_LIGHTS 69
386 #define EC_KK_JUNKS 70
387 #define EC_KK_CORPSES 71
388 #define EC_KK_SPELLBOOKS 72
389 #define EC_KK_SHIELDS 73
390 #define EC_KK_BOWS 74
391 #define EC_KK_RINGS 75
392 #define EC_KK_AMULETS 76
393 #define EC_KK_SUITS 77
394 #define EC_KK_CLOAKS 78
395 #define EC_KK_HELMS 79
396 #define EC_KK_GLOVES 80
397 #define EC_KK_BOOTS 81
401 static GAME_TEXT MN_QUIT[] = "セーブ無しで終了";
402 static GAME_TEXT MN_SAVEQUIT[] = "セーブして終了";
403 static GAME_TEXT MN_REVERT[] = "全ての変更を破棄";
404 static GAME_TEXT MN_HELP[] = "ヘルプ";
406 static GAME_TEXT MN_MOVE[] = "カーソル移動";
407 static GAME_TEXT MN_LEFT[] = "左 (←矢印キー)";
408 static GAME_TEXT MN_DOWN[] = "下 (↓矢印キー)";
409 static GAME_TEXT MN_UP[] = "上 (↑矢印キー)";
410 static GAME_TEXT MN_RIGHT[] = "右 (→矢印キー)";
411 static GAME_TEXT MN_BOL[] = "行の先頭";
412 static GAME_TEXT MN_EOL[] = "行の終端";
413 static GAME_TEXT MN_PGUP[] = "上のページ (PageUpキー)";
414 static GAME_TEXT MN_PGDOWN[] = "下のページ (PageDownキー)";
415 static GAME_TEXT MN_TOP[] = "1行目へ移動 (Homeキー)";
416 static GAME_TEXT MN_BOTTOM[] = "最下行へ移動(Endキー)";
418 static GAME_TEXT MN_EDIT[] = "編集";
419 static GAME_TEXT MN_CUT[] = "カット";
420 static GAME_TEXT MN_COPY[] = "コピー";
421 static GAME_TEXT MN_PASTE[] = "ペースト";
422 static GAME_TEXT MN_BLOCK[] = "選択範囲の指定";
423 static GAME_TEXT MN_KILL_LINE[] = "行の残りを削除";
424 static GAME_TEXT MN_DELETE_CHAR[] = "1文字削除";
425 static GAME_TEXT MN_BACKSPACE[] = "バックスペース";
426 static GAME_TEXT MN_RETURN[] = "改行";
428 static GAME_TEXT MN_SEARCH[] = "検索";
429 static GAME_TEXT MN_SEARCH_STR[] = "文字列で検索";
430 static GAME_TEXT MN_SEARCH_FORW[] = "前方へ再検索";
431 static GAME_TEXT MN_SEARCH_BACK[] = "後方へ再検索";
432 static GAME_TEXT MN_SEARCH_OBJ[] = "アイテムを選択して検索";
433 static GAME_TEXT MN_SEARCH_DESTROYED[] = "自動破壊されたアイテムで検索";
435 static GAME_TEXT MN_INSERT[] = "色々挿入";
436 static GAME_TEXT MN_INSERT_OBJECT[] = "選択したアイテムの名前を挿入";
437 static GAME_TEXT MN_INSERT_DESTROYED[] = "自動破壊されたアイテムの名前を挿入";
438 static GAME_TEXT MN_INSERT_BLOCK[] = "条件分岐ブロックの例を挿入";
439 static GAME_TEXT MN_INSERT_MACRO[] = "マクロ定義を挿入";
440 static GAME_TEXT MN_INSERT_KEYMAP[] = "キーマップ定義を挿入";
442 static GAME_TEXT MN_COMMAND_LETTER[] = "拾い/破壊/放置の選択";
443 static GAME_TEXT MN_CL_AUTOPICK[] = "「 」 (自動拾い)";
444 static GAME_TEXT MN_CL_DESTROY[] = "「!」 (自動破壊)";
445 static GAME_TEXT MN_CL_LEAVE[] = "「~」 (放置)";
446 static GAME_TEXT MN_CL_QUERY[] = "「;」 (確認して拾う)";
447 static GAME_TEXT MN_CL_NO_DISP[] = "「(」 (マップコマンドで表示しない)";
449 static GAME_TEXT MN_ADJECTIVE_GEN[] = "形容詞(一般)の選択";
450 static GAME_TEXT MN_RARE[] = "レアな (装備)";
451 static GAME_TEXT MN_COMMON[] = "ありふれた (装備)";
453 static GAME_TEXT MN_ADJECTIVE_SPECIAL[] = "形容詞(特殊)の選択";
454 static GAME_TEXT MN_BOOSTED[] = "ダイス目の違う (武器)";
455 static GAME_TEXT MN_MORE_DICE[] = "ダイス目 # 以上の (武器)";
456 static GAME_TEXT MN_MORE_BONUS[] = "修正値 # 以上の (指輪等)";
457 static GAME_TEXT MN_WANTED[] = "賞金首の (死体)";
458 static GAME_TEXT MN_UNIQUE[] = "ユニーク・モンスターの (死体)";
459 static GAME_TEXT MN_HUMAN[] = "人間の (死体)";
460 static GAME_TEXT MN_UNREADABLE[] = "読めない (魔法書)";
461 static GAME_TEXT MN_REALM1[] = "第一領域の (魔法書)";
462 static GAME_TEXT MN_REALM2[] = "第二領域の (魔法書)";
463 static GAME_TEXT MN_FIRST[] = "1冊目の (魔法書)";
464 static GAME_TEXT MN_SECOND[] = "2冊目の (魔法書)";
465 static GAME_TEXT MN_THIRD[] = "3冊目の (魔法書)";
466 static GAME_TEXT MN_FOURTH[] = "4冊目の (魔法書)";
468 static GAME_TEXT MN_NOUN[] = "名詞の選択";
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";
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)";
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";
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 object";
502 static GAME_TEXT MN_SEARCH_DESTROYED[] = "Search by destroyed object";
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";
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)";
518 static GAME_TEXT MN_ADJECTIVE_GEN[] = "Adjective (general)";
519 static GAME_TEXT MN_RARE[] = "rare (equipment)";
520 static GAME_TEXT MN_COMMON[] = "common (equipment)";
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)";
537 static GAME_TEXT MN_NOUN[] = "Keywords (noun)";
548 command_menu_type menu_data[] =
550 {MN_HELP, 0, -1, EC_HELP},
551 {MN_QUIT, 0, KTRL('q'), EC_QUIT},
552 {MN_SAVEQUIT, 0, KTRL('w'), EC_SAVEQUIT},
553 {MN_REVERT, 0, KTRL('z'), EC_REVERT},
555 {MN_EDIT, 0, -1, -1},
556 {MN_CUT, 1, KTRL('x'), EC_CUT},
557 {MN_COPY, 1, KTRL('c'), EC_COPY},
558 {MN_PASTE, 1, KTRL('v'), EC_PASTE},
559 {MN_BLOCK, 1, KTRL('g'), EC_BLOCK},
560 {MN_KILL_LINE, 1, KTRL('k'), EC_KILL_LINE},
561 {MN_DELETE_CHAR, 1, KTRL('d'), EC_DELETE_CHAR},
562 {MN_BACKSPACE, 1, KTRL('h'), EC_BACKSPACE},
563 {MN_RETURN, 1, KTRL('j'), EC_RETURN},
564 {MN_RETURN, 1, KTRL('m'), EC_RETURN},
566 {MN_SEARCH, 0, -1, -1},
567 {MN_SEARCH_STR, 1, KTRL('s'), EC_SEARCH_STR},
568 {MN_SEARCH_FORW, 1, -1, EC_SEARCH_FORW},
569 {MN_SEARCH_BACK, 1, KTRL('r'), EC_SEARCH_BACK},
570 {MN_SEARCH_OBJ, 1, KTRL('y'), EC_SEARCH_OBJ},
571 {MN_SEARCH_DESTROYED, 1, -1, EC_SEARCH_DESTROYED},
573 {MN_MOVE, 0, -1, -1},
574 {MN_LEFT, 1, KTRL('b'), EC_LEFT},
575 {MN_DOWN, 1, KTRL('n'), EC_DOWN},
576 {MN_UP, 1, KTRL('p'), EC_UP},
577 {MN_RIGHT, 1, KTRL('f'), EC_RIGHT},
578 {MN_BOL, 1, KTRL('a'), EC_BOL},
579 {MN_EOL, 1, KTRL('e'), EC_EOL},
580 {MN_PGUP, 1, KTRL('o'), EC_PGUP},
581 {MN_PGDOWN, 1, KTRL('l'), EC_PGDOWN},
582 {MN_TOP, 1, KTRL('t'), EC_TOP},
583 {MN_BOTTOM, 1, KTRL('u'), EC_BOTTOM},
585 {MN_INSERT, 0, -1, -1},
586 {MN_INSERT_OBJECT, 1, KTRL('i'), EC_INSERT_OBJECT},
587 {MN_INSERT_DESTROYED, 1, -1, EC_INSERT_DESTROYED},
588 {MN_INSERT_BLOCK, 1, -1, EC_INSERT_BLOCK},
589 {MN_INSERT_MACRO, 1, -1, EC_INSERT_MACRO},
590 {MN_INSERT_KEYMAP, 1, -1, EC_INSERT_KEYMAP},
592 {MN_ADJECTIVE_GEN, 0, -1, -1},
593 {KEY_UNAWARE, 1, -1, EC_IK_UNAWARE},
594 {KEY_UNIDENTIFIED, 1, -1, EC_IK_UNIDENTIFIED},
595 {KEY_IDENTIFIED, 1, -1, EC_IK_IDENTIFIED},
596 {KEY_STAR_IDENTIFIED, 1, -1, EC_IK_STAR_IDENTIFIED},
597 {KEY_COLLECTING, 1, -1, EC_OK_COLLECTING},
598 {KEY_ARTIFACT, 1, -1, EC_OK_ARTIFACT},
599 {KEY_EGO, 1, -1, EC_OK_EGO},
600 {KEY_GOOD, 1, -1, EC_OK_GOOD},
601 {KEY_NAMELESS, 1, -1, EC_OK_NAMELESS},
602 {KEY_AVERAGE, 1, -1, EC_OK_AVERAGE},
603 {KEY_WORTHLESS, 1, -1, EC_OK_WORTHLESS},
604 {MN_RARE, 1, -1, EC_OK_RARE},
605 {MN_COMMON, 1, -1, EC_OK_COMMON},
607 {MN_ADJECTIVE_SPECIAL, 0, -1, -1},
608 {MN_BOOSTED, 1, -1, EC_OK_BOOSTED},
609 {MN_MORE_DICE, 1, -1, EC_OK_MORE_DICE},
610 {MN_MORE_BONUS, 1, -1, EC_OK_MORE_BONUS},
611 {MN_WANTED, 1, -1, EC_OK_WANTED},
612 {MN_UNIQUE, 1, -1, EC_OK_UNIQUE},
613 {MN_HUMAN, 1, -1, EC_OK_HUMAN},
614 {MN_UNREADABLE, 1, -1, EC_OK_UNREADABLE},
615 {MN_REALM1, 1, -1, EC_OK_REALM1},
616 {MN_REALM2, 1, -1, EC_OK_REALM2},
617 {MN_FIRST, 1, -1, EC_OK_FIRST},
618 {MN_SECOND, 1, -1, EC_OK_SECOND},
619 {MN_THIRD, 1, -1, EC_OK_THIRD},
620 {MN_FOURTH, 1, -1, EC_OK_FOURTH},
622 {MN_NOUN, 0, -1, -1},
623 {KEY_WEAPONS, 1, -1, EC_KK_WEAPONS},
624 {KEY_FAVORITE_WEAPONS, 1, -1, EC_KK_FAVORITE_WEAPONS},
625 {KEY_ARMORS, 1, -1, EC_KK_ARMORS},
626 {KEY_MISSILES, 1, -1, EC_KK_MISSILES},
627 {KEY_DEVICES, 1, -1, EC_KK_DEVICES},
628 {KEY_LIGHTS, 1, -1, EC_KK_LIGHTS},
629 {KEY_JUNKS, 1, -1, EC_KK_JUNKS},
630 {KEY_CORPSES, 1, -1, EC_KK_CORPSES},
631 {KEY_SPELLBOOKS, 1, -1, EC_KK_SPELLBOOKS},
632 {KEY_SHIELDS, 1, -1, EC_KK_SHIELDS},
633 {KEY_BOWS, 1, -1, EC_KK_BOWS},
634 {KEY_RINGS, 1, -1, EC_KK_RINGS},
635 {KEY_AMULETS, 1, -1, EC_KK_AMULETS},
636 {KEY_SUITS, 1, -1, EC_KK_SUITS},
637 {KEY_CLOAKS, 1, -1, EC_KK_CLOAKS},
638 {KEY_HELMS, 1, -1, EC_KK_HELMS},
639 {KEY_GLOVES, 1, -1, EC_KK_GLOVES},
640 {KEY_BOOTS, 1, -1, EC_KK_BOOTS},
642 {MN_COMMAND_LETTER, 0, -1, -1},
643 {MN_CL_AUTOPICK, 1, -1, EC_CL_AUTOPICK},
644 {MN_CL_DESTROY, 1, -1, EC_CL_DESTROY},
645 {MN_CL_LEAVE, 1, -1, EC_CL_LEAVE},
646 {MN_CL_QUERY, 1, -1, EC_CL_QUERY},
647 {MN_CL_NO_DISP, 1, -1, EC_CL_NO_DISP},
649 {MN_DELETE_CHAR, -1, 0x7F, EC_DELETE_CHAR},
655 * A function to create new entry
657 static bool autopick_new_entry(autopick_type *entry, concptr str, bool allow_default)
659 if (str[0] && str[1] == ':') switch (str[0])
662 case 'A': case 'P': case 'C':
666 entry->flag[0] = entry->flag[1] = 0L;
670 byte act = DO_AUTOPICK | DO_DISPLAY;
673 if ((act & DO_AUTOPICK) && *str == '!')
676 act |= DO_AUTODESTROY;
681 if ((act & DO_AUTOPICK) && *str == '~')
684 act |= DONT_AUTOPICK;
689 if ((act & DO_AUTOPICK) && *str == ';')
692 act |= DO_QUERY_AUTOPICK;
697 if ((act & DO_DISPLAY) && *str == '(')
708 char buf[MAX_LINELEN];
710 for (i = 0; *str; i++)
728 if (isupper(c)) c = (char)tolower(c);
734 if (!allow_default && *buf == 0) return FALSE;
735 if (*buf == 0 && insc) return FALSE;
737 concptr prev_ptr, ptr;
738 ptr = prev_ptr = buf;
739 concptr old_ptr = NULL;
740 while (old_ptr != ptr)
743 if (MATCH_KEY(KEY_ALL)) ADD_FLG(FLG_ALL);
744 if (MATCH_KEY(KEY_COLLECTING)) ADD_FLG(FLG_COLLECTING);
745 if (MATCH_KEY(KEY_UNAWARE)) ADD_FLG(FLG_UNAWARE);
746 if (MATCH_KEY(KEY_UNIDENTIFIED)) ADD_FLG(FLG_UNIDENTIFIED);
747 if (MATCH_KEY(KEY_IDENTIFIED)) ADD_FLG(FLG_IDENTIFIED);
748 if (MATCH_KEY(KEY_STAR_IDENTIFIED)) ADD_FLG(FLG_STAR_IDENTIFIED);
749 if (MATCH_KEY(KEY_BOOSTED)) ADD_FLG(FLG_BOOSTED);
751 /*** Weapons whose dd*ds is more than nn ***/
752 if (MATCH_KEY2(KEY_MORE_THAN))
757 while (' ' == *ptr) ptr++;
759 while ('0' <= *ptr && *ptr <= '9')
761 entry->dice = 10 * entry->dice + (*ptr - '0');
768 (void)MATCH_KEY(KEY_DICE);
769 ADD_FLG(FLG_MORE_DICE);
775 /*** Items whose magical bonus is more than n ***/
776 if (MATCH_KEY2(KEY_MORE_BONUS))
781 while (' ' == *ptr) ptr++;
783 while ('0' <= *ptr && *ptr <= '9')
785 entry->bonus = 10 * entry->bonus + (*ptr - '0');
793 (void)MATCH_KEY(KEY_MORE_BONUS2);
795 if (' ' == *ptr) ptr++;
797 ADD_FLG(FLG_MORE_BONUS);
803 if (MATCH_KEY(KEY_WORTHLESS)) ADD_FLG(FLG_WORTHLESS);
804 if (MATCH_KEY(KEY_EGO)) ADD_FLG(FLG_EGO);
805 if (MATCH_KEY(KEY_GOOD)) ADD_FLG(FLG_GOOD);
806 if (MATCH_KEY(KEY_NAMELESS)) ADD_FLG(FLG_NAMELESS);
807 if (MATCH_KEY(KEY_AVERAGE)) ADD_FLG(FLG_AVERAGE);
808 if (MATCH_KEY(KEY_RARE)) ADD_FLG(FLG_RARE);
809 if (MATCH_KEY(KEY_COMMON)) ADD_FLG(FLG_COMMON);
810 if (MATCH_KEY(KEY_WANTED)) ADD_FLG(FLG_WANTED);
811 if (MATCH_KEY(KEY_UNIQUE)) ADD_FLG(FLG_UNIQUE);
812 if (MATCH_KEY(KEY_HUMAN)) ADD_FLG(FLG_HUMAN);
813 if (MATCH_KEY(KEY_UNREADABLE)) ADD_FLG(FLG_UNREADABLE);
814 if (MATCH_KEY(KEY_REALM1)) ADD_FLG(FLG_REALM1);
815 if (MATCH_KEY(KEY_REALM2)) ADD_FLG(FLG_REALM2);
816 if (MATCH_KEY(KEY_FIRST)) ADD_FLG(FLG_FIRST);
817 if (MATCH_KEY(KEY_SECOND)) ADD_FLG(FLG_SECOND);
818 if (MATCH_KEY(KEY_THIRD)) ADD_FLG(FLG_THIRD);
819 if (MATCH_KEY(KEY_FOURTH)) ADD_FLG(FLG_FOURTH);
823 if (MATCH_KEY2(KEY_ARTIFACT)) ADD_FLG_NOUN(FLG_ARTIFACT);
825 if (MATCH_KEY2(KEY_ITEMS)) ADD_FLG_NOUN(FLG_ITEMS);
826 else if (MATCH_KEY2(KEY_WEAPONS)) ADD_FLG_NOUN(FLG_WEAPONS);
827 else if (MATCH_KEY2(KEY_FAVORITE_WEAPONS)) ADD_FLG_NOUN(FLG_FAVORITE_WEAPONS);
828 else if (MATCH_KEY2(KEY_ARMORS)) ADD_FLG_NOUN(FLG_ARMORS);
829 else if (MATCH_KEY2(KEY_MISSILES)) ADD_FLG_NOUN(FLG_MISSILES);
830 else if (MATCH_KEY2(KEY_DEVICES)) ADD_FLG_NOUN(FLG_DEVICES);
831 else if (MATCH_KEY2(KEY_LIGHTS)) ADD_FLG_NOUN(FLG_LIGHTS);
832 else if (MATCH_KEY2(KEY_JUNKS)) ADD_FLG_NOUN(FLG_JUNKS);
833 else if (MATCH_KEY2(KEY_CORPSES)) ADD_FLG_NOUN(FLG_CORPSES);
834 else if (MATCH_KEY2(KEY_SPELLBOOKS)) ADD_FLG_NOUN(FLG_SPELLBOOKS);
835 else if (MATCH_KEY2(KEY_HAFTED)) ADD_FLG_NOUN(FLG_HAFTED);
836 else if (MATCH_KEY2(KEY_SHIELDS)) ADD_FLG_NOUN(FLG_SHIELDS);
837 else if (MATCH_KEY2(KEY_BOWS)) ADD_FLG_NOUN(FLG_BOWS);
838 else if (MATCH_KEY2(KEY_RINGS)) ADD_FLG_NOUN(FLG_RINGS);
839 else if (MATCH_KEY2(KEY_AMULETS)) ADD_FLG_NOUN(FLG_AMULETS);
840 else if (MATCH_KEY2(KEY_SUITS)) ADD_FLG_NOUN(FLG_SUITS);
841 else if (MATCH_KEY2(KEY_CLOAKS)) ADD_FLG_NOUN(FLG_CLOAKS);
842 else if (MATCH_KEY2(KEY_HELMS)) ADD_FLG_NOUN(FLG_HELMS);
843 else if (MATCH_KEY2(KEY_GLOVES)) ADD_FLG_NOUN(FLG_GLOVES);
844 else if (MATCH_KEY2(KEY_BOOTS)) ADD_FLG_NOUN(FLG_BOOTS);
849 else if (ptr[0] == kanji_colon[0] && ptr[1] == kanji_colon[1])
852 else if (*ptr == '\0')
855 ADD_FLG_NOUN(FLG_ITEMS);
861 entry->flag[prev_flg / 32] &= ~(1L << (prev_flg % 32));
866 entry->name = string_make(ptr);
868 entry->insc = string_make(insc);
875 * Get auto-picker entry from o_ptr.
877 static void autopick_entry_from_object(player_type *player_ptr, autopick_type *entry, object_type *o_ptr)
879 /* Assume that object name is to be added */
883 /* エゴ銘が邪魔かもしれないので、デフォルトで「^」は付けない */
884 bool bol_mark = FALSE;
886 /* We can always use the ^ mark in English */
887 bool bol_mark = TRUE;
890 GAME_TEXT name_str[MAX_NLEN];
893 entry->insc = string_make(quark_str(o_ptr->inscription));
894 entry->action = DO_AUTOPICK | DO_DISPLAY;
895 entry->flag[0] = entry->flag[1] = 0L;
898 if (!object_is_aware(o_ptr))
900 ADD_FLG(FLG_UNAWARE);
903 else if (!object_is_known(o_ptr))
905 if (!(o_ptr->ident & IDENT_SENSE))
907 ADD_FLG(FLG_UNIDENTIFIED);
912 switch (o_ptr->feeling)
916 ADD_FLG(FLG_NAMELESS);
922 ADD_FLG(FLG_NAMELESS);
923 ADD_FLG(FLG_WORTHLESS);
929 ADD_FLG(FLG_WORTHLESS);
946 if (object_is_ego(o_ptr))
948 if (object_is_weapon_armour_ammo(o_ptr))
951 * Base name of ego weapons and armors
952 * are almost meaningless.
953 * Register the ego type only.
955 ego_item_type *e_ptr = &e_info[o_ptr->name2];
957 /* エゴ銘には「^」マークが使える */
958 sprintf(name_str, "^%s", e_name + e_ptr->name);
960 /* We ommit the basename and cannot use the ^ mark */
961 strcpy(name_str, e_name + e_ptr->name);
964 if (!object_is_rare(o_ptr)) ADD_FLG(FLG_COMMON);
969 else if (object_is_artifact(o_ptr))
970 ADD_FLG(FLG_ARTIFACT);
973 if (object_is_equipment(o_ptr))
974 ADD_FLG(FLG_NAMELESS);
981 if (object_is_melee_weapon(o_ptr))
983 object_kind *k_ptr = &k_info[o_ptr->k_idx];
985 if ((o_ptr->dd != k_ptr->dd) || (o_ptr->ds != k_ptr->ds))
986 ADD_FLG(FLG_BOOSTED);
989 if (object_is_bounty(o_ptr))
991 REM_FLG(FLG_WORTHLESS);
995 if ((o_ptr->tval == TV_CORPSE || o_ptr->tval == TV_STATUE)
996 && (r_info[o_ptr->pval].flags1 & RF1_UNIQUE))
1001 if (o_ptr->tval == TV_CORPSE && my_strchr("pht", r_info[o_ptr->pval].d_char))
1006 if (o_ptr->tval >= TV_LIFE_BOOK &&
1007 !check_book_realm(player_ptr, o_ptr->tval, o_ptr->sval))
1009 ADD_FLG(FLG_UNREADABLE);
1010 if (o_ptr->tval != TV_ARCANE_BOOK) name = FALSE;
1013 if (REALM1_BOOK == o_ptr->tval &&
1014 player_ptr->pclass != CLASS_SORCERER &&
1015 player_ptr->pclass != CLASS_RED_MAGE)
1017 ADD_FLG(FLG_REALM1);
1021 if (REALM2_BOOK == o_ptr->tval &&
1022 player_ptr->pclass != CLASS_SORCERER &&
1023 player_ptr->pclass != CLASS_RED_MAGE)
1025 ADD_FLG(FLG_REALM2);
1029 if (o_ptr->tval >= TV_LIFE_BOOK && 0 == o_ptr->sval)
1031 if (o_ptr->tval >= TV_LIFE_BOOK && 1 == o_ptr->sval)
1032 ADD_FLG(FLG_SECOND);
1033 if (o_ptr->tval >= TV_LIFE_BOOK && 2 == o_ptr->sval)
1035 if (o_ptr->tval >= TV_LIFE_BOOK && 3 == o_ptr->sval)
1036 ADD_FLG(FLG_FOURTH);
1038 if (object_is_ammo(o_ptr))
1039 ADD_FLG(FLG_MISSILES);
1040 else if (o_ptr->tval == TV_SCROLL || o_ptr->tval == TV_STAFF
1041 || o_ptr->tval == TV_WAND || o_ptr->tval == TV_ROD)
1042 ADD_FLG(FLG_DEVICES);
1043 else if (o_ptr->tval == TV_LITE)
1044 ADD_FLG(FLG_LIGHTS);
1045 else if (o_ptr->tval == TV_SKELETON || o_ptr->tval == TV_BOTTLE
1046 || o_ptr->tval == TV_JUNK || o_ptr->tval == TV_STATUE)
1048 else if (o_ptr->tval == TV_CORPSE)
1049 ADD_FLG(FLG_CORPSES);
1050 else if (o_ptr->tval >= TV_LIFE_BOOK)
1051 ADD_FLG(FLG_SPELLBOOKS);
1052 else if (o_ptr->tval == TV_POLEARM || o_ptr->tval == TV_SWORD
1053 || o_ptr->tval == TV_DIGGING || o_ptr->tval == TV_HAFTED)
1054 ADD_FLG(FLG_WEAPONS);
1055 else if (o_ptr->tval == TV_SHIELD)
1056 ADD_FLG(FLG_SHIELDS);
1057 else if (o_ptr->tval == TV_BOW)
1059 else if (o_ptr->tval == TV_RING)
1061 else if (o_ptr->tval == TV_AMULET)
1062 ADD_FLG(FLG_AMULETS);
1063 else if (o_ptr->tval == TV_DRAG_ARMOR || o_ptr->tval == TV_HARD_ARMOR ||
1064 o_ptr->tval == TV_SOFT_ARMOR)
1066 else if (o_ptr->tval == TV_CLOAK)
1067 ADD_FLG(FLG_CLOAKS);
1068 else if (o_ptr->tval == TV_HELM)
1070 else if (o_ptr->tval == TV_GLOVES)
1071 ADD_FLG(FLG_GLOVES);
1072 else if (o_ptr->tval == TV_BOOTS)
1077 str_tolower(name_str);
1078 entry->name = string_make(name_str);
1082 GAME_TEXT o_name[MAX_NLEN];
1083 object_desc(player_ptr, o_name, o_ptr, (OD_NO_FLAVOR | OD_OMIT_PREFIX | OD_NO_PLURAL | OD_NAME_ONLY));
1086 * If necessary, add a '^' which indicates the
1087 * beginning of line.
1089 sprintf(name_str, "%s%s", bol_mark ? "^" : "", o_name);
1090 str_tolower(name_str);
1091 entry->name = string_make(name_str);
1096 * A function to delete entry
1098 static void autopick_free_entry(autopick_type *entry)
1100 string_free(entry->name);
1101 string_free(entry->insc);
1108 * Initialize the autopick
1110 static void init_autopick(void)
1112 static const char easy_autopick_inscription[] = "(:=g";
1113 autopick_type entry;
1118 max_max_autopick = MAX_AUTOPICK_DEFAULT;
1119 C_MAKE(autopick_list, max_max_autopick, autopick_type);
1123 for (i = 0; i < max_autopick; i++)
1124 autopick_free_entry(&autopick_list[i]);
1127 autopick_new_entry(&entry, easy_autopick_inscription, TRUE);
1128 autopick_list[max_autopick++] = entry;
1133 * Get file name for autopick preference
1135 static concptr pickpref_filename(player_type *player_ptr, int filename_mode)
1137 static const char namebase[] = _("picktype", "pickpref");
1139 switch (filename_mode)
1142 return format("%s.prf", namebase);
1145 return format("%s-%s.prf", namebase, player_ptr->base_name);
1154 * Load an autopick preference file
1156 void autopick_load_pref(player_type *player_ptr, bool disp_mes)
1160 my_strcpy(buf, pickpref_filename(player_ptr, PT_WITH_PNAME), sizeof(buf));
1161 errr err = process_autopick_file(player_ptr, buf);
1162 if (err == 0 && disp_mes)
1164 msg_format(_("%sを読み込みました。", "Loaded '%s'."), buf);
1169 my_strcpy(buf, pickpref_filename(player_ptr, PT_DEFAULT), sizeof(buf));
1170 err = process_autopick_file(player_ptr, buf);
1171 if (err == 0 && disp_mes)
1173 msg_format(_("%sを読み込みました。", "Loaded '%s'."), buf);
1177 if (err && disp_mes)
1179 msg_print(_("自動拾い設定ファイルの読み込みに失敗しました。", "Failed to reload autopick preference."));
1185 * Add one line to autopick_list[]
1187 static void add_autopick_list(autopick_type *entry)
1189 if (max_autopick >= max_max_autopick)
1191 int old_max_max_autopick = max_max_autopick;
1192 autopick_type *old_autopick_list = autopick_list;
1193 max_max_autopick += MAX_AUTOPICK_DEFAULT;
1194 C_MAKE(autopick_list, max_max_autopick, autopick_type);
1195 (void)C_COPY(autopick_list, old_autopick_list, old_max_max_autopick, autopick_type);
1196 C_KILL(old_autopick_list, old_max_max_autopick, autopick_type);
1199 autopick_list[max_autopick] = *entry;
1205 * Process line for auto picker/destroyer.
1207 void process_autopick_file_command(char *buf)
1209 autopick_type an_entry, *entry = &an_entry;
1211 for (i = 0; buf[i]; i++)
1214 if (iskanji(buf[i]))
1220 if (iswspace(buf[i]) && buf[i] != ' ')
1225 if (!autopick_new_entry(entry, buf, FALSE)) return;
1227 for (i = 0; i < max_autopick; i++)
1229 if (!strcmp(entry->name, autopick_list[i].name)
1230 && entry->flag[0] == autopick_list[i].flag[0]
1231 && entry->flag[1] == autopick_list[i].flag[1]
1232 && entry->dice == autopick_list[i].dice
1233 && entry->bonus == autopick_list[i].bonus)
1235 autopick_free_entry(entry);
1240 add_autopick_list(entry);
1246 * Reconstruct preference line from entry
1248 concptr autopick_line_from_entry(autopick_type *entry)
1250 char buf[MAX_LINELEN];
1252 if (!(entry->action & DO_DISPLAY)) strcat(buf, "(");
1253 if (entry->action & DO_QUERY_AUTOPICK) strcat(buf, ";");
1254 if (entry->action & DO_AUTODESTROY) strcat(buf, "!");
1255 if (entry->action & DONT_AUTOPICK) strcat(buf, "~");
1259 if (IS_FLG(FLG_ALL)) ADD_KEY(KEY_ALL);
1260 if (IS_FLG(FLG_COLLECTING)) ADD_KEY(KEY_COLLECTING);
1261 if (IS_FLG(FLG_UNAWARE)) ADD_KEY(KEY_UNAWARE);
1262 if (IS_FLG(FLG_UNIDENTIFIED)) ADD_KEY(KEY_UNIDENTIFIED);
1263 if (IS_FLG(FLG_IDENTIFIED)) ADD_KEY(KEY_IDENTIFIED);
1264 if (IS_FLG(FLG_STAR_IDENTIFIED)) ADD_KEY(KEY_STAR_IDENTIFIED);
1265 if (IS_FLG(FLG_BOOSTED)) ADD_KEY(KEY_BOOSTED);
1267 if (IS_FLG(FLG_MORE_DICE))
1269 ADD_KEY(KEY_MORE_THAN);
1270 strcat(ptr, format("%d", entry->dice));
1274 if (IS_FLG(FLG_MORE_BONUS))
1276 ADD_KEY(KEY_MORE_BONUS);
1277 strcat(ptr, format("%d", entry->bonus));
1278 ADD_KEY(KEY_MORE_BONUS2);
1281 if (IS_FLG(FLG_UNREADABLE)) ADD_KEY(KEY_UNREADABLE);
1282 if (IS_FLG(FLG_REALM1)) ADD_KEY(KEY_REALM1);
1283 if (IS_FLG(FLG_REALM2)) ADD_KEY(KEY_REALM2);
1284 if (IS_FLG(FLG_FIRST)) ADD_KEY(KEY_FIRST);
1285 if (IS_FLG(FLG_SECOND)) ADD_KEY(KEY_SECOND);
1286 if (IS_FLG(FLG_THIRD)) ADD_KEY(KEY_THIRD);
1287 if (IS_FLG(FLG_FOURTH)) ADD_KEY(KEY_FOURTH);
1288 if (IS_FLG(FLG_WANTED)) ADD_KEY(KEY_WANTED);
1289 if (IS_FLG(FLG_UNIQUE)) ADD_KEY(KEY_UNIQUE);
1290 if (IS_FLG(FLG_HUMAN)) ADD_KEY(KEY_HUMAN);
1291 if (IS_FLG(FLG_WORTHLESS)) ADD_KEY(KEY_WORTHLESS);
1292 if (IS_FLG(FLG_GOOD)) ADD_KEY(KEY_GOOD);
1293 if (IS_FLG(FLG_NAMELESS)) ADD_KEY(KEY_NAMELESS);
1294 if (IS_FLG(FLG_AVERAGE)) ADD_KEY(KEY_AVERAGE);
1295 if (IS_FLG(FLG_RARE)) ADD_KEY(KEY_RARE);
1296 if (IS_FLG(FLG_COMMON)) ADD_KEY(KEY_COMMON);
1297 if (IS_FLG(FLG_EGO)) ADD_KEY(KEY_EGO);
1299 if (IS_FLG(FLG_ARTIFACT)) ADD_KEY(KEY_ARTIFACT);
1301 bool sepa_flag = TRUE;
1302 if (IS_FLG(FLG_ITEMS)) ADD_KEY2(KEY_ITEMS);
1303 else if (IS_FLG(FLG_WEAPONS)) ADD_KEY2(KEY_WEAPONS);
1304 else if (IS_FLG(FLG_FAVORITE_WEAPONS)) ADD_KEY2(KEY_FAVORITE_WEAPONS);
1305 else if (IS_FLG(FLG_ARMORS)) ADD_KEY2(KEY_ARMORS);
1306 else if (IS_FLG(FLG_MISSILES)) ADD_KEY2(KEY_MISSILES);
1307 else if (IS_FLG(FLG_DEVICES)) ADD_KEY2(KEY_DEVICES);
1308 else if (IS_FLG(FLG_LIGHTS)) ADD_KEY2(KEY_LIGHTS);
1309 else if (IS_FLG(FLG_JUNKS)) ADD_KEY2(KEY_JUNKS);
1310 else if (IS_FLG(FLG_CORPSES)) ADD_KEY2(KEY_CORPSES);
1311 else if (IS_FLG(FLG_SPELLBOOKS)) ADD_KEY2(KEY_SPELLBOOKS);
1312 else if (IS_FLG(FLG_HAFTED)) ADD_KEY2(KEY_HAFTED);
1313 else if (IS_FLG(FLG_SHIELDS)) ADD_KEY2(KEY_SHIELDS);
1314 else if (IS_FLG(FLG_BOWS)) ADD_KEY2(KEY_BOWS);
1315 else if (IS_FLG(FLG_RINGS)) ADD_KEY2(KEY_RINGS);
1316 else if (IS_FLG(FLG_AMULETS)) ADD_KEY2(KEY_AMULETS);
1317 else if (IS_FLG(FLG_SUITS)) ADD_KEY2(KEY_SUITS);
1318 else if (IS_FLG(FLG_CLOAKS)) ADD_KEY2(KEY_CLOAKS);
1319 else if (IS_FLG(FLG_HELMS)) ADD_KEY2(KEY_HELMS);
1320 else if (IS_FLG(FLG_GLOVES)) ADD_KEY2(KEY_GLOVES);
1321 else if (IS_FLG(FLG_BOOTS)) ADD_KEY2(KEY_BOOTS);
1322 else if (!IS_FLG(FLG_ARTIFACT))
1325 if (entry->name && entry->name[0])
1327 if (sepa_flag) strcat(buf, ":");
1329 int i = strlen(buf);
1331 while (entry->name[j] && i < MAX_LINELEN - 2 - 1)
1334 if (iskanji(entry->name[j]))
1335 buf[i++] = entry->name[j++];
1337 buf[i++] = entry->name[j++];
1342 if (!entry->insc) return string_make(buf);
1348 while (entry->insc[j] && i < MAX_LINELEN - 2)
1351 if (iskanji(entry->insc[j]))
1352 buf[i++] = entry->insc[j++];
1354 buf[i++] = entry->insc[j++];
1358 return string_make(buf);
1363 * Reconstruct preference line from entry and kill entry
1365 static concptr autopick_line_from_entry_kill(autopick_type *entry)
1367 concptr ptr = autopick_line_from_entry(entry);
1368 autopick_free_entry(entry);
1374 * A function for Auto-picker/destroyer
1375 * Examine whether the object matches to the entry
1377 static bool is_autopick_aux(player_type *player_ptr, object_type *o_ptr, autopick_type *entry, concptr o_name)
1379 concptr ptr = entry->name;
1380 if (IS_FLG(FLG_UNAWARE) && object_is_aware(o_ptr))
1383 if (IS_FLG(FLG_UNIDENTIFIED)
1384 && (object_is_known(o_ptr) || (o_ptr->ident & IDENT_SENSE)))
1387 if (IS_FLG(FLG_IDENTIFIED) && !object_is_known(o_ptr))
1390 if (IS_FLG(FLG_STAR_IDENTIFIED) &&
1391 (!object_is_known(o_ptr) || !OBJECT_IS_FULL_KNOWN(o_ptr)))
1394 if (IS_FLG(FLG_BOOSTED))
1396 object_kind *k_ptr = &k_info[o_ptr->k_idx];
1397 if (!object_is_melee_weapon(o_ptr))
1400 if ((o_ptr->dd == k_ptr->dd) && (o_ptr->ds == k_ptr->ds))
1403 if (!object_is_known(o_ptr) && object_is_quest_target(o_ptr))
1409 if (IS_FLG(FLG_MORE_DICE))
1411 if (o_ptr->dd * o_ptr->ds < entry->dice)
1415 if (IS_FLG(FLG_MORE_BONUS))
1417 if (!object_is_known(o_ptr)) return FALSE;
1421 if (o_ptr->pval < entry->bonus) return FALSE;
1425 if (o_ptr->to_h < entry->bonus &&
1426 o_ptr->to_d < entry->bonus &&
1427 o_ptr->to_a < entry->bonus &&
1428 o_ptr->pval < entry->bonus)
1433 if (IS_FLG(FLG_WORTHLESS) && object_value(o_ptr) > 0)
1436 if (IS_FLG(FLG_ARTIFACT))
1438 if (!object_is_known(o_ptr) || !object_is_artifact(o_ptr))
1442 if (IS_FLG(FLG_EGO))
1444 if (!object_is_ego(o_ptr)) return FALSE;
1445 if (!object_is_known(o_ptr) &&
1446 !((o_ptr->ident & IDENT_SENSE) && o_ptr->feeling == FEEL_EXCELLENT))
1450 if (IS_FLG(FLG_GOOD))
1452 if (!object_is_equipment(o_ptr)) return FALSE;
1453 if (object_is_known(o_ptr))
1455 if (!object_is_nameless(o_ptr))
1458 if (o_ptr->to_a <= 0 && (o_ptr->to_h + o_ptr->to_d) <= 0)
1461 else if (o_ptr->ident & IDENT_SENSE)
1463 switch (o_ptr->feeling)
1478 if (IS_FLG(FLG_NAMELESS))
1480 if (!object_is_equipment(o_ptr)) return FALSE;
1481 if (object_is_known(o_ptr))
1483 if (!object_is_nameless(o_ptr))
1486 else if (o_ptr->ident & IDENT_SENSE)
1488 switch (o_ptr->feeling)
1506 if (IS_FLG(FLG_AVERAGE))
1508 if (!object_is_equipment(o_ptr)) return FALSE;
1509 if (object_is_known(o_ptr))
1511 if (!object_is_nameless(o_ptr))
1514 if (object_is_cursed(o_ptr) || object_is_broken(o_ptr))
1517 if (o_ptr->to_a > 0 || (o_ptr->to_h + o_ptr->to_d) > 0)
1520 else if (o_ptr->ident & IDENT_SENSE)
1522 switch (o_ptr->feeling)
1537 if (IS_FLG(FLG_RARE) && !object_is_rare(o_ptr))
1540 if (IS_FLG(FLG_COMMON) && object_is_rare(o_ptr))
1543 if (IS_FLG(FLG_WANTED) && !object_is_bounty(o_ptr))
1546 if (IS_FLG(FLG_UNIQUE) &&
1547 ((o_ptr->tval != TV_CORPSE && o_ptr->tval != TV_STATUE) ||
1548 !(r_info[o_ptr->pval].flags1 & RF1_UNIQUE)))
1551 if (IS_FLG(FLG_HUMAN) &&
1552 (o_ptr->tval != TV_CORPSE ||
1553 !my_strchr("pht", r_info[o_ptr->pval].d_char)))
1556 if (IS_FLG(FLG_UNREADABLE) &&
1557 (o_ptr->tval < TV_LIFE_BOOK ||
1558 check_book_realm(player_ptr, o_ptr->tval, o_ptr->sval)))
1561 if (IS_FLG(FLG_REALM1) &&
1562 (REALM1_BOOK != o_ptr->tval ||
1563 player_ptr->pclass == CLASS_SORCERER ||
1564 player_ptr->pclass == CLASS_RED_MAGE))
1567 if (IS_FLG(FLG_REALM2) &&
1568 (REALM2_BOOK != o_ptr->tval ||
1569 player_ptr->pclass == CLASS_SORCERER ||
1570 player_ptr->pclass == CLASS_RED_MAGE))
1573 if (IS_FLG(FLG_FIRST) &&
1574 (o_ptr->tval < TV_LIFE_BOOK || 0 != o_ptr->sval))
1577 if (IS_FLG(FLG_SECOND) &&
1578 (o_ptr->tval < TV_LIFE_BOOK || 1 != o_ptr->sval))
1581 if (IS_FLG(FLG_THIRD) &&
1582 (o_ptr->tval < TV_LIFE_BOOK || 2 != o_ptr->sval))
1585 if (IS_FLG(FLG_FOURTH) &&
1586 (o_ptr->tval < TV_LIFE_BOOK || 3 != o_ptr->sval))
1589 if (IS_FLG(FLG_WEAPONS))
1591 if (!object_is_weapon(o_ptr))
1594 else if (IS_FLG(FLG_FAVORITE_WEAPONS))
1596 if (!object_is_favorite(o_ptr))
1599 else if (IS_FLG(FLG_ARMORS))
1601 if (!object_is_armour(o_ptr))
1604 else if (IS_FLG(FLG_MISSILES))
1606 if (!object_is_ammo(o_ptr)) return FALSE;
1608 else if (IS_FLG(FLG_DEVICES))
1610 switch (o_ptr->tval)
1612 case TV_SCROLL: case TV_STAFF: case TV_WAND: case TV_ROD:
1614 default: return FALSE;
1617 else if (IS_FLG(FLG_LIGHTS))
1619 if (!(o_ptr->tval == TV_LITE))
1622 else if (IS_FLG(FLG_JUNKS))
1624 switch (o_ptr->tval)
1626 case TV_SKELETON: case TV_BOTTLE:
1627 case TV_JUNK: case TV_STATUE:
1629 default: return FALSE;
1632 else if (IS_FLG(FLG_CORPSES))
1634 if (o_ptr->tval != TV_CORPSE && o_ptr->tval != TV_SKELETON)
1637 else if (IS_FLG(FLG_SPELLBOOKS))
1639 if (!(o_ptr->tval >= TV_LIFE_BOOK))
1642 else if (IS_FLG(FLG_HAFTED))
1644 if (!(o_ptr->tval == TV_HAFTED))
1647 else if (IS_FLG(FLG_SHIELDS))
1649 if (!(o_ptr->tval == TV_SHIELD))
1652 else if (IS_FLG(FLG_BOWS))
1654 if (!(o_ptr->tval == TV_BOW))
1657 else if (IS_FLG(FLG_RINGS))
1659 if (!(o_ptr->tval == TV_RING))
1662 else if (IS_FLG(FLG_AMULETS))
1664 if (!(o_ptr->tval == TV_AMULET))
1667 else if (IS_FLG(FLG_SUITS))
1669 if (!(o_ptr->tval == TV_DRAG_ARMOR ||
1670 o_ptr->tval == TV_HARD_ARMOR ||
1671 o_ptr->tval == TV_SOFT_ARMOR))
1674 else if (IS_FLG(FLG_CLOAKS))
1676 if (!(o_ptr->tval == TV_CLOAK))
1679 else if (IS_FLG(FLG_HELMS))
1681 if (!(o_ptr->tval == TV_CROWN || o_ptr->tval == TV_HELM))
1684 else if (IS_FLG(FLG_GLOVES))
1686 if (!(o_ptr->tval == TV_GLOVES))
1689 else if (IS_FLG(FLG_BOOTS))
1691 if (!(o_ptr->tval == TV_BOOTS))
1698 if (strncmp(o_name, ptr, strlen(ptr))) return FALSE;
1702 if (!my_strstr(o_name, ptr)) return FALSE;
1705 if (!IS_FLG(FLG_COLLECTING)) return TRUE;
1707 for (int j = 0; j < INVEN_PACK; j++)
1710 * 'Collecting' means the item must be absorbed
1711 * into an inventory slot.
1712 * But an item can not be absorbed into itself!
1714 if ((&player_ptr->inventory_list[j] != o_ptr) &&
1715 object_similar(&player_ptr->inventory_list[j], o_ptr))
1724 * A function for Auto-picker/destroyer
1725 * Examine whether the object matches to the list of keywords or not.
1727 int is_autopick(player_type *player_ptr, object_type *o_ptr)
1729 GAME_TEXT o_name[MAX_NLEN];
1730 if (o_ptr->tval == TV_GOLD) return -1;
1732 object_desc(player_ptr, o_name, o_ptr, (OD_NO_FLAVOR | OD_OMIT_PREFIX | OD_NO_PLURAL));
1733 str_tolower(o_name);
1734 for (int i = 0; i < max_autopick; i++)
1736 autopick_type *entry = &autopick_list[i];
1737 if (is_autopick_aux(player_ptr, o_ptr, entry, o_name))
1748 static void auto_inscribe_item(player_type *player_ptr, object_type *o_ptr, int idx)
1750 if (idx < 0 || !autopick_list[idx].insc) return;
1752 if (!o_ptr->inscription)
1753 o_ptr->inscription = quark_add(autopick_list[idx].insc);
1755 player_ptr->window |= (PW_EQUIP | PW_INVEN);
1756 player_ptr->update |= (PU_BONUS);
1761 * Automatically destroy items in this grid.
1763 static bool is_opt_confirm_destroy(player_type *player_ptr, object_type *o_ptr)
1765 if (!destroy_items) return FALSE;
1768 if (object_value(o_ptr) > 0) return FALSE;
1771 if (object_is_weapon_armour_ammo(o_ptr)) return FALSE;
1774 if ((o_ptr->tval == TV_CHEST) && o_ptr->pval) return FALSE;
1778 if (object_is_bounty(o_ptr)) return FALSE;
1782 if (o_ptr->tval == TV_CORPSE) return FALSE;
1785 if ((o_ptr->tval == TV_SKELETON) || (o_ptr->tval == TV_BOTTLE) || (o_ptr->tval == TV_JUNK) || (o_ptr->tval == TV_STATUE)) return FALSE;
1789 if (player_ptr->prace == RACE_DEMON)
1791 if (o_ptr->tval == TV_CORPSE &&
1792 o_ptr->sval == SV_CORPSE &&
1793 my_strchr("pht", r_info[o_ptr->pval].d_char))
1797 if (player_ptr->pclass == CLASS_ARCHER)
1799 if (o_ptr->tval == TV_SKELETON ||
1800 (o_ptr->tval == TV_CORPSE && o_ptr->sval == SV_SKELETON))
1803 else if (player_ptr->pclass == CLASS_NINJA)
1805 if (o_ptr->tval == TV_LITE &&
1806 o_ptr->name2 == EGO_LITE_DARKNESS && object_is_known(o_ptr))
1809 else if (player_ptr->pclass == CLASS_BEASTMASTER ||
1810 player_ptr->pclass == CLASS_CAVALRY)
1812 if (o_ptr->tval == TV_WAND &&
1813 o_ptr->sval == SV_WAND_HEAL_MONSTER && object_is_aware(o_ptr))
1818 if (o_ptr->tval == TV_GOLD) return FALSE;
1824 static void auto_destroy_item(player_type *player_ptr, object_type *o_ptr, int autopick_idx)
1826 bool destroy = FALSE;
1827 if (is_opt_confirm_destroy(player_ptr, o_ptr)) destroy = TRUE;
1829 if (autopick_idx >= 0 &&
1830 !(autopick_list[autopick_idx].action & DO_AUTODESTROY))
1835 if (autopick_idx >= 0 &&
1836 (autopick_list[autopick_idx].action & DO_AUTODESTROY))
1840 if (!destroy) return;
1842 disturb(player_ptr, FALSE, FALSE);
1843 if (!can_player_destroy_object(o_ptr))
1845 GAME_TEXT o_name[MAX_NLEN];
1846 object_desc(player_ptr, o_name, o_ptr, 0);
1847 msg_format(_("%sは破壊不能だ。", "You cannot auto-destroy %s."), o_name);
1851 (void)COPY(&autopick_last_destroyed_object, o_ptr, object_type);
1852 o_ptr->marked |= OM_AUTODESTROY;
1853 player_ptr->update |= PU_AUTODESTROY;
1858 * Auto-destroy marked item
1860 static void autopick_delayed_alter_aux(player_type *player_ptr, INVENTORY_IDX item)
1863 o_ptr = REF_ITEM(player_ptr, player_ptr->current_floor_ptr, item);
1865 if (o_ptr->k_idx == 0 || !(o_ptr->marked & OM_AUTODESTROY)) return;
1867 GAME_TEXT o_name[MAX_NLEN];
1868 object_desc(player_ptr, o_name, o_ptr, 0);
1871 inven_item_increase(player_ptr, item, -(o_ptr->number));
1872 inven_item_optimize(player_ptr, item);
1876 delete_object_idx(player_ptr, 0 - item);
1879 msg_format(_("%sを自動破壊します。", "Auto-destroying %s."), o_name);
1884 * Auto-destroy marked items in inventry and on floor
1886 void autopick_delayed_alter(player_type *owner_ptr)
1891 * Scan inventry in reverse order to prevent
1892 * skipping after inven_item_optimize()
1894 for (item = INVEN_TOTAL - 1; item >= 0; item--)
1895 autopick_delayed_alter_aux(owner_ptr, item);
1897 floor_type *floor_ptr = owner_ptr->current_floor_ptr;
1898 item = floor_ptr->grid_array[owner_ptr->y][owner_ptr->x].o_idx;
1901 OBJECT_IDX next = floor_ptr->o_list[item].next_o_idx;
1902 autopick_delayed_alter_aux(owner_ptr, -item);
1909 * Auto-inscription and/or destroy
1911 * Auto-destroyer works only on inventory or on floor stack only when
1914 void autopick_alter_item(player_type *player_ptr, INVENTORY_IDX item, bool destroy)
1917 o_ptr = REF_ITEM(player_ptr, player_ptr->current_floor_ptr, item);
1918 int idx = is_autopick(player_ptr, o_ptr);
1919 auto_inscribe_item(player_ptr, o_ptr, idx);
1920 if (destroy && item <= INVEN_PACK)
1921 auto_destroy_item(player_ptr, o_ptr, idx);
1926 * Automatically pickup/destroy items in this grid.
1928 void autopick_pickup_items(player_type* player_ptr, grid_type *g_ptr)
1930 OBJECT_IDX this_o_idx, next_o_idx = 0;
1931 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
1933 object_type *o_ptr = &player_ptr->current_floor_ptr->o_list[this_o_idx];
1934 next_o_idx = o_ptr->next_o_idx;
1935 int idx = is_autopick(player_ptr, o_ptr);
1936 auto_inscribe_item(player_ptr, o_ptr, idx);
1937 bool is_auto_pickup = idx >= 0;
1938 is_auto_pickup &= (autopick_list[idx].action & (DO_AUTOPICK | DO_QUERY_AUTOPICK)) != 0;
1939 if (!is_auto_pickup)
1941 auto_destroy_item(player_ptr, o_ptr, idx);
1945 disturb(player_ptr, FALSE, FALSE);
1946 if (!inven_carry_okay(o_ptr))
1948 GAME_TEXT o_name[MAX_NLEN];
1949 object_desc(player_ptr, o_name, o_ptr, 0);
1950 msg_format(_("ザックには%sを入れる隙間がない。", "You have no room for %s."), o_name);
1951 o_ptr->marked |= OM_NOMSG;
1955 if (!(autopick_list[idx].action & DO_QUERY_AUTOPICK))
1957 py_pickup_aux(player_ptr, this_o_idx);
1961 char out_val[MAX_NLEN + 20];
1962 GAME_TEXT o_name[MAX_NLEN];
1963 if (o_ptr->marked & OM_NO_QUERY)
1968 object_desc(player_ptr, o_name, o_ptr, 0);
1969 sprintf(out_val, _("%sを拾いますか? ", "Pick up %s? "), o_name);
1970 if (!get_check(out_val))
1972 o_ptr->marked |= OM_NOMSG | OM_NO_QUERY;
1976 py_pickup_aux(player_ptr, this_o_idx);
1981 static const char autoregister_header[] = "?:$AUTOREGISTER";
1984 * Clear auto registered lines in the picktype.prf .
1986 static bool clear_auto_register(player_type *player_ptr)
1988 char tmp_file[1024];
1989 char pref_file[1024];
1994 bool autoregister = FALSE;
1997 path_build(pref_file, sizeof(pref_file), ANGBAND_DIR_USER, pickpref_filename(player_ptr, PT_WITH_PNAME));
1998 pref_fff = my_fopen(pref_file, "r");
2002 path_build(pref_file, sizeof(pref_file), ANGBAND_DIR_USER, pickpref_filename(player_ptr, PT_DEFAULT));
2003 pref_fff = my_fopen(pref_file, "r");
2011 tmp_fff = my_fopen_temp(tmp_file, sizeof(tmp_file));
2015 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
2022 if (my_fgets(pref_fff, buf, sizeof(buf))) break;
2026 if (buf[0] != '#' && buf[0] != '?') num++;
2030 if (streq(buf, autoregister_header))
2032 autoregister = TRUE;
2036 fprintf(tmp_fff, "%s\n", buf);
2040 my_fclose(pref_fff);
2045 msg_format(_("以前のキャラクター用の自動設定(%d行)が残っています。",
2046 "Auto registered lines (%d lines) for previous character are remaining."), num);
2047 strcpy(buf, _("古い設定行は削除します。よろしいですか?", "These lines will be deleted. Are you sure? "));
2049 if (!get_check(buf))
2052 autoregister = FALSE;
2054 msg_print(_("エディタのカット&ペースト等を使って必要な行を避難してください。",
2055 "Use cut & paste of auto picker editor (_) to keep old prefs."));
2061 tmp_fff = my_fopen(tmp_file, "r");
2062 pref_fff = my_fopen(pref_file, "w");
2064 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
2065 fprintf(pref_fff, "%s\n", buf);
2067 my_fclose(pref_fff);
2077 * Automatically register an auto-destroy preference line
2079 bool autopick_autoregister(player_type *player_ptr, object_type *o_ptr)
2082 char pref_file[1024];
2084 autopick_type an_entry, *entry = &an_entry;
2085 int match_autopick = is_autopick(player_ptr, o_ptr);
2086 if (match_autopick != -1)
2089 byte act = autopick_list[match_autopick].action;
2090 if (act & DO_AUTOPICK) what = _("自動で拾う", "auto-pickup");
2091 else if (act & DO_AUTODESTROY) what = _("自動破壊する", "auto-destroy");
2092 else if (act & DONT_AUTOPICK) what = _("放置する", "leave on floor");
2093 else what = _("確認して拾う", "query auto-pickup");
2095 msg_format(_("そのアイテムは既に%sように設定されています。", "The object is already registered to %s."), what);
2099 if ((object_is_known(o_ptr) && object_is_artifact(o_ptr)) ||
2100 ((o_ptr->ident & IDENT_SENSE) &&
2101 (o_ptr->feeling == FEEL_TERRIBLE || o_ptr->feeling == FEEL_SPECIAL)))
2103 GAME_TEXT o_name[MAX_NLEN];
2104 object_desc(player_ptr, o_name, o_ptr, 0);
2105 msg_format(_("%sは破壊不能だ。", "You cannot auto-destroy %s."), o_name);
2109 if (!player_ptr->autopick_autoregister)
2111 if (!clear_auto_register(player_ptr)) return FALSE;
2114 path_build(pref_file, sizeof(pref_file), ANGBAND_DIR_USER, pickpref_filename(player_ptr, PT_WITH_PNAME));
2115 pref_fff = my_fopen(pref_file, "r");
2119 path_build(pref_file, sizeof(pref_file), ANGBAND_DIR_USER, pickpref_filename(player_ptr, PT_DEFAULT));
2120 pref_fff = my_fopen(pref_file, "r");
2127 if (my_fgets(pref_fff, buf, sizeof(buf)))
2129 player_ptr->autopick_autoregister = FALSE;
2133 if (streq(buf, autoregister_header))
2135 player_ptr->autopick_autoregister = TRUE;
2145 * File could not be opened for reading. Assume header not
2148 player_ptr->autopick_autoregister = FALSE;
2151 pref_fff = my_fopen(pref_file, "a");
2154 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), pref_file);
2159 if (!player_ptr->autopick_autoregister)
2161 fprintf(pref_fff, "%s\n", autoregister_header);
2163 fprintf(pref_fff, "%s\n", _("# *警告!!* 以降の行は自動登録されたものです。",
2164 "# *Warning!* The lines below will be deleted later."));
2165 fprintf(pref_fff, "%s\n", _("# 後で自動的に削除されますので、必要な行は上の方へ移動しておいてください。",
2166 "# Keep it by cut & paste if you need these lines for future characters."));
2167 player_ptr->autopick_autoregister = TRUE;
2170 autopick_entry_from_object(player_ptr, entry, o_ptr);
2171 entry->action = DO_AUTODESTROY;
2172 add_autopick_list(entry);
2174 concptr tmp = autopick_line_from_entry(entry);
2175 fprintf(pref_fff, "%s\n", tmp);
2183 * Describe which kind of object is Auto-picked/destroyed
2185 static void describe_autopick(char *buff, autopick_type *entry)
2187 concptr str = entry->name;
2188 byte act = entry->action;
2189 concptr insc = entry->insc;
2195 concptr before_str[100], body_str;
2199 if (IS_FLG(FLG_COLLECTING))
2200 before_str[before_n++] = "収集中で既に持っているスロットにまとめられる";
2202 if (IS_FLG(FLG_UNAWARE))
2203 before_str[before_n++] = "未鑑定でその効果も判明していない";
2205 if (IS_FLG(FLG_UNIDENTIFIED))
2206 before_str[before_n++] = "未鑑定の";
2208 if (IS_FLG(FLG_IDENTIFIED))
2209 before_str[before_n++] = "鑑定済みの";
2211 if (IS_FLG(FLG_STAR_IDENTIFIED))
2212 before_str[before_n++] = "完全に鑑定済みの";
2214 if (IS_FLG(FLG_BOOSTED))
2216 before_str[before_n++] = "ダメージダイスが通常より大きい";
2220 if (IS_FLG(FLG_MORE_DICE))
2222 static char more_than_desc_str[] = "___";
2223 before_str[before_n++] = "ダメージダイスの最大値が";
2226 sprintf(more_than_desc_str, "%d", entry->dice);
2227 before_str[before_n++] = more_than_desc_str;
2228 before_str[before_n++] = "以上の";
2231 if (IS_FLG(FLG_MORE_BONUS))
2233 static char more_bonus_desc_str[] = "___";
2234 before_str[before_n++] = "修正値が(+";
2236 sprintf(more_bonus_desc_str, "%d", entry->bonus);
2237 before_str[before_n++] = more_bonus_desc_str;
2238 before_str[before_n++] = ")以上の";
2241 if (IS_FLG(FLG_WORTHLESS))
2242 before_str[before_n++] = "店で無価値と判定される";
2244 if (IS_FLG(FLG_ARTIFACT))
2246 before_str[before_n++] = "アーティファクトの";
2250 if (IS_FLG(FLG_EGO))
2252 before_str[before_n++] = "エゴアイテムの";
2256 if (IS_FLG(FLG_GOOD))
2258 before_str[before_n++] = "上質の";
2262 if (IS_FLG(FLG_NAMELESS))
2264 before_str[before_n++] = "エゴでもアーティファクトでもない";
2268 if (IS_FLG(FLG_AVERAGE))
2270 before_str[before_n++] = "並の";
2274 if (IS_FLG(FLG_RARE))
2276 before_str[before_n++] = "ドラゴン装備やカオス・ブレード等を含む珍しい";
2280 if (IS_FLG(FLG_COMMON))
2282 before_str[before_n++] = "ありふれた(ドラゴン装備やカオス・ブレード等の珍しい物ではない)";
2286 if (IS_FLG(FLG_WANTED))
2288 before_str[before_n++] = "ハンター事務所で賞金首とされている";
2292 if (IS_FLG(FLG_HUMAN))
2294 before_str[before_n++] = "悪魔魔法で使うための人間やヒューマノイドの";
2298 if (IS_FLG(FLG_UNIQUE))
2300 before_str[before_n++] = "ユニークモンスターの";
2304 if (IS_FLG(FLG_UNREADABLE))
2306 before_str[before_n++] = "あなたが読めない領域の";
2310 if (IS_FLG(FLG_REALM1))
2312 before_str[before_n++] = "第一領域の";
2316 if (IS_FLG(FLG_REALM2))
2318 before_str[before_n++] = "第二領域の";
2322 if (IS_FLG(FLG_FIRST))
2324 before_str[before_n++] = "全4冊の内の1冊目の";
2328 if (IS_FLG(FLG_SECOND))
2330 before_str[before_n++] = "全4冊の内の2冊目の";
2334 if (IS_FLG(FLG_THIRD))
2336 before_str[before_n++] = "全4冊の内の3冊目の";
2340 if (IS_FLG(FLG_FOURTH))
2342 before_str[before_n++] = "全4冊の内の4冊目の";
2346 if (IS_FLG(FLG_ITEMS))
2347 ; /* Nothing to do */
2348 else if (IS_FLG(FLG_WEAPONS))
2350 else if (IS_FLG(FLG_FAVORITE_WEAPONS))
2352 else if (IS_FLG(FLG_ARMORS))
2354 else if (IS_FLG(FLG_MISSILES))
2355 body_str = "弾や矢やクロスボウの矢";
2356 else if (IS_FLG(FLG_DEVICES))
2357 body_str = "巻物や魔法棒や杖やロッド";
2358 else if (IS_FLG(FLG_LIGHTS))
2359 body_str = "光源用のアイテム";
2360 else if (IS_FLG(FLG_JUNKS))
2361 body_str = "折れた棒等のガラクタ";
2362 else if (IS_FLG(FLG_CORPSES))
2364 else if (IS_FLG(FLG_SPELLBOOKS))
2366 else if (IS_FLG(FLG_HAFTED))
2368 else if (IS_FLG(FLG_SHIELDS))
2370 else if (IS_FLG(FLG_BOWS))
2371 body_str = "スリングや弓やクロスボウ";
2372 else if (IS_FLG(FLG_RINGS))
2374 else if (IS_FLG(FLG_AMULETS))
2375 body_str = "アミュレット";
2376 else if (IS_FLG(FLG_SUITS))
2378 else if (IS_FLG(FLG_CLOAKS))
2380 else if (IS_FLG(FLG_HELMS))
2381 body_str = "ヘルメットや冠";
2382 else if (IS_FLG(FLG_GLOVES))
2384 else if (IS_FLG(FLG_BOOTS))
2389 strcat(buff, "全ての");
2390 else for (i = 0; i < before_n && before_str[i]; i++)
2391 strcat(buff, before_str[i]);
2393 strcat(buff, body_str);
2403 strcat(buff, "で、名前が「");
2404 strncat(buff, str, 80);
2406 strcat(buff, "」で始まるもの");
2408 strcat(buff, "」を含むもの");
2413 strncat(buff, format("に「%s」", insc), 80);
2415 if (my_strstr(insc, "%%all"))
2416 strcat(buff, "(%%allは全能力を表す英字の記号で置換)");
2417 else if (my_strstr(insc, "%all"))
2418 strcat(buff, "(%allは全能力を表す記号で置換)");
2419 else if (my_strstr(insc, "%%"))
2420 strcat(buff, "(%%は追加能力を表す英字の記号で置換)");
2421 else if (my_strstr(insc, "%"))
2422 strcat(buff, "(%は追加能力を表す記号で置換)");
2424 strcat(buff, "と刻んで");
2429 if (act & DONT_AUTOPICK)
2430 strcat(buff, "放置する。");
2431 else if (act & DO_AUTODESTROY)
2432 strcat(buff, "破壊する。");
2433 else if (act & DO_QUERY_AUTOPICK)
2434 strcat(buff, "確認の後に拾う。");
2436 strcat(buff, "拾う。");
2438 if (act & DO_DISPLAY)
2440 if (act & DONT_AUTOPICK)
2441 strcat(buff, "全体マップ('M')で'N'を押したときに表示する。");
2442 else if (act & DO_AUTODESTROY)
2443 strcat(buff, "全体マップ('M')で'K'を押したときに表示する。");
2445 strcat(buff, "全体マップ('M')で'M'を押したときに表示する。");
2448 strcat(buff, "全体マップには表示しない。");
2452 concptr before_str[20], after_str[20], which_str[20], whose_str[20], body_str;
2453 int before_n = 0, after_n = 0, which_n = 0, whose_n = 0;
2455 if (IS_FLG(FLG_COLLECTING))
2456 which_str[which_n++] = "can be absorbed into an existing inventory list slot";
2458 if (IS_FLG(FLG_UNAWARE))
2460 before_str[before_n++] = "unidentified";
2461 whose_str[whose_n++] = "basic abilities are not known";
2464 if (IS_FLG(FLG_UNIDENTIFIED))
2465 before_str[before_n++] = "unidentified";
2467 if (IS_FLG(FLG_IDENTIFIED))
2468 before_str[before_n++] = "identified";
2470 if (IS_FLG(FLG_STAR_IDENTIFIED))
2471 before_str[before_n++] = "fully identified";
2473 if (IS_FLG(FLG_RARE))
2475 before_str[before_n++] = "very rare";
2476 body_str = "equipments";
2477 after_str[after_n++] = "such as Dragon armor, Blades of Chaos, etc.";
2480 if (IS_FLG(FLG_COMMON))
2482 before_str[before_n++] = "relatively common";
2483 body_str = "equipments";
2484 after_str[after_n++] = "compared to very rare Dragon armor, Blades of Chaos, etc.";
2487 if (IS_FLG(FLG_WORTHLESS))
2489 before_str[before_n++] = "worthless";
2490 which_str[which_n++] = "can not be sold at stores";
2493 if (IS_FLG(FLG_ARTIFACT))
2495 before_str[before_n++] = "artifact";
2498 if (IS_FLG(FLG_EGO))
2500 before_str[before_n++] = "ego";
2503 if (IS_FLG(FLG_GOOD))
2505 body_str = "equipment";
2506 which_str[which_n++] = "have good quality";
2509 if (IS_FLG(FLG_NAMELESS))
2511 body_str = "equipment";
2512 which_str[which_n++] = "is neither ego-item nor artifact";
2515 if (IS_FLG(FLG_AVERAGE))
2517 body_str = "equipment";
2518 which_str[which_n++] = "have average quality";
2521 if (IS_FLG(FLG_BOOSTED))
2523 body_str = "weapons";
2524 whose_str[whose_n++] = "damage dice is bigger than normal";
2527 if (IS_FLG(FLG_MORE_DICE))
2529 static char more_than_desc_str[] =
2530 "maximum damage from dice is bigger than __";
2531 body_str = "weapons";
2533 sprintf(more_than_desc_str + sizeof(more_than_desc_str) - 3,
2535 whose_str[whose_n++] = more_than_desc_str;
2538 if (IS_FLG(FLG_MORE_BONUS))
2540 static char more_bonus_desc_str[] =
2541 "magical bonus is bigger than (+__)";
2543 sprintf(more_bonus_desc_str + sizeof(more_bonus_desc_str) - 4,
2544 "%d)", entry->bonus);
2545 whose_str[whose_n++] = more_bonus_desc_str;
2548 if (IS_FLG(FLG_WANTED))
2550 body_str = "corpse or skeletons";
2551 which_str[which_n++] = "is wanted at the Hunter's Office";
2554 if (IS_FLG(FLG_HUMAN))
2556 before_str[before_n++] = "humanoid";
2557 body_str = "corpse or skeletons";
2558 which_str[which_n++] = "can be used for Daemon magic";
2561 if (IS_FLG(FLG_UNIQUE))
2563 before_str[before_n++] = "unique monster's";
2564 body_str = "corpse or skeletons";
2567 if (IS_FLG(FLG_UNREADABLE))
2569 body_str = "spellbooks";
2570 after_str[after_n++] = "of different realms from yours";
2573 if (IS_FLG(FLG_REALM1))
2575 body_str = "spellbooks";
2576 after_str[after_n++] = "of your first realm";
2579 if (IS_FLG(FLG_REALM2))
2581 body_str = "spellbooks";
2582 after_str[after_n++] = "of your second realm";
2585 if (IS_FLG(FLG_FIRST))
2587 before_str[before_n++] = "first one of four";
2588 body_str = "spellbooks";
2591 if (IS_FLG(FLG_SECOND))
2593 before_str[before_n++] = "second one of four";
2594 body_str = "spellbooks";
2597 if (IS_FLG(FLG_THIRD))
2599 before_str[before_n++] = "third one of four";
2600 body_str = "spellbooks";
2603 if (IS_FLG(FLG_FOURTH))
2605 before_str[before_n++] = "fourth one of four";
2606 body_str = "spellbooks";
2609 if (IS_FLG(FLG_ITEMS))
2610 ; /* Nothing to do */
2611 else if (IS_FLG(FLG_WEAPONS))
2612 body_str = "weapons";
2613 else if (IS_FLG(FLG_FAVORITE_WEAPONS))
2614 body_str = "favorite weapons";
2615 else if (IS_FLG(FLG_ARMORS))
2616 body_str = "armors";
2617 else if (IS_FLG(FLG_MISSILES))
2618 body_str = "shots, arrows or crossbow bolts";
2619 else if (IS_FLG(FLG_DEVICES))
2620 body_str = "scrolls, wands, staffs or rods";
2621 else if (IS_FLG(FLG_LIGHTS))
2622 body_str = "light sources";
2623 else if (IS_FLG(FLG_JUNKS))
2624 body_str = "junk such as broken sticks";
2625 else if (IS_FLG(FLG_CORPSES))
2626 body_str = "corpses or skeletons";
2627 else if (IS_FLG(FLG_SPELLBOOKS))
2628 body_str = "spellbooks";
2629 else if (IS_FLG(FLG_HAFTED))
2630 body_str = "hafted weapons";
2631 else if (IS_FLG(FLG_SHIELDS))
2632 body_str = "shields";
2633 else if (IS_FLG(FLG_BOWS))
2634 body_str = "slings, bows or crossbows";
2635 else if (IS_FLG(FLG_RINGS))
2637 else if (IS_FLG(FLG_AMULETS))
2638 body_str = "amulets";
2639 else if (IS_FLG(FLG_SUITS))
2640 body_str = "body armors";
2641 else if (IS_FLG(FLG_CLOAKS))
2642 body_str = "cloaks";
2643 else if (IS_FLG(FLG_HELMS))
2644 body_str = "helms or crowns";
2645 else if (IS_FLG(FLG_GLOVES))
2646 body_str = "gloves";
2647 else if (IS_FLG(FLG_BOOTS))
2656 whose_str[whose_n++] = "name begins with \"";
2659 which_str[which_n++] = "have \"";
2663 if (act & DONT_AUTOPICK)
2664 strcpy(buff, "Leave on floor ");
2665 else if (act & DO_AUTODESTROY)
2666 strcpy(buff, "Destroy ");
2667 else if (act & DO_QUERY_AUTOPICK)
2668 strcpy(buff, "Ask to pick up ");
2670 strcpy(buff, "Pickup ");
2674 strncat(buff, format("and inscribe \"%s\"", insc), 80);
2676 if (my_strstr(insc, "%all"))
2677 strcat(buff, ", replacing %all with code string representing all abilities,");
2678 else if (my_strstr(insc, "%"))
2679 strcat(buff, ", replacing % with code string representing extra random abilities,");
2681 strcat(buff, " on ");
2685 strcat(buff, "all ");
2686 else for (i = 0; i < before_n && before_str[i]; i++)
2688 strcat(buff, before_str[i]);
2692 strcat(buff, body_str);
2694 for (i = 0; i < after_n && after_str[i]; i++)
2697 strcat(buff, after_str[i]);
2700 for (i = 0; i < whose_n && whose_str[i]; i++)
2703 strcat(buff, " whose ");
2705 strcat(buff, ", and ");
2707 strcat(buff, whose_str[i]);
2716 if (whose_n && which_n)
2717 strcat(buff, ", and ");
2719 for (i = 0; i < which_n && which_str[i]; i++)
2722 strcat(buff, " which ");
2724 strcat(buff, ", and ");
2726 strcat(buff, which_str[i]);
2731 strncat(buff, str, 80);
2732 strcat(buff, "\" as part of its name");
2736 if (act & DO_DISPLAY)
2738 if (act & DONT_AUTOPICK)
2739 strcat(buff, " Display these items when you press the N key in the full 'M'ap.");
2740 else if (act & DO_AUTODESTROY)
2741 strcat(buff, " Display these items when you press the K key in the full 'M'ap.");
2743 strcat(buff, " Display these items when you press the M key in the full 'M'ap.");
2746 strcat(buff, " Not displayed in the full map.");
2752 * Read whole lines of a file to memory
2754 static concptr *read_text_lines(concptr filename)
2756 concptr *lines_list = NULL;
2762 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, filename);
2763 fff = my_fopen(buf, "r");
2764 if (!fff) return NULL;
2766 C_MAKE(lines_list, MAX_LINES, concptr);
2767 while (my_fgets(fff, buf, sizeof(buf)) == 0)
2769 lines_list[lines++] = string_make(buf);
2770 if (lines >= MAX_LINES - 1) break;
2774 lines_list[0] = string_make("");
2782 * Copy the default autopick file to the user directory
2784 static void prepare_default_pickpref(player_type *player_ptr)
2786 const concptr messages[] = {
2787 _("あなたは「自動拾いエディタ」を初めて起動しました。", "You have activated the Auto-Picker Editor for the first time."),
2788 _("自動拾いのユーザー設定ファイルがまだ書かれていないので、", "Since user pref file for autopick is not yet created,"),
2789 _("基本的な自動拾い設定ファイルをlib/pref/picktype.prfからコピーします。", "the default setting is loaded from lib/pref/pickpref.prf ."),
2793 concptr filename = pickpref_filename(player_ptr, PT_DEFAULT);
2794 for (int i = 0; messages[i]; i++)
2796 msg_print(messages[i]);
2801 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, filename);
2803 user_fp = my_fopen(buf, "w");
2804 if (!user_fp) return;
2806 fprintf(user_fp, "#***\n");
2807 for (int i = 0; messages[i]; i++)
2809 fprintf(user_fp, "#*** %s\n", messages[i]);
2812 fprintf(user_fp, "#***\n\n\n");
2813 path_build(buf, sizeof(buf), ANGBAND_DIR_PREF, filename);
2815 pref_fp = my_fopen(buf, "r");
2823 while (!my_fgets(pref_fp, buf, sizeof(buf)))
2825 fprintf(user_fp, "%s\n", buf);
2833 * Read an autopick prefence file to memory
2834 * Prepare default if no user file is found
2836 static concptr *read_pickpref_text_lines(player_type *player_ptr, int *filename_mode_p)
2838 /* Try a filename with player name */
2839 *filename_mode_p = PT_WITH_PNAME;
2841 strcpy(buf, pickpref_filename(player_ptr, *filename_mode_p));
2842 concptr *lines_list;
2843 lines_list = read_text_lines(buf);
2847 *filename_mode_p = PT_DEFAULT;
2848 strcpy(buf, pickpref_filename(player_ptr, *filename_mode_p));
2849 lines_list = read_text_lines(buf);
2854 prepare_default_pickpref(player_ptr);
2855 lines_list = read_text_lines(buf);
2860 C_MAKE(lines_list, MAX_LINES, concptr);
2861 lines_list[0] = string_make("");
2869 * Write whole lines of memory to a file.
2871 static bool write_text_lines(concptr filename, concptr *lines_list)
2874 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, filename);
2876 fff = my_fopen(buf, "w");
2877 if (!fff) return FALSE;
2879 for (int lines = 0; lines_list[lines]; lines++)
2881 my_fputs(fff, lines_list[lines], 1024);
2890 * Free memory of lines_list.
2892 static void free_text_lines(concptr *lines_list)
2894 for (int lines = 0; lines_list[lines]; lines++)
2896 string_free(lines_list[lines]);
2899 /* free list of pointers */
2900 C_KILL(lines_list, MAX_LINES, concptr);
2905 * Delete or insert string
2907 static void toggle_keyword(text_body_type *tb, BIT_FLAGS flg)
2914 by1 = MIN(tb->my, tb->cy);
2915 by2 = MAX(tb->my, tb->cy);
2917 else /* if (!tb->mark) */
2922 for (int y = by1; y <= by2; y++)
2924 autopick_type an_entry, *entry = &an_entry;
2925 if (!autopick_new_entry(entry, tb->lines_list[y], !fixed)) continue;
2927 string_free(tb->lines_list[y]);
2930 if (!IS_FLG(flg)) add = TRUE;
2936 if (FLG_NOUN_BEGIN <= flg && flg <= FLG_NOUN_END)
2939 for (i = FLG_NOUN_BEGIN; i <= FLG_NOUN_END; i++)
2942 else if (FLG_UNAWARE <= flg && flg <= FLG_STAR_IDENTIFIED)
2945 for (i = FLG_UNAWARE; i <= FLG_STAR_IDENTIFIED; i++)
2948 else if (FLG_ARTIFACT <= flg && flg <= FLG_AVERAGE)
2951 for (i = FLG_ARTIFACT; i <= FLG_AVERAGE; i++)
2954 else if (FLG_RARE <= flg && flg <= FLG_COMMON)
2957 for (i = FLG_RARE; i <= FLG_COMMON; i++)
2961 if (add) ADD_FLG(flg);
2964 tb->lines_list[y] = autopick_line_from_entry_kill(entry);
2965 tb->dirty_flags |= DIRTY_ALL;
2972 * Change command letter
2974 static void toggle_command_letter(text_body_type *tb, byte flg)
2976 autopick_type an_entry, *entry = &an_entry;
2982 by1 = MIN(tb->my, tb->cy);
2983 by2 = MAX(tb->my, tb->cy);
2985 else /* if (!tb->mark) */
2990 for (y = by1; y <= by2; y++)
2994 if (!autopick_new_entry(entry, tb->lines_list[y], FALSE)) continue;
2996 string_free(tb->lines_list[y]);
3000 if (!(entry->action & flg)) add = TRUE;
3006 if (entry->action & DONT_AUTOPICK) wid--;
3007 else if (entry->action & DO_AUTODESTROY) wid--;
3008 else if (entry->action & DO_QUERY_AUTOPICK) wid--;
3009 if (!(entry->action & DO_DISPLAY)) wid--;
3011 if (flg != DO_DISPLAY)
3013 entry->action &= ~(DO_AUTOPICK | DONT_AUTOPICK | DO_AUTODESTROY | DO_QUERY_AUTOPICK);
3014 if (add) entry->action |= flg;
3015 else entry->action |= DO_AUTOPICK;
3019 entry->action &= ~(DO_DISPLAY);
3020 if (add) entry->action |= flg;
3025 if (entry->action & DONT_AUTOPICK) wid++;
3026 else if (entry->action & DO_AUTODESTROY) wid++;
3027 else if (entry->action & DO_QUERY_AUTOPICK) wid++;
3028 if (!(entry->action & DO_DISPLAY)) wid++;
3030 if (wid > 0) tb->cx++;
3031 if (wid < 0 && tb->cx > 0) tb->cx--;
3034 tb->lines_list[y] = autopick_line_from_entry_kill(entry);
3035 tb->dirty_flags |= DIRTY_ALL;
3042 * Delete or insert string
3044 static void add_keyword(text_body_type *tb, BIT_FLAGS flg)
3049 by1 = MIN(tb->my, tb->cy);
3050 by2 = MAX(tb->my, tb->cy);
3057 for (int y = by1; y <= by2; y++)
3059 autopick_type an_entry, *entry = &an_entry;
3060 if (!autopick_new_entry(entry, tb->lines_list[y], FALSE)) continue;
3064 autopick_free_entry(entry);
3068 string_free(tb->lines_list[y]);
3069 if (FLG_NOUN_BEGIN <= flg && flg <= FLG_NOUN_END)
3072 for (i = FLG_NOUN_BEGIN; i <= FLG_NOUN_END; i++)
3077 tb->lines_list[y] = autopick_line_from_entry_kill(entry);
3078 tb->dirty_flags |= DIRTY_ALL;
3085 * Check if this line is expression or not.
3086 * And update it if it is.
3088 static void check_expression_line(text_body_type *tb, int y)
3090 concptr s = tb->lines_list[y];
3092 if ((s[0] == '?' && s[1] == ':') ||
3093 (tb->states[y] & LSTAT_BYPASS))
3095 tb->dirty_flags |= DIRTY_EXPRESSION;
3101 * Add an empty line at the last of the file
3103 static bool add_empty_line(text_body_type *tb)
3106 for (num_lines = 0; tb->lines_list[num_lines]; num_lines++);
3108 if (num_lines >= MAX_LINES - 2) return FALSE;
3109 if (!tb->lines_list[num_lines - 1][0]) return FALSE;
3111 tb->lines_list[num_lines] = string_make("");
3112 tb->dirty_flags |= DIRTY_EXPRESSION;
3119 * Insert return code and split the line
3121 static bool insert_return_code(text_body_type *tb)
3123 char buf[MAX_LINELEN];
3124 int i, j, num_lines;
3126 for (num_lines = 0; tb->lines_list[num_lines]; num_lines++);
3128 if (num_lines >= MAX_LINES - 2) return FALSE;
3131 for (; tb->cy < num_lines; num_lines--)
3133 tb->lines_list[num_lines + 1] = tb->lines_list[num_lines];
3134 tb->states[num_lines + 1] = tb->states[num_lines];
3137 for (i = j = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
3140 if (iskanji(tb->lines_list[tb->cy][i]))
3141 buf[j++] = tb->lines_list[tb->cy][i++];
3143 buf[j++] = tb->lines_list[tb->cy][i];
3147 tb->lines_list[tb->cy + 1] = string_make(&tb->lines_list[tb->cy][i]);
3148 string_free(tb->lines_list[tb->cy]);
3149 tb->lines_list[tb->cy] = string_make(buf);
3150 tb->dirty_flags |= DIRTY_EXPRESSION;
3157 * Choose an item and get auto-picker entry from it.
3159 static bool entry_from_choosed_object(player_type *player_ptr, autopick_type *entry)
3161 concptr q = _("どのアイテムを登録しますか? ", "Enter which item? ");
3162 concptr s = _("アイテムを持っていない。", "You have nothing to enter.");
3164 o_ptr = choose_object(player_ptr, NULL, q, s, USE_INVEN | USE_FLOOR | USE_EQUIP, 0);
3165 if (!o_ptr) return FALSE;
3167 autopick_entry_from_object(player_ptr, entry, o_ptr);
3173 * Choose an item for search
3175 static bool get_object_for_search(player_type *player_ptr, object_type **o_handle, concptr *search_strp)
3177 concptr q = _("どのアイテムを検索しますか? ", "Enter which item? ");
3178 concptr s = _("アイテムを持っていない。", "You have nothing to enter.");
3180 o_ptr = choose_object(player_ptr, NULL, q, s, USE_INVEN | USE_FLOOR | USE_EQUIP, 0);
3181 if (!o_ptr) return FALSE;
3184 string_free(*search_strp);
3185 char buf[MAX_NLEN + 20];
3186 object_desc(player_ptr, buf, *o_handle, (OD_NO_FLAVOR | OD_OMIT_PREFIX | OD_NO_PLURAL));
3187 *search_strp = string_make(format("<%s>", buf));
3193 * Prepare for search by destroyed object
3195 static bool get_destroyed_object_for_search(player_type *player_ptr, object_type **o_handle, concptr *search_strp)
3197 if (!autopick_last_destroyed_object.k_idx) return FALSE;
3199 *o_handle = &autopick_last_destroyed_object;
3200 string_free(*search_strp);
3201 char buf[MAX_NLEN + 20];
3202 object_desc(player_ptr, buf, *o_handle, (OD_NO_FLAVOR | OD_OMIT_PREFIX | OD_NO_PLURAL));
3203 *search_strp = string_make(format("<%s>", buf));
3209 * Choose an item or string for search
3211 static byte get_string_for_search(player_type *player_ptr, object_type **o_handle, concptr *search_strp)
3215 * TERM_YELLOW : Overwrite mode
3216 * TERM_WHITE : Insert mode
3218 byte color = TERM_YELLOW;
3219 char buf[MAX_NLEN + 20];
3221 char prompt[] = _("検索(^I:持ち物 ^L:破壊された物): ", "Search key(^I:inven ^L:destroyed): ");
3222 int col = sizeof(prompt) - 1;
3223 if (*search_strp) strcpy(buf, *search_strp);
3226 if (*o_handle) color = TERM_L_GREEN;
3235 Term_erase(col, 0, 255);
3236 Term_putstr(col, 0, -1, color, buf);
3237 Term_gotoxy(col + pos, 0);
3239 skey = inkey_special(TRUE);
3247 if (pos == 0) break;
3251 int next_pos = i + 1;
3254 if (iskanji(buf[i])) next_pos++;
3256 if (next_pos >= pos) break;
3268 if ('\0' == buf[pos]) break;
3271 if (iskanji(buf[pos])) pos += 2;
3288 if (*o_handle) return (back ? -1 : 1);
3289 string_free(*search_strp);
3290 *search_strp = string_make(buf);
3292 return (back ? -1 : 1);
3295 return get_object_for_search(player_ptr, o_handle, search_strp);
3298 if (get_destroyed_object_for_search(player_ptr, o_handle, search_strp))
3306 if (pos == 0) break;
3310 int next_pos = i + 1;
3312 if (iskanji(buf[i])) next_pos++;
3314 if (next_pos >= pos) break;
3328 if (buf[pos] == '\0') break;
3332 if (iskanji(buf[pos])) src++;
3335 while ('\0' != (buf[dst++] = buf[src++]));
3344 if (skey & SKEY_MASK) break;
3347 if (color != TERM_WHITE)
3349 if (color == TERM_L_GREEN)
3352 string_free(*search_strp);
3353 *search_strp = NULL;
3360 strcpy(tmp, buf + pos);
3382 if (pos < len && (isprint(c) || iskana(c)))
3384 if (pos < len && isprint(c))
3396 my_strcat(buf, tmp, len + 1);
3402 if (*o_handle == NULL || color == TERM_L_GREEN) continue;
3406 string_free(*search_strp);
3407 *search_strp = NULL;
3413 * Search next line matches for o_ptr
3415 static void search_for_object(player_type *player_ptr, text_body_type *tb, object_type *o_ptr, bool forward)
3417 autopick_type an_entry, *entry = &an_entry;
3418 GAME_TEXT o_name[MAX_NLEN];
3419 int bypassed_cy = -1;
3421 object_desc(player_ptr, o_name, o_ptr, (OD_NO_FLAVOR | OD_OMIT_PREFIX | OD_NO_PLURAL));
3422 str_tolower(o_name);
3429 if (!tb->lines_list[++i]) break;
3436 if (!autopick_new_entry(entry, tb->lines_list[i], FALSE)) continue;
3438 match = is_autopick_aux(player_ptr, o_ptr, entry, o_name);
3439 autopick_free_entry(entry);
3440 if (!match) continue;
3442 if (tb->states[i] & LSTAT_BYPASS)
3444 if (bypassed_cy == -1) bypassed_cy = i;
3450 if (bypassed_cy != -1)
3452 tb->dirty_flags |= DIRTY_SKIP_INACTIVE;
3458 if (bypassed_cy == -1)
3460 tb->dirty_flags |= DIRTY_NOT_FOUND;
3465 tb->cy = bypassed_cy;
3466 tb->dirty_flags |= DIRTY_INACTIVE;
3471 * Search next line matches to the string
3473 static void search_for_string(text_body_type *tb, concptr search_str, bool forward)
3475 int bypassed_cy = -1;
3476 int bypassed_cx = 0;
3484 if (!tb->lines_list[++i]) break;
3491 pos = my_strstr(tb->lines_list[i], search_str);
3494 if ((tb->states[i] & LSTAT_BYPASS) &&
3495 !(tb->states[i] & LSTAT_EXPRESSION))
3497 if (bypassed_cy == -1)
3500 bypassed_cx = (int)(pos - tb->lines_list[i]);
3506 tb->cx = (int)(pos - tb->lines_list[i]);
3509 if (bypassed_cy != -1)
3511 tb->dirty_flags |= DIRTY_SKIP_INACTIVE;
3517 if (bypassed_cy == -1)
3519 tb->dirty_flags |= DIRTY_NOT_FOUND;
3523 tb->cx = bypassed_cx;
3524 tb->cy = bypassed_cy;
3525 tb->dirty_flags |= DIRTY_INACTIVE;
3530 * Find a command by 'key'.
3532 static int get_com_id(char key)
3534 for (int i = 0; menu_data[i].name; i++)
3536 if (menu_data[i].key == key)
3538 return menu_data[i].com_id;
3547 * Display the menu, and get a command
3549 static int do_command_menu(int level, int start)
3552 int col0 = 5 + level * 7;
3553 int row0 = 1 + level * 3;
3554 int menu_id_list[26];
3556 char linestr[MAX_LINELEN];
3559 for (int i = start; menu_data[i].level >= level; i++)
3563 /* Ignore lower level sub menus */
3564 if (menu_data[i].level > level) continue;
3566 len = strlen(menu_data[i].name);
3567 if (len > max_len) max_len = len;
3569 menu_id_list[menu_key] = i;
3573 while (menu_key < 26)
3575 menu_id_list[menu_key] = -1;
3579 int max_menu_wid = max_len + 3 + 3;
3581 /* Prepare box line */
3583 strcat(linestr, "+");
3584 for (int i = 0; i < max_menu_wid + 2; i++)
3586 strcat(linestr, "-");
3589 strcat(linestr, "+");
3599 int row1 = row0 + 1;
3600 Term_putstr(col0, row0, -1, TERM_WHITE, linestr);
3603 for (int i = start; menu_data[i].level >= level; i++)
3605 char com_key_str[3];
3607 if (menu_data[i].level > level) continue;
3609 if (menu_data[i].com_id == -1)
3611 strcpy(com_key_str, _("▼", ">"));
3613 else if (menu_data[i].key != -1)
3615 com_key_str[0] = '^';
3616 com_key_str[1] = menu_data[i].key + '@';
3617 com_key_str[2] = '\0';
3621 com_key_str[0] = '\0';
3624 str = format("| %c) %-*s %2s | ", menu_key + 'a', max_len, menu_data[i].name, com_key_str);
3626 Term_putstr(col0, row1++, -1, TERM_WHITE, str);
3631 Term_putstr(col0, row1, -1, TERM_WHITE, linestr);
3635 prt(format(_("(a-%c) コマンド:", "(a-%c) Command:"), menu_key + 'a' - 1), 0, 0);
3638 if (key == ESCAPE) return 0;
3640 bool is_alphabet = key >= 'a' && key <= 'z';
3643 com_id = get_com_id(key);
3652 menu_id = menu_id_list[key - 'a'];
3654 if (menu_id < 0) continue;
3656 com_id = menu_data[menu_id].com_id;
3660 com_id = do_command_menu(level + 1, menu_id + 1);
3662 if (com_id) return com_id;
3673 static chain_str_type *new_chain_str(concptr str)
3675 chain_str_type *chain;
3676 size_t len = strlen(str);
3677 chain = (chain_str_type *)ralloc(sizeof(chain_str_type) + len * sizeof(char));
3678 strcpy(chain->s, str);
3684 static void kill_yank_chain(text_body_type *tb)
3686 chain_str_type *chain = tb->yank;
3688 tb->yank_eol = TRUE;
3692 chain_str_type *next = chain->next;
3693 size_t len = strlen(chain->s);
3695 rnfree(chain, sizeof(chain_str_type) + len * sizeof(char));
3702 static void add_str_to_yank(text_body_type *tb, concptr str)
3704 tb->yank_eol = FALSE;
3705 if (NULL == tb->yank)
3707 tb->yank = new_chain_str(str);
3711 chain_str_type *chain;
3718 chain->next = new_chain_str(str);
3723 chain = chain->next;
3729 * Do work for the copy editor-command
3731 static void copy_text_to_yank(text_body_type *tb)
3733 int len = strlen(tb->lines_list[tb->cy]);
3734 if (tb->cx > len) tb->cx = len;
3743 kill_yank_chain(tb);
3744 if (tb->my != tb->cy)
3746 int by1 = MIN(tb->my, tb->cy);
3747 int by2 = MAX(tb->my, tb->cy);
3749 for (int y = by1; y <= by2; y++)
3751 add_str_to_yank(tb, tb->lines_list[y]);
3754 add_str_to_yank(tb, "");
3756 tb->dirty_flags |= DIRTY_ALL;
3760 char buf[MAX_LINELEN];
3761 int bx1 = MIN(tb->mx, tb->cx);
3762 int bx2 = MAX(tb->mx, tb->cx);
3763 if (bx2 > len) bx2 = len;
3765 if (bx1 == 0 && bx2 == len)
3767 add_str_to_yank(tb, tb->lines_list[tb->cy]);
3768 add_str_to_yank(tb, "");
3772 int end = bx2 - bx1;
3773 for (int i = 0; i < bx2 - bx1; i++)
3775 buf[i] = tb->lines_list[tb->cy][bx1 + i];
3779 add_str_to_yank(tb, buf);
3783 tb->dirty_flags |= DIRTY_ALL;
3790 static void draw_text_editor(player_type *player_ptr, text_body_type *tb)
3793 int by1 = 0, by2 = 0;
3795 Term_get_size(&tb->wid, &tb->hgt);
3798 * Top line (-1), description line (-3), separator (-1)
3801 tb->hgt -= 2 + DESCRIPT_HGT;
3804 /* Don't let cursor at second byte of kanji */
3805 for (i = 0; tb->lines_list[tb->cy][i]; i++)
3806 if (iskanji(tb->lines_list[tb->cy][i]))
3812 * Move to a correct position in the
3815 if (i & 1) tb->cx--;
3821 if (tb->cy < tb->upper || tb->upper + tb->hgt <= tb->cy)
3822 tb->upper = tb->cy - (tb->hgt) / 2;
3825 if ((tb->cx < tb->left + 10 && tb->left > 0) || tb->left + tb->wid - 5 <= tb->cx)
3826 tb->left = tb->cx - (tb->wid) * 2 / 3;
3830 if (tb->old_wid != tb->wid || tb->old_hgt != tb->hgt)
3831 tb->dirty_flags |= DIRTY_SCREEN;
3832 else if (tb->old_upper != tb->upper || tb->old_left != tb->left)
3833 tb->dirty_flags |= DIRTY_ALL;
3835 if (tb->dirty_flags & DIRTY_SCREEN)
3837 tb->dirty_flags |= (DIRTY_ALL | DIRTY_MODE);
3841 if (tb->dirty_flags & DIRTY_MODE)
3843 char buf[MAX_LINELEN];
3844 int sepa_length = tb->wid;
3845 for (i = 0; i < sepa_length; i++)
3848 Term_putstr(0, tb->hgt + 1, sepa_length, TERM_WHITE, buf);
3851 if (tb->dirty_flags & DIRTY_EXPRESSION)
3854 for (int y = 0; tb->lines_list[y]; y++)
3858 concptr s = tb->lines_list[y];
3862 tb->states[y] = state;
3864 if (*s++ != '?') continue;
3865 if (*s++ != ':') continue;
3867 if (streq(s, "$AUTOREGISTER"))
3868 state |= LSTAT_AUTOREGISTER;
3871 ss = (char *)string_make(s);
3874 v = process_pref_file_expr(player_ptr, &ss, &f);
3876 if (streq(v, "0")) state |= LSTAT_BYPASS;
3877 else state &= ~LSTAT_BYPASS;
3879 C_KILL(s_keep, s_len + 1, char);
3881 tb->states[y] = state | LSTAT_EXPRESSION;
3884 tb->dirty_flags |= DIRTY_ALL;
3889 tb->dirty_flags |= DIRTY_ALL;
3891 by1 = MIN(tb->my, tb->cy);
3892 by2 = MAX(tb->my, tb->cy);
3895 for (i = 0; i < tb->hgt; i++)
3901 int y = tb->upper + i;
3903 if (!(tb->dirty_flags & DIRTY_ALL) && (tb->dirty_line != y))
3906 msg = tb->lines_list[y];
3909 for (j = 0; *msg; msg++, j++)
3911 if (j == tb->left) break;
3926 Term_erase(0, i + 1, tb->wid);
3927 if (tb->states[y] & LSTAT_AUTOREGISTER)
3933 if (tb->states[y] & LSTAT_BYPASS) color = TERM_SLATE;
3934 else color = TERM_WHITE;
3937 if (!tb->mark || (y < by1 || by2 < y))
3939 Term_putstr(leftcol, i + 1, tb->wid - 1, color, msg);
3941 else if (by1 != by2)
3943 Term_putstr(leftcol, i + 1, tb->wid - 1, TERM_YELLOW, msg);
3947 int x0 = leftcol + tb->left;
3948 int len = strlen(tb->lines_list[tb->cy]);
3949 int bx1 = MIN(tb->mx, tb->cx);
3950 int bx2 = MAX(tb->mx, tb->cx);
3952 if (bx2 > len) bx2 = len;
3954 Term_gotoxy(leftcol, i + 1);
3955 if (x0 < bx1) Term_addstr(bx1 - x0, color, msg);
3956 if (x0 < bx2) Term_addstr(bx2 - bx1, TERM_YELLOW, msg + (bx1 - x0));
3957 Term_addstr(-1, color, msg + (bx2 - x0));
3961 for (; i < tb->hgt; i++)
3963 Term_erase(0, i + 1, tb->wid);
3966 bool is_dirty_diary = (tb->dirty_flags & (DIRTY_ALL | DIRTY_NOT_FOUND | DIRTY_NO_SEARCH)) != 0;
3967 bool is_updated = tb->old_cy != tb->cy || is_dirty_diary || tb->dirty_line == tb->cy;
3968 if (is_updated) return;
3970 autopick_type an_entry, *entry = &an_entry;
3971 concptr str1 = NULL, str2 = NULL;
3972 for (i = 0; i < DESCRIPT_HGT; i++)
3974 Term_erase(0, tb->hgt + 2 + i, tb->wid);
3977 if (tb->dirty_flags & DIRTY_NOT_FOUND)
3979 str1 = format(_("パターンが見つかりません: %s", "Pattern not found: %s"), tb->search_str);
3981 else if (tb->dirty_flags & DIRTY_SKIP_INACTIVE)
3983 str1 = format(_("無効状態の行をスキップしました。(%sを検索中)",
3984 "Some inactive lines are skipped. (Searching %s)"), tb->search_str);
3986 else if (tb->dirty_flags & DIRTY_INACTIVE)
3988 str1 = format(_("無効状態の行だけが見付かりました。(%sを検索中)",
3989 "Found only an inactive line. (Searching %s)"), tb->search_str);
3991 else if (tb->dirty_flags & DIRTY_NO_SEARCH)
3993 str1 = _("検索するパターンがありません(^S で検索)。", "No pattern to search. (Press ^S to search.)");
3995 else if (tb->lines_list[tb->cy][0] == '#')
3997 str1 = _("この行はコメントです。", "This line is a comment.");
3999 else if (tb->lines_list[tb->cy][0] && tb->lines_list[tb->cy][1] == ':')
4001 switch (tb->lines_list[tb->cy][0])
4004 str1 = _("この行は条件分岐式です。", "This line is a Conditional Expression.");
4007 str1 = _("この行はマクロの実行内容を定義します。", "This line defines a Macro action.");
4010 str1 = _("この行はマクロのトリガー・キーを定義します。", "This line defines a Macro trigger key.");
4013 str1 = _("この行はキー配置を定義します。", "This line defines a Keymap.");
4017 switch (tb->lines_list[tb->cy][0])
4020 if (tb->states[tb->cy] & LSTAT_BYPASS)
4022 str2 = _("現在の式の値は「偽(=0)」です。", "The expression is 'False'(=0) currently.");
4026 str2 = _("現在の式の値は「真(=1)」です。", "The expression is 'True'(=1) currently.");
4031 if (tb->states[tb->cy] & LSTAT_AUTOREGISTER)
4033 str2 = _("この行は後で削除されます。", "This line will be delete later.");
4036 else if (tb->states[tb->cy] & LSTAT_BYPASS)
4038 str2 = _("この行は現在は無効な状態です。", "This line is bypassed currently.");
4043 else if (autopick_new_entry(entry, tb->lines_list[tb->cy], FALSE))
4045 char buf[MAX_LINELEN];
4046 char temp[MAX_LINELEN];
4049 describe_autopick(buf, entry);
4051 if (tb->states[tb->cy] & LSTAT_AUTOREGISTER)
4053 strcat(buf, _("この行は後で削除されます。", " This line will be delete later."));
4056 if (tb->states[tb->cy] & LSTAT_BYPASS)
4058 strcat(buf, _("この行は現在は無効な状態です。", " This line is bypassed currently."));
4061 roff_to_buf(buf, 81, temp, sizeof(temp));
4063 for (i = 0; i < 3; i++)
4069 prt(t, tb->hgt + 1 + 1 + i, 0);
4073 autopick_free_entry(entry);
4076 if (str1) prt(str1, tb->hgt + 1 + 1, 0);
4077 if (str2) prt(str2, tb->hgt + 1 + 2, 0);
4082 * Kill segment of a line
4084 static void kill_line_segment(text_body_type *tb, int y, int x0, int x1, bool whole)
4086 concptr s = tb->lines_list[y];
4087 if (whole && x0 == 0 && s[x1] == '\0' && tb->lines_list[y + 1])
4089 string_free(tb->lines_list[y]);
4092 for (i = y; tb->lines_list[i + 1]; i++)
4093 tb->lines_list[i] = tb->lines_list[i + 1];
4094 tb->lines_list[i] = NULL;
4096 tb->dirty_flags |= DIRTY_EXPRESSION;
4101 if (x0 == x1) return;
4103 char buf[MAX_LINELEN];
4105 for (int x = 0; x < x0; x++)
4108 for (int x = x1; s[x]; x++)
4112 string_free(tb->lines_list[y]);
4113 tb->lines_list[y] = string_make(buf);
4114 check_expression_line(tb, y);
4120 * Get a trigger key and insert ASCII string for the trigger
4122 static bool insert_macro_line(text_body_type *tb)
4141 ascii_to_text(tmp, buf);
4142 if (!tmp[0]) return FALSE;
4145 insert_return_code(tb);
4146 string_free(tb->lines_list[tb->cy]);
4147 tb->lines_list[tb->cy] = string_make(format("P:%s", tmp));
4149 i = macro_find_exact(buf);
4156 ascii_to_text(tmp, macro__act[i]);
4159 insert_return_code(tb);
4160 string_free(tb->lines_list[tb->cy]);
4161 tb->lines_list[tb->cy] = string_make(format("A:%s", tmp));
4168 * Get a command key and insert ASCII string for the key
4170 static bool insert_keymap_line(text_body_type *tb)
4173 if (rogue_like_commands)
4175 mode = KEYMAP_MODE_ROGUE;
4179 mode = KEYMAP_MODE_ORIG;
4189 ascii_to_text(tmp, buf);
4190 if (!tmp[0]) return FALSE;
4193 insert_return_code(tb);
4194 string_free(tb->lines_list[tb->cy]);
4195 tb->lines_list[tb->cy] = string_make(format("C:%d:%s", mode, tmp));
4197 concptr act = keymap_act[mode][(byte)(buf[0])];
4200 ascii_to_text(tmp, act);
4203 insert_return_code(tb);
4204 string_free(tb->lines_list[tb->cy]);
4205 tb->lines_list[tb->cy] = string_make(format("A:%s", tmp));
4212 * Execute a single editor command
4214 static bool do_editor_command(player_type *player_ptr, text_body_type *tb, int com_id)
4221 if (!get_check(_("全ての変更を破棄してから終了します。よろしいですか? ",
4222 "Discard all changes and quit. Are you sure? "))) break;
4225 return QUIT_WITHOUT_SAVE;
4228 return QUIT_AND_SAVE;
4231 if (!get_check(_("全ての変更を破棄して元の状態に戻します。よろしいですか? ",
4232 "Discard all changes and revert to original file. Are you sure? "))) break;
4234 free_text_lines(tb->lines_list);
4235 tb->lines_list = read_pickpref_text_lines(player_ptr, &tb->filename_mode);
4236 tb->dirty_flags |= DIRTY_ALL | DIRTY_MODE | DIRTY_EXPRESSION;
4237 tb->cx = tb->cy = 0;
4240 tb->changed = FALSE;
4244 (void)show_file(player_ptr, TRUE, _("jeditor.txt", "editor.txt"), NULL, 0, 0);
4245 tb->dirty_flags |= DIRTY_SCREEN;
4253 tb->dirty_flags |= DIRTY_ALL;
4256 insert_return_code(tb);
4260 tb->dirty_flags |= DIRTY_ALL;
4272 len = strlen(tb->lines_list[tb->cy]);
4273 if (len < tb->cx) tb->cx = len;
4275 for (i = 0; tb->lines_list[tb->cy][i]; i++)
4277 if (iskanji(tb->lines_list[tb->cy][i]))
4289 else if (tb->cy > 0)
4292 tb->cx = strlen(tb->lines_list[tb->cy]);
4298 if (!tb->lines_list[tb->cy + 1])
4300 if (!add_empty_line(tb)) break;
4307 if (tb->cy > 0) tb->cy--;
4313 if (iskanji(tb->lines_list[tb->cy][tb->cx])) tb->cx++;
4316 int len = strlen(tb->lines_list[tb->cy]);
4320 if (!tb->lines_list[tb->cy + 1])
4322 if (!add_empty_line(tb)) break;
4336 tb->cx = strlen(tb->lines_list[tb->cy]);
4340 while (0 < tb->cy && tb->upper <= tb->cy)
4342 while (0 < tb->upper && tb->cy + 1 < tb->upper + tb->hgt)
4347 while (tb->cy < tb->upper + tb->hgt)
4349 if (!tb->lines_list[tb->cy + 1])
4351 if (!add_empty_line(tb)) break;
4367 if (!tb->lines_list[tb->cy + 1])
4369 if (!add_empty_line(tb)) break;
4380 copy_text_to_yank(tb);
4381 if (tb->my == tb->cy)
4383 int bx1 = MIN(tb->mx, tb->cx);
4384 int bx2 = MAX(tb->mx, tb->cx);
4385 int len = strlen(tb->lines_list[tb->cy]);
4386 if (bx2 > len) bx2 = len;
4388 kill_line_segment(tb, tb->cy, bx1, bx2, TRUE);
4393 int by1 = MIN(tb->my, tb->cy);
4394 int by2 = MAX(tb->my, tb->cy);
4396 for (int y = by2; y >= by1; y--)
4398 int len = strlen(tb->lines_list[y]);
4400 kill_line_segment(tb, y, 0, len, TRUE);
4408 tb->dirty_flags |= DIRTY_ALL;
4413 copy_text_to_yank(tb);
4416 * Move cursor position to the end of the selection
4418 * Pressing ^C ^V correctly duplicates the selection.
4420 if (tb->my != tb->cy)
4422 tb->cy = MAX(tb->cy, tb->my);
4423 if (!tb->lines_list[tb->cy + 1])
4425 if (!add_empty_line(tb)) break;
4432 tb->cx = MAX(tb->cx, tb->mx);
4433 if (!tb->lines_list[tb->cy][tb->cx])
4435 if (!tb->lines_list[tb->cy + 1])
4437 if (!add_empty_line(tb)) break;
4448 chain_str_type *chain = tb->yank;
4449 int len = strlen(tb->lines_list[tb->cy]);
4451 if (tb->cx > len) tb->cx = len;
4456 tb->dirty_flags |= DIRTY_ALL;
4461 concptr yank_str = chain->s;
4462 char buf[MAX_LINELEN];
4464 char rest[MAX_LINELEN], *rest_ptr = rest;
4465 for (i = 0; i < tb->cx; i++)
4466 buf[i] = tb->lines_list[tb->cy][i];
4468 strcpy(rest, &(tb->lines_list[tb->cy][i]));
4469 while (*yank_str && i < MAX_LINELEN - 1)
4471 buf[i++] = *yank_str++;
4475 chain = chain->next;
4476 if (chain || tb->yank_eol)
4478 insert_return_code(tb);
4479 string_free(tb->lines_list[tb->cy]);
4480 tb->lines_list[tb->cy] = string_make(buf);
4487 tb->cx = strlen(buf);
4488 while (*rest_ptr && i < MAX_LINELEN - 1)
4490 buf[i++] = *rest_ptr++;
4494 string_free(tb->lines_list[tb->cy]);
4495 tb->lines_list[tb->cy] = string_make(buf);
4499 tb->dirty_flags |= DIRTY_ALL;
4500 tb->dirty_flags |= DIRTY_EXPRESSION;
4509 tb->dirty_flags |= DIRTY_ALL;
4513 tb->mark = MARK_MARK;
4514 if (com_id == tb->old_com_id)
4522 tb->dirty_flags |= DIRTY_ALL;
4526 int len = strlen(tb->lines_list[tb->cy]);
4530 if (tb->cx > len) tb->mx = len;
4535 int len = strlen(tb->lines_list[tb->cy]);
4536 if (tb->cx > len) tb->cx = len;
4541 tb->dirty_flags |= DIRTY_ALL;
4544 if (tb->old_com_id != com_id)
4546 kill_yank_chain(tb);
4552 add_str_to_yank(tb, &(tb->lines_list[tb->cy][tb->cx]));
4553 kill_line_segment(tb, tb->cy, tb->cx, len, FALSE);
4554 tb->dirty_line = tb->cy;
4558 if (tb->yank_eol) add_str_to_yank(tb, "");
4560 tb->yank_eol = TRUE;
4561 do_editor_command(player_ptr, tb, EC_DELETE_CHAR);
4564 case EC_DELETE_CHAR:
4569 tb->dirty_flags |= DIRTY_ALL;
4573 if (iskanji(tb->lines_list[tb->cy][tb->cx])) tb->cx++;
4576 int len = strlen(tb->lines_list[tb->cy]);
4579 do_editor_command(player_ptr, tb, EC_BACKSPACE);
4583 if (tb->lines_list[tb->cy + 1])
4594 do_editor_command(player_ptr, tb, EC_BACKSPACE);
4600 char buf[MAX_LINELEN];
4604 tb->dirty_flags |= DIRTY_ALL;
4607 len = strlen(tb->lines_list[tb->cy]);
4608 if (len < tb->cx) tb->cx = len;
4612 if (tb->cy == 0) break;
4613 tb->cx = strlen(tb->lines_list[tb->cy - 1]);
4614 strcpy(buf, tb->lines_list[tb->cy - 1]);
4615 strcat(buf, tb->lines_list[tb->cy]);
4616 string_free(tb->lines_list[tb->cy - 1]);
4617 string_free(tb->lines_list[tb->cy]);
4618 tb->lines_list[tb->cy - 1] = string_make(buf);
4620 for (i = tb->cy; tb->lines_list[i + 1]; i++)
4621 tb->lines_list[i] = tb->lines_list[i + 1];
4623 tb->lines_list[i] = NULL;
4625 tb->dirty_flags |= DIRTY_ALL;
4626 tb->dirty_flags |= DIRTY_EXPRESSION;
4631 for (i = j = k = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
4635 if (iskanji(tb->lines_list[tb->cy][i]))
4636 buf[j++] = tb->lines_list[tb->cy][i++];
4638 buf[j++] = tb->lines_list[tb->cy][i];
4647 for (; tb->lines_list[tb->cy][i]; i++)
4649 buf[j++] = tb->lines_list[tb->cy][i];
4653 string_free(tb->lines_list[tb->cy]);
4654 tb->lines_list[tb->cy] = string_make(buf);
4655 tb->dirty_line = tb->cy;
4656 check_expression_line(tb, tb->cy);
4663 tb->dirty_flags |= DIRTY_SCREEN;
4664 search_dir = get_string_for_search(player_ptr, &tb->search_o_ptr, &tb->search_str);
4666 if (!search_dir) break;
4668 if (search_dir == 1) do_editor_command(player_ptr, tb, EC_SEARCH_FORW);
4669 else do_editor_command(player_ptr, tb, EC_SEARCH_BACK);
4672 case EC_SEARCH_FORW:
4673 if (tb->search_o_ptr)
4675 search_for_object(player_ptr, tb, tb->search_o_ptr, TRUE);
4679 if (tb->search_str && tb->search_str[0])
4681 search_for_string(tb, tb->search_str, TRUE);
4685 tb->dirty_flags |= DIRTY_NO_SEARCH;
4688 case EC_SEARCH_BACK:
4689 if (tb->search_o_ptr)
4691 search_for_object(player_ptr, tb, tb->search_o_ptr, FALSE);
4695 if (tb->search_str && tb->search_str[0])
4697 search_for_string(tb, tb->search_str, FALSE);
4701 tb->dirty_flags |= DIRTY_NO_SEARCH;
4705 tb->dirty_flags |= DIRTY_SCREEN;
4707 if (!get_object_for_search(player_ptr, &tb->search_o_ptr, &tb->search_str)) break;
4709 do_editor_command(player_ptr, tb, EC_SEARCH_FORW);
4712 case EC_SEARCH_DESTROYED:
4713 if (!get_destroyed_object_for_search(player_ptr, &tb->search_o_ptr, &tb->search_str))
4715 tb->dirty_flags |= DIRTY_NO_SEARCH;
4719 do_editor_command(player_ptr, tb, EC_SEARCH_FORW);
4722 case EC_INSERT_OBJECT:
4724 autopick_type an_entry, *entry = &an_entry;
4725 if (!entry_from_choosed_object(player_ptr, entry))
4727 tb->dirty_flags |= DIRTY_SCREEN;
4732 insert_return_code(tb);
4733 string_free(tb->lines_list[tb->cy]);
4734 tb->lines_list[tb->cy] = autopick_line_from_entry_kill(entry);
4735 tb->dirty_flags |= DIRTY_SCREEN;
4738 case EC_INSERT_DESTROYED:
4739 if (!tb->last_destroyed) break;
4742 insert_return_code(tb);
4743 string_free(tb->lines_list[tb->cy]);
4744 tb->lines_list[tb->cy] = string_make(tb->last_destroyed);
4745 tb->dirty_flags |= DIRTY_ALL;
4749 case EC_INSERT_BLOCK:
4751 char expression[80];
4752 sprintf(expression, "?:[AND [EQU $RACE %s] [EQU $CLASS %s] [GEQ $LEVEL %02d]]",
4754 rp_ptr->E_title, cp_ptr->E_title,
4756 rp_ptr->title, cp_ptr->title,
4760 insert_return_code(tb);
4761 string_free(tb->lines_list[tb->cy]);
4762 tb->lines_list[tb->cy] = string_make(expression);
4764 insert_return_code(tb);
4765 string_free(tb->lines_list[tb->cy]);
4766 tb->lines_list[tb->cy] = string_make("?:1");
4767 tb->dirty_flags |= DIRTY_ALL;
4772 case EC_INSERT_MACRO:
4773 draw_text_editor(player_ptr, tb);
4774 Term_erase(0, tb->cy - tb->upper + 1, tb->wid);
4775 Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW, _("P:<トリガーキー>: ", "P:<Trigger key>: "));
4776 if (!insert_macro_line(tb)) break;
4779 tb->dirty_flags |= DIRTY_ALL;
4783 case EC_INSERT_KEYMAP:
4784 draw_text_editor(player_ptr, tb);
4785 Term_erase(0, tb->cy - tb->upper + 1, tb->wid);
4786 Term_putstr(0, tb->cy - tb->upper + 1, tb->wid - 1, TERM_YELLOW,
4787 format(_("C:%d:<コマンドキー>: ", "C:%d:<Keypress>: "), (rogue_like_commands ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG)));
4789 if (!insert_keymap_line(tb)) break;
4792 tb->dirty_flags |= DIRTY_ALL;
4796 case EC_CL_AUTOPICK: toggle_command_letter(tb, DO_AUTOPICK); break;
4797 case EC_CL_DESTROY: toggle_command_letter(tb, DO_AUTODESTROY); break;
4798 case EC_CL_LEAVE: toggle_command_letter(tb, DONT_AUTOPICK); break;
4799 case EC_CL_QUERY: toggle_command_letter(tb, DO_QUERY_AUTOPICK); break;
4800 case EC_CL_NO_DISP: toggle_command_letter(tb, DO_DISPLAY); break;
4802 case EC_IK_UNAWARE: toggle_keyword(tb, FLG_UNAWARE); break;
4803 case EC_IK_UNIDENTIFIED: toggle_keyword(tb, FLG_UNIDENTIFIED); break;
4804 case EC_IK_IDENTIFIED: toggle_keyword(tb, FLG_IDENTIFIED); break;
4805 case EC_IK_STAR_IDENTIFIED: toggle_keyword(tb, FLG_STAR_IDENTIFIED); break;
4806 case EC_KK_WEAPONS: toggle_keyword(tb, FLG_WEAPONS); break;
4807 case EC_KK_FAVORITE_WEAPONS: toggle_keyword(tb, FLG_FAVORITE_WEAPONS); break;
4808 case EC_KK_ARMORS: toggle_keyword(tb, FLG_ARMORS); break;
4809 case EC_KK_MISSILES: toggle_keyword(tb, FLG_MISSILES); break;
4810 case EC_KK_DEVICES: toggle_keyword(tb, FLG_DEVICES); break;
4811 case EC_KK_LIGHTS: toggle_keyword(tb, FLG_LIGHTS); break;
4812 case EC_KK_JUNKS: toggle_keyword(tb, FLG_JUNKS); break;
4813 case EC_KK_CORPSES: toggle_keyword(tb, FLG_CORPSES); break;
4814 case EC_KK_SPELLBOOKS: toggle_keyword(tb, FLG_SPELLBOOKS); break;
4815 case EC_KK_SHIELDS: toggle_keyword(tb, FLG_SHIELDS); break;
4816 case EC_KK_BOWS: toggle_keyword(tb, FLG_BOWS); break;
4817 case EC_KK_RINGS: toggle_keyword(tb, FLG_RINGS); break;
4818 case EC_KK_AMULETS: toggle_keyword(tb, FLG_AMULETS); break;
4819 case EC_KK_SUITS: toggle_keyword(tb, FLG_SUITS); break;
4820 case EC_KK_CLOAKS: toggle_keyword(tb, FLG_CLOAKS); break;
4821 case EC_KK_HELMS: toggle_keyword(tb, FLG_HELMS); break;
4822 case EC_KK_GLOVES: toggle_keyword(tb, FLG_GLOVES); break;
4823 case EC_KK_BOOTS: toggle_keyword(tb, FLG_BOOTS); break;
4824 case EC_OK_COLLECTING: toggle_keyword(tb, FLG_COLLECTING); break;
4825 case EC_OK_BOOSTED: toggle_keyword(tb, FLG_BOOSTED); break;
4826 case EC_OK_MORE_DICE: toggle_keyword(tb, FLG_MORE_DICE); break;
4827 case EC_OK_MORE_BONUS: toggle_keyword(tb, FLG_MORE_BONUS); break;
4828 case EC_OK_WORTHLESS: toggle_keyword(tb, FLG_WORTHLESS); break;
4829 case EC_OK_ARTIFACT: toggle_keyword(tb, FLG_ARTIFACT); break;
4830 case EC_OK_EGO: toggle_keyword(tb, FLG_EGO); break;
4831 case EC_OK_GOOD: toggle_keyword(tb, FLG_GOOD); break;
4832 case EC_OK_NAMELESS: toggle_keyword(tb, FLG_NAMELESS); break;
4833 case EC_OK_AVERAGE: toggle_keyword(tb, FLG_AVERAGE); break;
4834 case EC_OK_RARE: toggle_keyword(tb, FLG_RARE); break;
4835 case EC_OK_COMMON: toggle_keyword(tb, FLG_COMMON); break;
4836 case EC_OK_WANTED: toggle_keyword(tb, FLG_WANTED); break;
4837 case EC_OK_UNIQUE: toggle_keyword(tb, FLG_UNIQUE); break;
4838 case EC_OK_HUMAN: toggle_keyword(tb, FLG_HUMAN); break;
4839 case EC_OK_UNREADABLE:
4840 toggle_keyword(tb, FLG_UNREADABLE);
4841 add_keyword(tb, FLG_SPELLBOOKS);
4844 toggle_keyword(tb, FLG_REALM1);
4845 add_keyword(tb, FLG_SPELLBOOKS);
4848 toggle_keyword(tb, FLG_REALM2);
4849 add_keyword(tb, FLG_SPELLBOOKS);
4852 toggle_keyword(tb, FLG_FIRST);
4853 add_keyword(tb, FLG_SPELLBOOKS);
4856 toggle_keyword(tb, FLG_SECOND);
4857 add_keyword(tb, FLG_SPELLBOOKS);
4860 toggle_keyword(tb, FLG_THIRD);
4861 add_keyword(tb, FLG_SPELLBOOKS);
4864 toggle_keyword(tb, FLG_FOURTH);
4865 add_keyword(tb, FLG_SPELLBOOKS);
4869 tb->old_com_id = com_id;
4875 * Insert single letter at cursor position.
4877 static void insert_single_letter(text_body_type *tb, int key)
4880 char buf[MAX_LINELEN];
4882 for (i = j = 0; tb->lines_list[tb->cy][i] && i < tb->cx; i++)
4884 buf[j++] = tb->lines_list[tb->cy][i];
4894 if (j + 2 < MAX_LINELEN)
4896 buf[j++] = (char)key;
4897 buf[j++] = (char)next;
4906 if (j + 1 < MAX_LINELEN)
4907 buf[j++] = (char)key;
4911 for (; tb->lines_list[tb->cy][i] && j + 1 < MAX_LINELEN; i++)
4912 buf[j++] = tb->lines_list[tb->cy][i];
4915 string_free(tb->lines_list[tb->cy]);
4916 tb->lines_list[tb->cy] = string_make(buf);
4917 len = strlen(tb->lines_list[tb->cy]);
4918 if (len < tb->cx) tb->cx = len;
4920 tb->dirty_line = tb->cy;
4921 check_expression_line(tb, tb->cy);
4927 * Check special key code and get a movement command id
4929 static int analyze_move_key(text_body_type *tb, int skey)
4932 if (!(skey & SKEY_MASK)) return 0;
4934 switch (skey & ~SKEY_MOD_MASK)
4936 case SKEY_DOWN: com_id = EC_DOWN; break;
4937 case SKEY_LEFT: com_id = EC_LEFT; break;
4938 case SKEY_RIGHT: com_id = EC_RIGHT; break;
4939 case SKEY_UP: com_id = EC_UP; break;
4940 case SKEY_PGUP: com_id = EC_PGUP; break;
4941 case SKEY_PGDOWN: com_id = EC_PGDOWN; break;
4942 case SKEY_TOP: com_id = EC_TOP; break;
4943 case SKEY_BOTTOM: com_id = EC_BOTTOM; break;
4948 if (!(skey & SKEY_MOD_SHIFT))
4951 * Un-shifted cursor keys cancells
4952 * selection created by shift+cursor.
4954 if (tb->mark & MARK_BY_SHIFT)
4957 tb->dirty_flags |= DIRTY_ALL;
4963 if (tb->mark) return com_id;
4965 int len = strlen(tb->lines_list[tb->cy]);
4966 tb->mark = MARK_MARK | MARK_BY_SHIFT;
4969 if (tb->cx > len) tb->mx = len;
4971 if (com_id == EC_UP || com_id == EC_DOWN)
4973 tb->dirty_flags |= DIRTY_ALL;
4977 tb->dirty_line = tb->cy;
4984 * In-game editor of Object Auto-picker/Destoryer
4985 * @param player_ptr プレーヤーへの参照ポインタ
4987 void do_cmd_edit_autopick(player_type *player_ptr)
4989 static int cx_save = 0;
4990 static int cy_save = 0;
4991 text_body_type text_body, *tb = &text_body;
4992 autopick_type an_entry, *entry = &an_entry;
4993 char buf[MAX_LINELEN];
4996 static s32b old_autosave_turn = 0L;
4999 tb->changed = FALSE;
5002 tb->upper = tb->left = 0;
5004 tb->mx = tb->my = 0;
5005 tb->old_cy = tb->old_upper = tb->old_left = -1;
5006 tb->old_wid = tb->old_hgt = -1;
5010 tb->search_o_ptr = NULL;
5011 tb->search_str = NULL;
5012 tb->last_destroyed = NULL;
5013 tb->dirty_flags = DIRTY_ALL | DIRTY_MODE | DIRTY_EXPRESSION;
5014 tb->dirty_line = -1;
5015 tb->filename_mode = PT_DEFAULT;
5017 if (current_world_ptr->game_turn < old_autosave_turn)
5019 while (old_autosave_turn > current_world_ptr->game_turn) old_autosave_turn -= TURNS_PER_TICK * TOWN_DAWN;
5022 if (current_world_ptr->game_turn > old_autosave_turn + 100L)
5024 do_cmd_save_game(player_ptr, TRUE);
5025 old_autosave_turn = current_world_ptr->game_turn;
5030 if (autopick_last_destroyed_object.k_idx)
5032 autopick_entry_from_object(player_ptr, entry, &autopick_last_destroyed_object);
5033 tb->last_destroyed = autopick_line_from_entry_kill(entry);
5036 tb->lines_list = read_pickpref_text_lines(player_ptr, &tb->filename_mode);
5037 for (i = 0; i < tb->cy; i++)
5039 if (!tb->lines_list[i])
5041 tb->cy = tb->cx = 0;
5050 draw_text_editor(player_ptr, tb);
5051 prt(_("(^Q:終了 ^W:セーブして終了, ESC:メニュー, その他:入力)",
5052 "(^Q:Quit, ^W:Save&Quit, ESC:Menu, Other:Input text)"), 0, 0);
5055 prt(format("(%d,%d)", tb->cx, tb->cy), 0, 60);
5059 prt(format("(%d,%d)-(%d,%d)", tb->mx, tb->my, tb->cx, tb->cy), 0, 60);
5062 Term_gotoxy(tb->cx - tb->left, tb->cy - tb->upper + 1);
5063 tb->dirty_flags = 0;
5064 tb->dirty_line = -1;
5065 tb->old_cy = tb->cy;
5066 tb->old_upper = tb->upper;
5067 tb->old_left = tb->left;
5068 tb->old_wid = tb->wid;
5069 tb->old_hgt = tb->hgt;
5071 key = inkey_special(TRUE);
5073 if (key & SKEY_MASK)
5075 com_id = analyze_move_key(tb, key);
5077 else if (key == ESCAPE)
5079 com_id = do_command_menu(0, 0);
5080 tb->dirty_flags |= DIRTY_SCREEN;
5082 else if (!iscntrl((unsigned char)key))
5087 tb->dirty_flags |= DIRTY_ALL;
5090 insert_single_letter(tb, key);
5095 com_id = get_com_id((char)key);
5098 if (com_id) quit = do_editor_command(player_ptr, tb, com_id);
5102 strcpy(buf, pickpref_filename(player_ptr, tb->filename_mode));
5104 if (quit == QUIT_AND_SAVE)
5105 write_text_lines(buf, tb->lines_list);
5107 free_text_lines(tb->lines_list);
5108 string_free(tb->search_str);
5109 string_free(tb->last_destroyed);
5110 kill_yank_chain(tb);
5112 process_autopick_file(player_ptr, buf);
5113 current_world_ptr->start_time = (u32b)time(NULL);