3 * @brief プレイヤーのインターフェイスに関するコマンドの実装 / Interface commands
7 * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
8 * This software may be copied and distributed for educational, research,
9 * and not for profit purposes provided that this copyright and statement
10 * are included in all such copies. Other copyrights may also apply.
14 * A set of functions to maintain automatic dumps of various kinds.
16 * remove_auto_dump(orig_file, mark)
17 * Remove the old automatic dump of type "mark".
18 * auto_dump_printf(fmt, ...)
19 * Dump a formatted string using fprintf().
20 * open_auto_dump(buf, mark)
21 * Open a file, remove old dump, and add new header.
22 * close_auto_dump(void)
23 * Add a footer, and close the file.
24 * The dump commands of original Angband simply add new lines to
25 * existing files; these files will become bigger and bigger unless
26 * an user deletes some or all of these files by hand at some
28 * These three functions automatically delete old dumped lines
29 * before adding new ones. Since there are various kinds of automatic
30 * dumps in a single file, we add a header and a footer with a type
31 * name for every automatic dump, and kill old lines only when the
32 * lines have the correct type of header and footer.
33 * We need to be quite paranoid about correctness; the user might
34 * (mistakenly) edit the file by hand, and see all their work come
35 * to nothing on the next auto dump otherwise. The current code only
36 * detects changes by noting inconsistencies between the actual number
37 * of lines and the number written in the footer. Note that this will
38 * not catch single-line edits.
45 #include "player-status.h"
54 * Mark strings for auto dump
56 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
57 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
60 * Variables for auto dump
62 static FILE *auto_dump_stream;
63 static concptr auto_dump_mark;
64 static int auto_dump_line_num;
68 * @brief prf出力内容を消去する /
69 * Remove old lines automatically generated before.
70 * @param orig_file 消去を行うファイル名
72 static void remove_auto_dump(concptr orig_file)
74 FILE *tmp_fff, *orig_fff;
78 bool between_mark = FALSE;
81 long header_location = 0;
82 char header_mark_str[80];
83 char footer_mark_str[80];
86 /* Prepare a header/footer mark string */
87 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
88 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
90 mark_len = strlen(footer_mark_str);
92 /* Open an old dump file in read-only mode */
93 orig_fff = my_fopen(orig_file, "r");
95 /* If original file does not exist, nothing to do */
96 if (!orig_fff) return;
98 /* Open a new (temporary) file */
99 tmp_fff = my_fopen_temp(tmp_file, 1024);
103 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
108 /* Loop for every line */
112 if (my_fgets(orig_fff, buf, sizeof(buf)))
114 /* Read error: Assume End of File */
117 * Was looking for the footer, but not found.
119 * Since automatic dump might be edited by hand,
120 * it's dangerous to kill these lines.
121 * Seek back to the next line of the (pseudo) header,
126 fseek(orig_fff, header_location, SEEK_SET);
127 between_mark = FALSE;
131 /* Success -- End the loop */
138 /* We are looking for the header mark of automatic dump */
141 /* Is this line a header? */
142 if (!strcmp(buf, header_mark_str))
144 /* Memorise seek point of this line */
145 header_location = ftell(orig_fff);
147 /* Initialize counter for number of lines */
150 /* Look for the footer from now */
153 /* There are some changes */
160 /* Copy orginally lines */
161 fprintf(tmp_fff, "%s\n", buf);
165 /* We are looking for the footer mark of automatic dump */
168 /* Is this line a footer? */
169 if (!strncmp(buf, footer_mark_str, mark_len))
174 * Compare the number of lines
176 * If there is an inconsistency between
177 * actual number of lines and the
178 * number here, the automatic dump
179 * might be edited by hand. So it's
180 * dangerous to kill these lines.
181 * Seek back to the next line of the
182 * (pseudo) header, and read again.
184 if (!sscanf(buf + mark_len, " (%d)", &tmp)
187 fseek(orig_fff, header_location, SEEK_SET);
190 /* Look for another header */
191 between_mark = FALSE;
197 /* Ignore old line, and count number of lines */
207 /* If there are some changes, overwrite the original file with new one */
210 /* Copy contents of temporary file */
212 tmp_fff = my_fopen(tmp_file, "r");
213 orig_fff = my_fopen(orig_file, "w");
215 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
216 fprintf(orig_fff, "%s\n", buf);
222 /* Kill the temporary file */
230 * @brief prfファイルのフォーマットに従った内容を出力する /
231 * Dump a formatted line, using "vstrnfmt()".
234 static void auto_dump_printf(concptr fmt, ...)
241 /* Begin the Varargs Stuff */
244 /* Format the args, save the length */
245 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
247 /* End the Varargs Stuff */
250 /* Count number of lines */
251 for (p = buf; *p; p++)
253 if (*p == '\n') auto_dump_line_num++;
257 fprintf(auto_dump_stream, "%s", buf);
262 * @brief prfファイルをファイルオープンする /
263 * Open file to append auto dump.
265 * @param mark 出力するヘッダマーク
266 * @return ファイルポインタを取得できたらTRUEを返す
268 static bool open_auto_dump(concptr buf, concptr mark)
271 char header_mark_str[80];
273 /* Save the mark string */
274 auto_dump_mark = mark;
276 /* Prepare a header mark string */
277 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
279 /* Remove old macro dumps */
280 remove_auto_dump(buf);
282 /* Append to the file */
283 auto_dump_stream = my_fopen(buf, "a");
286 if (!auto_dump_stream) {
287 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
295 fprintf(auto_dump_stream, "%s\n", header_mark_str);
297 /* Initialize counter */
298 auto_dump_line_num = 0;
300 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
301 "# *Warning!* The lines below are an automatic dump.\n"));
302 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
303 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
309 * @brief prfファイルをファイルクローズする /
310 * Append foot part and close auto dump.
313 static void close_auto_dump(void)
315 char footer_mark_str[80];
317 /* Prepare a footer mark string */
318 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
320 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
321 "# *Warning!* The lines below are an automatic dump.\n"));
322 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
323 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
325 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
328 my_fclose(auto_dump_stream);
337 * @brief Return suffix of ordinal number
339 * @return pointer of suffix string.
341 concptr get_ordinal_number_suffix(int num)
343 num = ABS(num) % 100;
347 return (num == 11) ? "th" : "st";
349 return (num == 12) ? "th" : "nd";
351 return (num == 13) ? "th" : "rd";
360 * @brief 日記にメッセージを追加する /
361 * Take note to the diary.
362 * @param type 日記内容のID
363 * @param num 日記内容のIDに応じた数値
364 * @param note 日記内容のIDに応じた文字列参照ポインタ
367 errr do_cmd_write_nikki(int type, int num, concptr note)
371 GAME_TEXT file_name[MAX_NLEN];
373 concptr note_level = "";
374 bool do_level = TRUE;
375 char note_level_buf[40];
378 static bool disable_nikki = FALSE;
380 extract_day_hour_min(&day, &hour, &min);
382 if (disable_nikki) return(-1);
384 if (type == NIKKI_FIX_QUEST_C ||
385 type == NIKKI_FIX_QUEST_F ||
386 type == NIKKI_RAND_QUEST_C ||
387 type == NIKKI_RAND_QUEST_F ||
388 type == NIKKI_TO_QUEST)
392 old_quest = p_ptr->inside_quest;
393 p_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
395 /* Get the quest text */
396 init_flags = INIT_NAME_ONLY;
398 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
400 /* Reset the old quest number */
401 p_ptr->inside_quest = old_quest;
404 /* different filne name to avoid mixing */
405 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
407 /* Build the filename */
408 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
410 /* File type is "TEXT" */
411 FILE_TYPE(FILE_TYPE_TEXT);
413 fff = my_fopen(buf, "a");
418 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporally."), buf);
424 q_idx = quest_number(dun_level);
428 if (p_ptr->inside_arena)
429 note_level = _("アリーナ:", "Arane:");
431 note_level = _("地上:", "Surface:");
432 else if (q_idx && (is_fixed_quest_idx(q_idx)
433 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
434 note_level = _("クエスト:", "Quest:");
438 sprintf(note_level_buf, "%d階(%s):", (int)dun_level, d_name+d_info[dungeon_type].name);
440 sprintf(note_level_buf, "%s L%d:", d_name+d_info[dungeon_type].name, (int)dun_level);
442 note_level = note_level_buf;
450 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
451 else fputs(_("*****日目\n", "Day *****\n"), fff);
459 fprintf(fff, "%s\n",note);
463 fprintf(fff, " %2d:%02d %20s %s\n",hour, min, note_level, note);
468 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
471 case NIKKI_ART_SCROLL:
473 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
478 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
481 case NIKKI_FIX_QUEST_C:
483 if (quest[num].flags & QUEST_FLAG_SILENT) break;
484 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
485 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
488 case NIKKI_FIX_QUEST_F:
490 if (quest[num].flags & QUEST_FLAG_SILENT) break;
491 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
492 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
495 case NIKKI_RAND_QUEST_C:
497 GAME_TEXT name[MAX_NLEN];
498 strcpy(name, r_name+r_info[quest[num].r_idx].name);
499 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
500 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
503 case NIKKI_RAND_QUEST_F:
505 GAME_TEXT name[MAX_NLEN];
506 strcpy(name, r_name+r_info[quest[num].r_idx].name);
507 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
508 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
511 case NIKKI_MAXDEAPTH:
513 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
514 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
515 _(d_name+d_info[dungeon_type].name, num),
516 _(num, d_name+d_info[dungeon_type].name));
521 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
522 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
523 _(d_name + d_info[num].name, (int)max_dlv[num]),
524 _((int)max_dlv[num], d_name + d_info[num].name));
530 if (q_idx && (is_fixed_quest_idx(q_idx)
531 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
533 to = _("地上", "the surface");
537 if (!(dun_level+num)) to = _("地上", "the surface");
538 else to = format(_("%d階", "level %d"), dun_level+num);
540 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
546 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
547 hour, min, note_level, _(d_name+d_info[dungeon_type].name, (int)max_dlv[dungeon_type]),
548 _((int)max_dlv[dungeon_type], d_name+d_info[dungeon_type].name));
550 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
555 if (quest[num].flags & QUEST_FLAG_SILENT) break;
556 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
557 hour, min, note_level, quest[num].name);
562 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
563 hour, min, note_level);
568 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
573 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
581 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
582 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
585 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
586 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
588 if (num == MAX_ARENA_MONS)
590 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
591 " won all fight to become a Chanpion.\n"));
598 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
605 to = _("地上", "the surface");
607 to = format(_("%d階(%s)", "level %d of %s"), dun_level, d_name+d_info[dungeon_type].name);
609 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
610 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
617 to = _("地上", "the surface");
619 to = format(_("%d階(%s)", "level %d of %s"), dun_level, d_name+d_info[dungeon_type].name);
621 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
622 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
627 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
630 case NIKKI_GAMESTART:
632 time_t ct = time((time_t*)0);
636 fprintf(fff, "%s %s",note, ctime(&ct));
639 fprintf(fff, " %2d:%02d %20s %s %s",hour, min, note_level, note, ctime(&ct));
642 case NIKKI_NAMED_PET:
644 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
647 case RECORD_NAMED_PET_NAME:
648 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
650 case RECORD_NAMED_PET_UNNAME:
651 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
653 case RECORD_NAMED_PET_DISMISS:
654 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
656 case RECORD_NAMED_PET_DEATH:
657 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
659 case RECORD_NAMED_PET_MOVED:
660 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
662 case RECORD_NAMED_PET_LOST_SIGHT:
663 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
665 case RECORD_NAMED_PET_DESTROY:
666 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was made disappeared by *destruction*.\n"), note);
668 case RECORD_NAMED_PET_EARTHQUAKE:
669 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
671 case RECORD_NAMED_PET_GENOCIDE:
672 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was made disappeared by genocide.\n"), note);
674 case RECORD_NAMED_PET_WIZ_ZAP:
675 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
677 case RECORD_NAMED_PET_TELE_LEVEL:
678 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was made disappeared by teleport level.\n"), note);
680 case RECORD_NAMED_PET_BLAST:
681 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
683 case RECORD_NAMED_PET_HEAL_LEPER:
684 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
686 case RECORD_NAMED_PET_COMPACT:
687 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was made disappeared by compacting monsters.\n"), note);
689 case RECORD_NAMED_PET_LOSE_PARENT:
690 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because there does not exist summoner.\n"), note);
701 case NIKKI_WIZARD_LOG:
702 fprintf(fff, "%s\n", note);
711 if (do_level) write_level = FALSE;
717 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
720 * @brief 日記のタイトル表記と内容出力 /
723 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
725 static void do_cmd_disp_nikki(void)
727 char nikki_title[256];
728 GAME_TEXT file_name[MAX_NLEN];
733 static const char subtitle[][30] = {"最強の肉体を求めて",
764 static const char subtitle[][51] ={"Quest of The World's Toughest Body",
765 "Attack is the best form of defence.",
767 "An unexpected windfall",
768 "A drowning man will catch at a straw",
769 "Don't count your chickens before they are hatched.",
770 "It is no use crying over spilt milk.",
771 "Seeing is believing.",
772 "Strike the iron while it is hot.",
773 "I don't care what follows.",
774 "To dig a well to put out a house on fire.",
775 "Tomorrow is another day.",
776 "Easy come, easy go.",
777 "The more haste, the less speed.",
778 "Where there is life, there is hope.",
779 "There is no royal road to *WINNER*.",
780 "Danger past, God forgotten.",
781 "The best thing to do now is to run away.",
782 "Life is but an empty dream.",
783 "Dead men tell no tales.",
784 "A book that remains shut is but a block.",
785 "Misfortunes never come singly.",
786 "A little knowledge is a dangerous thing.",
787 "History repeats itself.",
788 "*WINNER* was not built in a day.",
789 "Ignorance is bliss.",
790 "To lose is to win?",
791 "No medicine can cure folly.",
792 "All good things come to an end.",
793 "M$ Empire strikes back.",
794 "To see is to believe",
796 "Quest of The World's Greatest Brain"};
798 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
800 /* Build the filename */
801 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
803 if (p_ptr->pclass == CLASS_WARRIOR || p_ptr->pclass == CLASS_MONK || p_ptr->pclass == CLASS_SAMURAI || p_ptr->pclass == CLASS_BERSERKER)
804 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)]);
805 else if (IS_WIZARD_CLASS())
806 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)+1]);
807 else strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-2)+1]);
810 sprintf(nikki_title, "「%s%s%sの伝説 -%s-」", ap_ptr->title, ap_ptr->no ? "の" : "", p_ptr->name, tmp);
812 sprintf(nikki_title, "Legend of %s %s '%s'", ap_ptr->title, p_ptr->name, tmp);
815 /* Display the file contents */
816 show_file(FALSE, buf, nikki_title, -1, 0);
820 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
823 static void do_cmd_bunshou(void)
826 char bunshou[80] = "\0";
828 if (get_string(_("内容: ", "diary note: "), tmp, 79))
830 strcpy(bunshou, tmp);
832 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, bunshou);
837 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
840 static void do_cmd_last_get(void)
845 if (record_o_name[0] == '\0') return;
847 sprintf(buf,_("%sの入手を記録します。", "Do you really want to record getting %s? "),record_o_name);
848 if (!get_check(buf)) return;
852 sprintf(buf,_("%sを手に入れた。", "descover %s."), record_o_name);
853 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, buf);
858 * @brief ファイル中の全日記記録を消去する /
861 static void do_cmd_erase_nikki(void)
863 GAME_TEXT file_name[MAX_NLEN];
867 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
868 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
870 /* Build the filename */
871 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
873 /* Remove the file */
876 fff = my_fopen(buf, "w");
879 msg_format(_("記録を消去しました。", "deleted record."));
881 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
890 void do_cmd_nikki(void)
894 /* File type is "TEXT" */
895 FILE_TYPE(FILE_TYPE_TEXT);
898 /* Interact until done */
903 /* Ask for a choice */
904 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
906 /* Give some choices */
907 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
908 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
909 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record item you last get/identify"), 6, 5);
910 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
912 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
915 prt(_("コマンド:", "Command: "), 18, 0);
920 if (i == ESCAPE) break;
934 do_cmd_erase_nikki();
938 prepare_movie_hooks();
940 default: /* Unknown option */
950 * @brief 画面を再描画するコマンドのメインルーチン
951 * Hack -- redraw the screen
955 * This command performs various low level updates, clears all the "extra"
956 * windows, does a total redraw of the main window, and requests all of the
957 * interesting updates and redraws that I can think of.
959 * This command is also used to "instantiate" the results of the user
960 * selecting various things, such as graphics mode, so it must call
961 * the "TERM_XTRA_REACT" hook before redrawing the windows.
964 void do_cmd_redraw(void)
970 /* Hack -- react to changes */
971 Term_xtra(TERM_XTRA_REACT, 0);
973 /* Combine and Reorder the pack (later) */
974 p_ptr->update |= (PU_COMBINE | PU_REORDER);
975 p_ptr->update |= (PU_TORCH);
976 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
977 p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
978 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
979 p_ptr->update |= (PU_MONSTERS);
981 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
983 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
984 p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
990 if (p_ptr->prace == RACE_ANDROID) calc_android_exp();
993 /* Redraw every window */
994 for (j = 0; j < 8; j++)
997 if (!angband_term[j]) continue;
1000 Term_activate(angband_term[j]);
1009 * @brief 名前を変更するコマンドのメインルーチン
1010 * Hack -- change name
1013 void do_cmd_change_name(void)
1028 /* Display the player */
1029 display_player(mode);
1034 display_player(mode);
1039 Term_putstr(2, 23, -1, TERM_WHITE,
1040 "['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]");
1042 Term_putstr(2, 23, -1, TERM_WHITE,
1043 "['c' to change name, 'f' to file, 'h' to change mode, or ESC]");
1051 if (c == ESCAPE) break;
1058 /* Process the player name */
1059 process_player_name(FALSE);
1065 sprintf(tmp, "%s.txt", player_base);
1066 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1068 if (tmp[0] && (tmp[0] != ' '))
1070 file_character(tmp);
1088 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1095 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1096 * Recall the most recent message
1099 void do_cmd_message_one(void)
1101 /* Recall one message */
1102 prt(format("> %s", message_str(0)), 0, 0);
1107 * @brief メッセージのログを表示するコマンドのメインルーチン
1108 * Recall the most recent message
1112 * Show previous messages to the user -BEN-
1114 * The screen format uses line 0 and 23 for headers and prompts,
1115 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1117 * This command shows you which commands you are viewing, and allows
1118 * you to "search" for strings in the recall.
1120 * Note that messages may be longer than 80 characters, but they are
1121 * displayed using "infinite" length, with a special sub-command to
1122 * "slide" the virtual display to the left or right.
1124 * Attempt to only hilite the matching portions of the string.
1127 void do_cmd_messages(int num_now)
1131 char shower_str[81];
1132 char finder_str[81];
1134 concptr shower = NULL;
1138 Term_get_size(&wid, &hgt);
1140 /* Number of message lines in a screen */
1141 num_lines = hgt - 4;
1144 strcpy(finder_str, "");
1147 strcpy(shower_str, "");
1149 /* Total messages */
1152 /* Start on first message */
1157 /* Process requests until done */
1163 /* Dump up to 20 lines of messages */
1164 for (j = 0; (j < num_lines) && (i + j < n); j++)
1166 concptr msg = message_str(i+j);
1168 /* Dump the messages, bottom to top */
1169 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1171 /* Hilite "shower" */
1172 if (shower && shower[0])
1176 /* Display matches */
1177 while ((str = my_strstr(str, shower)) != NULL)
1179 int len = strlen(shower);
1181 /* Display the match */
1182 Term_putstr(str-msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1190 /* Erase remaining lines */
1191 for (; j < num_lines; j++)
1193 Term_erase(0, num_lines + 1 - j, 255);
1196 /* Display header */
1198 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1199 i, i + j - 1, n), 0, 0);
1201 /* Display prompt (not very informative) */
1202 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1203 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1205 skey = inkey_special(TRUE);
1207 /* Exit on Escape */
1208 if (skey == ESCAPE) break;
1210 /* Hack -- Save the old index */
1215 /* Hack -- handle show */
1218 prt(_("強調: ", "Show: "), hgt - 1, 0);
1220 /* Get a "shower" string, or continue */
1221 strcpy(back_str, shower_str);
1222 if (askfor(shower_str, 80))
1225 shower = shower_str[0] ? shower_str : NULL;
1227 else strcpy(shower_str, back_str);
1231 /* Hack -- handle find */
1238 prt(_("検索: ", "Find: "), hgt - 1, 0);
1240 /* Get a "finder" string, or continue */
1241 strcpy(back_str, finder_str);
1242 if (!askfor(finder_str, 80))
1244 strcpy(finder_str, back_str);
1247 else if (!finder_str[0])
1249 shower = NULL; /* Stop showing */
1254 shower = finder_str;
1257 for (z = i + 1; z < n; z++)
1259 concptr msg = message_str(z);
1262 if (my_strstr(msg, finder_str))
1273 /* Recall 1 older message */
1275 /* Go to the oldest line */
1279 /* Recall 1 newer message */
1281 /* Go to the newest line */
1285 /* Recall 1 older message */
1290 /* Go older if legal */
1291 i = MIN(i + 1, n - num_lines);
1294 /* Recall 10 older messages */
1296 /* Go older if legal */
1297 i = MIN(i + 10, n - num_lines);
1300 /* Recall 20 older messages */
1305 /* Go older if legal */
1306 i = MIN(i + num_lines, n - num_lines);
1309 /* Recall 20 newer messages */
1313 /* Go newer (if able) */
1314 i = MAX(0, i - num_lines);
1317 /* Recall 10 newer messages */
1319 /* Go newer (if able) */
1323 /* Recall 1 newer messages */
1326 /* Go newer (if able) */
1331 /* Hack -- Error of some kind */
1339 * @brief チートオプションを変更するコマンドのメインルーチン
1340 * Interact with some options for cheating
1341 * @param info 表示メッセージ
1344 static void do_cmd_options_cheat(concptr info)
1347 int i, k = 0, n = CHEAT_MAX;
1351 /* Interact with the player */
1357 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, ESC で決定 )", "%s (RET to advance, y/n to set, ESC to accept) "), info);
1362 /* 詐欺オプションをうっかりいじってしまう人がいるようなので注意 */
1363 prt(" << 注意 >>", 11, 0);
1364 prt(" 詐欺オプションを一度でも設定すると、スコア記録が残らなくなります!", 12, 0);
1365 prt(" 後に解除してもダメですので、勝利者を目指す方はここのオプションはい", 13, 0);
1366 prt(" じらないようにして下さい。", 14, 0);
1368 /* Display the options */
1369 for (i = 0; i < n; i++)
1371 byte a = TERM_WHITE;
1373 /* Color current option */
1374 if (i == k) a = TERM_L_BLUE;
1376 /* Display the option text */
1377 sprintf(buf, "%-48s: %s (%s)",
1378 cheat_info[i].o_desc,
1379 (*cheat_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1380 cheat_info[i].o_text);
1381 c_prt(a, buf, i + 2, 0);
1384 /* Hilite current option */
1385 move_cursor(k + 2, 50);
1391 * HACK - Try to translate the key into a direction
1392 * to allow using the roguelike keys for navigation.
1394 dir = get_keymap_dir(ch);
1395 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1409 k = (n + k - 1) % n;
1427 do_cmd_write_nikki(NIKKI_BUNSHOU, 0,
1428 _("詐欺オプションをONにして、スコアを残せなくなった。", "give up sending score to use cheating options."));
1429 p_ptr->noscore |= (cheat_info[k].o_set * 256 + cheat_info[k].o_bit);
1430 (*cheat_info[k].o_var) = TRUE;
1439 (*cheat_info[k].o_var) = FALSE;
1446 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), cheat_info[k].o_text);
1447 /* Peruse the help file */
1448 (void)show_file(TRUE, buf, NULL, 0, 0);
1465 * @brief セーブ頻度ターンの次の値を返す
1466 * @param current 現在のセーブ頻度ターン値
1467 * @return 次のセーブ頻度ターン値
1469 static s16b toggle_frequency(s16b current)
1474 case 50: return 100;
1475 case 100: return 250;
1476 case 250: return 500;
1477 case 500: return 1000;
1478 case 1000: return 2500;
1479 case 2500: return 5000;
1480 case 5000: return 10000;
1481 case 10000: return 25000;
1488 * @brief 自動セーブオプションを変更するコマンドのメインルーチン
1489 * @param info 表示メッセージ
1492 static void do_cmd_options_autosave(concptr info)
1495 int i, k = 0, n = 2;
1500 /* Interact with the player */
1504 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ",
1505 "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info);
1509 /* Display the options */
1510 for (i = 0; i < n; i++)
1512 byte a = TERM_WHITE;
1514 /* Color current option */
1515 if (i == k) a = TERM_L_BLUE;
1517 /* Display the option text */
1518 sprintf(buf, "%-48s: %s (%s)",
1519 autosave_info[i].o_desc,
1520 (*autosave_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1521 autosave_info[i].o_text);
1522 c_prt(a, buf, i + 2, 0);
1524 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1526 /* Hilite current option */
1527 move_cursor(k + 2, 50);
1543 k = (n + k - 1) % n;
1561 (*autosave_info[k].o_var) = TRUE;
1570 (*autosave_info[k].o_var) = FALSE;
1578 autosave_freq = toggle_frequency(autosave_freq);
1579 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1585 (void)show_file(TRUE, _("joption.txt#Autosave", "option.txt#Autosave"), NULL, 0, 0);
1601 * @brief 標準オプションを変更するコマンドのサブルーチン /
1602 * Interact with some options
1603 * @param page オプションページ番号
1604 * @param info 表示メッセージ
1607 void do_cmd_options_aux(int page, concptr info)
1610 int i, k = 0, n = 0, l;
1613 bool browse_only = (page == OPT_PAGE_BIRTH) && character_generated &&
1614 (!p_ptr->wizard || !allow_debug_opts);
1617 /* Lookup the options */
1618 for (i = 0; i < 24; i++) opt[i] = 0;
1620 /* Scan the options */
1621 for (i = 0; option_info[i].o_desc; i++)
1623 /* Notice options on this "page" */
1624 if (option_info[i].o_page == page) opt[n++] = i;
1628 /* Interact with the player */
1634 sprintf(buf, _("%s (リターン:次, %sESC:終了, ?:ヘルプ) ", "%s (RET:next, %s, ?:help) "),
1635 info, browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept"));
1638 /* HACK -- description for easy-auto-destroy options */
1639 if (page == OPT_PAGE_AUTODESTROY)
1640 c_prt(TERM_YELLOW, _("以下のオプションは、簡易自動破壊を使用するときのみ有効",
1641 "Following options will protect items from easy auto-destroyer."), 6, _(6, 3));
1643 /* Display the options */
1644 for (i = 0; i < n; i++)
1646 byte a = TERM_WHITE;
1648 /* Color current option */
1649 if (i == k) a = TERM_L_BLUE;
1651 /* Display the option text */
1652 sprintf(buf, "%-48s: %s (%.19s)",
1653 option_info[opt[i]].o_desc,
1654 (*option_info[opt[i]].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1655 option_info[opt[i]].o_text);
1656 if ((page == OPT_PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
1657 else c_prt(a, buf, i + 2, 0);
1660 if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) l = 3;
1663 /* Hilite current option */
1664 move_cursor(k + 2 + l, 50);
1670 * HACK - Try to translate the key into a direction
1671 * to allow using the roguelike keys for navigation.
1673 dir = get_keymap_dir(ch);
1674 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1688 k = (n + k - 1) % n;
1705 if (browse_only) break;
1706 (*option_info[opt[k]].o_var) = TRUE;
1715 if (browse_only) break;
1716 (*option_info[opt[k]].o_var) = FALSE;
1724 if (!browse_only) (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
1730 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), option_info[opt[k]].o_text);
1731 /* Peruse the help file */
1732 (void)show_file(TRUE, buf, NULL, 0, 0);
1749 * @brief ウィンドウオプションを変更するコマンドのメインルーチン /
1750 * Modify the "window" options
1753 static void do_cmd_options_win(void)
1763 /* Memorize old flags */
1764 for (j = 0; j < 8; j++)
1766 /* Acquire current flags */
1767 old_flag[j] = window_flag[j];
1776 prt(_("ウィンドウ・フラグ (<方向>で移動, tでチェンジ, y/n でセット, ESC)", "Window Flags (<dir>, t, y, n, ESC) "), 0, 0);
1778 /* Display the windows */
1779 for (j = 0; j < 8; j++)
1781 byte a = TERM_WHITE;
1783 concptr s = angband_term_name[j];
1786 if (j == x) a = TERM_L_BLUE;
1788 /* Window name, staggered, centered */
1789 Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
1792 /* Display the options */
1793 for (i = 0; i < 16; i++)
1795 byte a = TERM_WHITE;
1797 concptr str = window_flag_desc[i];
1800 if (i == y) a = TERM_L_BLUE;
1803 if (!str) str = _("(未使用)", "(Unused option)");
1806 Term_putstr(0, i + 5, -1, a, str);
1808 /* Display the windows */
1809 for (j = 0; j < 8; j++)
1815 if ((i == y) && (j == x)) a = TERM_L_BLUE;
1818 if (window_flag[j] & (1L << i)) c = 'X';
1821 Term_putch(35 + j * 5, i + 5, a, c);
1826 Term_gotoxy(35 + x * 5, y + 5);
1844 for (j = 0; j < 8; j++)
1846 window_flag[j] &= ~(1L << y);
1850 for (i = 0; i < 16; i++)
1852 window_flag[x] &= ~(1L << i);
1865 window_flag[x] |= (1L << y);
1873 window_flag[x] &= ~(1L << y);
1879 (void)show_file(TRUE, _("joption.txt#Window", "option.txt#Window"), NULL, 0, 0);
1887 d = get_keymap_dir(ch);
1889 x = (x + ddx[d] + 8) % 8;
1890 y = (y + ddy[d] + 16) % 16;
1897 /* Notice changes */
1898 for (j = 0; j < 8; j++)
1903 if (!angband_term[j]) continue;
1905 /* Ignore non-changes */
1906 if (window_flag[j] == old_flag[j]) continue;
1909 Term_activate(angband_term[j]);
1926 option_fields[OPT_NUM] =
1929 { '1', " キー入力 オプション", 3 },
1930 { '2', " マップ画面 オプション", 4 },
1931 { '3', " テキスト表示 オプション", 5 },
1932 { '4', " ゲームプレイ オプション", 6 },
1933 { '5', " 行動中止関係 オプション", 7 },
1934 { '6', " 簡易自動破壊 オプション", 8 },
1935 { 'r', " プレイ記録 オプション", 9 },
1937 { 'p', "自動拾いエディタ", 11 },
1938 { 'd', " 基本ウェイト量 ", 12 },
1939 { 'h', "低ヒットポイント", 13 },
1940 { 'm', " 低魔力色閾値 ", 14 },
1941 { 'a', " 自動セーブ オプション", 15 },
1942 { 'w', "ウインドウフラグ", 16 },
1944 { 'b', " 初期 オプション (参照のみ)", 18 },
1945 { 'c', " 詐欺 オプション", 19 },
1947 { '1', "Input Options", 3 },
1948 { '2', "Map Screen Options", 4 },
1949 { '3', "Text Display Options", 5 },
1950 { '4', "Game-Play Options", 6 },
1951 { '5', "Disturbance Options", 7 },
1952 { '6', "Easy Auto-Destroyer Options", 8 },
1953 { 'r', "Play record Options", 9 },
1955 { 'p', "Auto-picker/destroyer editor", 11 },
1956 { 'd', "Base Delay Factor", 12 },
1957 { 'h', "Hitpoint Warning", 13 },
1958 { 'm', "Mana Color Threshold", 14 },
1959 { 'a', "Autosave Options", 15 },
1960 { 'w', "Window Flags", 16 },
1962 { 'b', "Birth Options (Browse Only)", 18 },
1963 { 'c', "Cheat Options", 19 },
1969 * @brief 標準オプションを変更するコマンドのメインルーチン /
1970 * Set or unset various options.
1974 * The user must use the "Ctrl-R" command to "adapt" to changes
1975 * in any options which control "visual" aspects of the game.
1978 void do_cmd_options(void)
1990 /* Does not list cheat option when cheat option is off */
1991 if (!p_ptr->noscore && !allow_debug_opts) n--;
1994 /* Why are we here */
1995 prt(_("[ オプションの設定 ]", "TinyAngband options"), 1, 0);
1999 /* Give some choices */
2000 for (i = 0; i < n; i++)
2002 byte a = TERM_WHITE;
2003 if (i == y) a = TERM_L_BLUE;
2004 Term_putstr(5, option_fields[i].row, -1, a,
2005 format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name));
2008 prt(_("<方向>で移動, Enterで決定, ESCでキャンセル, ?でヘルプ: ", "Move to <dir>, Select to Enter, Cancel to ESC, ? to help: "), 21, 0);
2011 skey = inkey_special(TRUE);
2012 if (!(skey & SKEY_MASK)) k = (char)skey;
2016 if (k == ESCAPE) break;
2018 if (my_strchr("\n\r ", k))
2020 k = option_fields[y].key;
2024 for (i = 0; i < n; i++)
2026 if (tolower(k) == option_fields[i].key) break;
2029 /* Command is found */
2032 /* Hack -- browse help */
2033 if (k == '?') break;
2037 if (skey == SKEY_UP) d = 8;
2038 if (skey == SKEY_DOWN) d = 2;
2039 y = (y + ddy[d] + n) % n;
2044 if (k == ESCAPE) break;
2051 /* Process the general options */
2052 do_cmd_options_aux(OPT_PAGE_INPUT, _("キー入力オプション", "Input Options"));
2058 /* Process the general options */
2059 do_cmd_options_aux(OPT_PAGE_MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
2066 do_cmd_options_aux(OPT_PAGE_TEXT, _("テキスト表示オプション", "Text Display Options"));
2073 do_cmd_options_aux(OPT_PAGE_GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
2080 do_cmd_options_aux(OPT_PAGE_DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
2087 do_cmd_options_aux(OPT_PAGE_AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
2091 /* Play-record Options */
2096 do_cmd_options_aux(OPT_PAGE_PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
2105 do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ?
2106 _("初期オプション(参照のみ)", "Birth Options(browse only)") :
2107 _("初期オプション((*)はスコアに影響)", "Birth Options((*)s effect score)"));
2111 /* Cheating Options */
2114 if (!p_ptr->noscore && !allow_debug_opts)
2116 /* Cheat options are not permitted */
2122 do_cmd_options_cheat(_("詐欺師は決して勝利できない!", "Cheaters never win"));
2129 do_cmd_options_autosave(_("自動セーブ", "Autosave"));
2138 do_cmd_options_win();
2139 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL |
2140 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
2141 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
2142 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON |
2147 /* Auto-picker/destroyer editor */
2151 do_cmd_edit_autopick();
2155 /* Hack -- Delay Speed */
2161 prt(_("コマンド: 基本ウェイト量", "Command: Base Delay Factor"), 19, 0);
2163 /* Get a new value */
2166 int msec = delay_factor * delay_factor * delay_factor;
2167 prt(format(_("現在のウェイト: %d (%dミリ秒)", "Current base delay factor: %d (%d msec)"), delay_factor, msec), 22, 0);
2168 prt(_("ウェイト (0-9) ESCで決定: ", "Delay Factor (0-9 or ESC to accept): "), 20, 0);
2170 if (k == ESCAPE) break;
2173 (void)show_file(TRUE, _("joption.txt#BaseDelay", "option.txt#BaseDelay"), NULL, 0, 0);
2176 else if (isdigit(k)) delay_factor = D2I(k);
2183 /* Hack -- hitpoint warning factor */
2189 prt(_("コマンド: 低ヒットポイント警告", "Command: Hitpoint Warning"), 19, 0);
2191 /* Get a new value */
2194 prt(format(_("現在の低ヒットポイント警告: %d0%%", "Current hitpoint warning: %d0%%"), hitpoint_warn), 22, 0);
2195 prt(_("低ヒットポイント警告 (0-9) ESCで決定: ", "Hitpoint Warning (0-9 or ESC to accept): "), 20, 0);
2197 if (k == ESCAPE) break;
2200 (void)show_file(TRUE, _("joption.txt#Hitpoint", "option.txt#Hitpoint"), NULL, 0, 0);
2203 else if (isdigit(k)) hitpoint_warn = D2I(k);
2210 /* Hack -- mana color factor */
2216 prt(_("コマンド: 低魔力色閾値", "Command: Mana Color Threshold"), 19, 0);
2218 /* Get a new value */
2221 prt(format(_("現在の低魔力色閾値: %d0%%", "Current mana color threshold: %d0%%"), mana_warn), 22, 0);
2222 prt(_("低魔力閾値 (0-9) ESCで決定: ", "Mana color Threshold (0-9 or ESC to accept): "), 20, 0);
2224 if (k == ESCAPE) break;
2227 (void)show_file(TRUE, _("joption.txt#Manapoint", "option.txt#Manapoint"), NULL, 0, 0);
2230 else if (isdigit(k)) mana_warn = D2I(k);
2238 (void)show_file(TRUE, _("joption.txt", "option.txt"), NULL, 0, 0);
2242 /* Unknown option */
2255 /* Hack - Redraw equippy chars */
2256 p_ptr->redraw |= (PR_EQUIPPY);
2262 * @brief prefファイルを選択して処理する /
2263 * Ask for a "user pref line" and process it
2266 * Allow absolute file names?
2268 void do_cmd_pref(void)
2275 /* Ask for a "user pref command" */
2276 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
2278 /* Process that pref command */
2279 (void)process_pref_file_command(buf);
2283 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
2286 void do_cmd_reload_autopick(void)
2288 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
2289 /* Load the file with messages */
2290 autopick_load_pref(TRUE);
2296 * @brief マクロ情報をprefファイルに保存する /
2297 * @param fname ファイル名
2300 static errr macro_dump(concptr fname)
2302 static concptr mark = "Macro Dump";
2308 /* Build the filename */
2309 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2311 /* File type is "TEXT" */
2312 FILE_TYPE(FILE_TYPE_TEXT);
2314 /* Append to the file */
2315 if (!open_auto_dump(buf, mark)) return (-1);
2318 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
2321 for (i = 0; i < macro__num; i++)
2323 /* Extract the action */
2324 ascii_to_text(buf, macro__act[i]);
2326 /* Dump the macro */
2327 auto_dump_printf("A:%s\n", buf);
2329 /* Extract the action */
2330 ascii_to_text(buf, macro__pat[i]);
2332 /* Dump normal macros */
2333 auto_dump_printf("P:%s\n", buf);
2336 auto_dump_printf("\n");
2348 * @brief マクロのトリガーキーを取得する /
2349 * Hack -- ask for a "trigger" (see below)
2350 * @param buf キー表記を保管するバッファ
2354 * Note the complex use of the "inkey()" function from "util.c".
2356 * Note that both "flush()" calls are extremely important.
2359 static void do_cmd_macro_aux(char *buf)
2367 /* Do not process macros */
2373 /* Read the pattern */
2379 /* Do not process macros */
2382 /* Do not wait for keys */
2385 /* Attempt to read a key */
2394 /* Convert the trigger */
2395 ascii_to_text(tmp, buf);
2397 /* Hack -- display the trigger */
2398 Term_addstr(-1, TERM_WHITE, tmp);
2404 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
2405 * Hack -- ask for a keymap "trigger" (see below)
2406 * @param buf キー表記を取得するバッファ
2410 * Note that both "flush()" calls are extremely important. This may
2411 * no longer be true, since "util.c" is much simpler now.
2414 static void do_cmd_macro_aux_keymap(char *buf)
2424 /* Convert to ascii */
2425 ascii_to_text(tmp, buf);
2427 /* Hack -- display the trigger */
2428 Term_addstr(-1, TERM_WHITE, tmp);
2435 * @brief キーマップをprefファイルにダンプする /
2436 * Hack -- append all keymaps to the given file
2437 * @param fname ファイルネーム
2441 static errr keymap_dump(concptr fname)
2443 static concptr mark = "Keymap Dump";
2452 if (rogue_like_commands)
2454 mode = KEYMAP_MODE_ROGUE;
2460 mode = KEYMAP_MODE_ORIG;
2464 /* Build the filename */
2465 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2467 /* File type is "TEXT" */
2468 FILE_TYPE(FILE_TYPE_TEXT);
2470 /* Append to the file */
2471 if (!open_auto_dump(buf, mark)) return -1;
2474 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
2477 for (i = 0; i < 256; i++)
2481 /* Loop up the keymap */
2482 act = keymap_act[mode][i];
2484 /* Skip empty keymaps */
2487 /* Encode the key */
2490 ascii_to_text(key, buf);
2492 /* Encode the action */
2493 ascii_to_text(buf, act);
2495 /* Dump the macro */
2496 auto_dump_printf("A:%s\n", buf);
2497 auto_dump_printf("C:%d:%s\n", mode, key);
2509 * @brief マクロを設定するコマンドのメインルーチン /
2510 * Interact with "macros"
2514 * Note that the macro "action" must be defined before the trigger.
2516 * Could use some helpful instructions on this page.
2519 void do_cmd_macros(void)
2531 if (rogue_like_commands)
2533 mode = KEYMAP_MODE_ROGUE;
2539 mode = KEYMAP_MODE_ORIG;
2542 /* File type is "TEXT" */
2543 FILE_TYPE(FILE_TYPE_TEXT);
2548 /* Process requests until done */
2552 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
2554 /* Describe that action */
2555 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
2557 /* Analyze the current action */
2558 ascii_to_text(buf, macro__buf);
2560 /* Display the current action */
2565 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2567 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
2568 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
2569 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
2570 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
2571 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
2572 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
2573 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
2574 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
2575 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
2576 #endif /* ALLOW_MACROS */
2579 prt(_("コマンド: ", "Command: "), 16, 0);
2584 if (i == ESCAPE) break;
2586 /* Load a 'macro' file */
2592 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
2595 prt(_("ファイル: ", "File: "), 18, 0);
2597 /* Default filename */
2598 sprintf(tmp, "%s.prf", player_base);
2600 /* Ask for a file */
2601 if (!askfor(tmp, 80)) continue;
2603 /* Process the given filename */
2604 err = process_pref_file(tmp);
2607 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
2612 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
2616 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
2626 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
2629 prt(_("ファイル: ", "File: "), 18, 0);
2631 /* Default filename */
2632 sprintf(tmp, "%s.prf", player_base);
2634 /* Ask for a file */
2635 if (!askfor(tmp, 80)) continue;
2637 /* Dump the macros */
2638 (void)macro_dump(tmp);
2641 msg_print(_("マクロを追加しました。", "Appended macros."));
2650 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
2654 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2656 /* Get a macro trigger */
2657 do_cmd_macro_aux(buf);
2659 /* Acquire action */
2660 k = macro_find_exact(buf);
2666 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
2672 /* Obtain the action */
2673 strcpy(macro__buf, macro__act[k]);
2675 /* Analyze the current action */
2676 ascii_to_text(buf, macro__buf);
2678 /* Display the current action */
2682 msg_print(_("マクロを確認しました。", "Found a macro."));
2686 /* Create a macro */
2690 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
2693 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2695 /* Get a macro trigger */
2696 do_cmd_macro_aux(buf);
2702 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2703 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2706 prt(_("マクロ行動: ", "Action: "), 20, 0);
2708 /* Convert to text */
2709 ascii_to_text(tmp, macro__buf);
2711 /* Get an encoded action */
2712 if (askfor(tmp, 80))
2714 /* Convert to ascii */
2715 text_to_ascii(macro__buf, tmp);
2717 /* Link the macro */
2718 macro_add(buf, macro__buf);
2721 msg_print(_("マクロを追加しました。", "Added a macro."));
2725 /* Remove a macro */
2729 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
2732 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2734 /* Get a macro trigger */
2735 do_cmd_macro_aux(buf);
2737 /* Link the macro */
2738 macro_add(buf, buf);
2741 msg_print(_("マクロを削除しました。", "Removed a macro."));
2748 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
2751 prt(_("ファイル: ", "File: "), 18, 0);
2753 /* Default filename */
2754 sprintf(tmp, "%s.prf", player_base);
2756 /* Ask for a file */
2757 if (!askfor(tmp, 80)) continue;
2759 /* Dump the macros */
2760 (void)keymap_dump(tmp);
2763 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
2766 /* Query a keymap */
2772 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
2775 prt(_("押すキー: ", "Keypress: "), 18, 0);
2777 /* Get a keymap trigger */
2778 do_cmd_macro_aux_keymap(buf);
2780 /* Look up the keymap */
2781 act = keymap_act[mode][(byte)(buf[0])];
2787 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
2793 /* Obtain the action */
2794 strcpy(macro__buf, act);
2796 /* Analyze the current action */
2797 ascii_to_text(buf, macro__buf);
2799 /* Display the current action */
2803 msg_print(_("キー配置を確認しました。", "Found a keymap."));
2807 /* Create a keymap */
2811 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
2814 prt(_("押すキー: ", "Keypress: "), 18, 0);
2816 /* Get a keymap trigger */
2817 do_cmd_macro_aux_keymap(buf);
2823 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2824 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2827 prt(_("行動: ", "Action: "), 20, 0);
2829 /* Convert to text */
2830 ascii_to_text(tmp, macro__buf);
2832 /* Get an encoded action */
2833 if (askfor(tmp, 80))
2835 /* Convert to ascii */
2836 text_to_ascii(macro__buf, tmp);
2838 /* Free old keymap */
2839 string_free(keymap_act[mode][(byte)(buf[0])]);
2841 /* Make new keymap */
2842 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
2845 msg_print(_("キー配置を追加しました。", "Added a keymap."));
2849 /* Remove a keymap */
2853 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
2856 prt(_("押すキー: ", "Keypress: "), 18, 0);
2858 /* Get a keymap trigger */
2859 do_cmd_macro_aux_keymap(buf);
2861 /* Free old keymap */
2862 string_free(keymap_act[mode][(byte)(buf[0])]);
2864 /* Make new keymap */
2865 keymap_act[mode][(byte)(buf[0])] = NULL;
2868 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
2871 /* Enter a new action */
2875 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
2881 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2882 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2885 prt(_("マクロ行動: ", "Action: "), 20, 0);
2887 /* Hack -- limit the value */
2890 /* Get an encoded action */
2891 if (!askfor(buf, 80)) continue;
2893 /* Extract an action */
2894 text_to_ascii(macro__buf, buf);
2897 #endif /* ALLOW_MACROS */
2910 * @brief キャラクタ色の明暗表現
2912 static concptr lighting_level_str[F_LIT_MAX] =
2927 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
2928 * @param i 指定対象となるキャラクタコード
2929 * @param num 指定されたビジュアルIDを返す参照ポインタ
2930 * @param max ビジュアルIDの最大数
2931 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
2933 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2940 sprintf(str, "%d", *num);
2942 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
2945 tmp = (IDX)strtol(str, NULL, 0);
2946 if (tmp >= 0 && tmp < max)
2949 else if (isupper(i))
2950 *num = (*num + max - 1) % max;
2952 *num = (*num + 1) % max;
2958 * @brief キャラクタの変更メニュー表示
2959 * @param choice_msg 選択メッセージ
2962 static void print_visuals_menu(concptr choice_msg)
2964 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2966 /* Give some choices */
2967 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2969 #ifdef ALLOW_VISUALS
2970 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2971 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2972 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2973 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2974 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2975 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2976 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2977 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2978 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2979 #endif /* ALLOW_VISUALS */
2981 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2984 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2987 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx);
2988 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx);
2989 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
2992 * Interact with "visuals"
2994 void do_cmd_visuals(void)
2999 bool need_redraw = FALSE;
3000 concptr empty_symbol = "<< ? >>";
3002 if (use_bigtile) empty_symbol = "<< ?? >>";
3004 /* File type is "TEXT" */
3005 FILE_TYPE(FILE_TYPE_TEXT);
3008 /* Interact until done */
3013 /* Ask for a choice */
3014 print_visuals_menu(NULL);
3019 if (i == ESCAPE) break;
3023 /* Load a 'pref' file */
3026 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
3029 prt(_("ファイル: ", "File: "), 17, 0);
3031 /* Default filename */
3032 sprintf(tmp, "%s.prf", player_base);
3035 if (!askfor(tmp, 70)) continue;
3037 /* Process the given filename */
3038 (void)process_pref_file(tmp);
3043 #ifdef ALLOW_VISUALS
3045 /* Dump monster attr/chars */
3048 static concptr mark = "Monster attr/chars";
3051 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
3054 prt(_("ファイル: ", "File: "), 17, 0);
3056 /* Default filename */
3057 sprintf(tmp, "%s.prf", player_base);
3059 /* Get a filename */
3060 if (!askfor(tmp, 70)) continue;
3062 /* Build the filename */
3063 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3065 /* Append to the file */
3066 if (!open_auto_dump(buf, mark)) continue;
3069 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
3072 for (i = 0; i < max_r_idx; i++)
3074 monster_race *r_ptr = &r_info[i];
3076 /* Skip non-entries */
3077 if (!r_ptr->name) continue;
3079 /* Dump a comment */
3080 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
3082 /* Dump the monster attr/char info */
3083 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
3084 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
3090 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
3095 /* Dump object attr/chars */
3098 static concptr mark = "Object attr/chars";
3099 KIND_OBJECT_IDX k_idx;
3102 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
3105 prt(_("ファイル: ", "File: "), 17, 0);
3107 /* Default filename */
3108 sprintf(tmp, "%s.prf", player_base);
3110 /* Get a filename */
3111 if (!askfor(tmp, 70)) continue;
3113 /* Build the filename */
3114 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3116 /* Append to the file */
3117 if (!open_auto_dump(buf, mark)) continue;
3120 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
3123 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
3125 GAME_TEXT o_name[MAX_NLEN];
3126 object_kind *k_ptr = &k_info[k_idx];
3128 /* Skip non-entries */
3129 if (!k_ptr->name) continue;
3134 strip_name(o_name, k_idx);
3140 /* Prepare dummy object */
3141 object_prep(&forge, k_idx);
3143 /* Get un-shuffled flavor name */
3144 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3147 /* Dump a comment */
3148 auto_dump_printf("# %s\n", o_name);
3150 /* Dump the object attr/char info */
3151 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
3152 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3158 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
3163 /* Dump feature attr/chars */
3166 static concptr mark = "Feature attr/chars";
3169 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
3172 prt(_("ファイル: ", "File: "), 17, 0);
3174 /* Default filename */
3175 sprintf(tmp, "%s.prf", player_base);
3177 /* Get a filename */
3178 if (!askfor(tmp, 70)) continue;
3180 /* Build the filename */
3181 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3183 /* Append to the file */
3184 if (!open_auto_dump(buf, mark)) continue;
3187 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
3190 for (i = 0; i < max_f_idx; i++)
3192 feature_type *f_ptr = &f_info[i];
3194 /* Skip non-entries */
3195 if (!f_ptr->name) continue;
3197 /* Skip mimiccing features */
3198 if (f_ptr->mimic != i) continue;
3200 /* Dump a comment */
3201 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
3203 /* Dump the feature attr/char info */
3204 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
3205 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
3206 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
3207 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
3213 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
3218 /* Modify monster attr/chars (numeric operation) */
3221 static concptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
3222 static MONRACE_IDX r = 0;
3224 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3226 /* Hack -- query until done */
3229 monster_race *r_ptr = &r_info[r];
3233 TERM_COLOR da = r_ptr->d_attr;
3234 byte dc = r_ptr->d_char;
3235 TERM_COLOR ca = r_ptr->x_attr;
3236 byte cc = r_ptr->x_char;
3238 /* Label the object */
3239 Term_putstr(5, 17, -1, TERM_WHITE,
3240 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
3242 /* Label the Default values */
3243 Term_putstr(10, 19, -1, TERM_WHITE,
3244 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
3246 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3247 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3249 /* Label the Current values */
3250 Term_putstr(10, 20, -1, TERM_WHITE,
3251 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
3253 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3254 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3257 Term_putstr(0, 22, -1, TERM_WHITE,
3258 _("コマンド (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ", "Command (n/N/^N/a/A/^A/c/C/^C/v/V/^V): "));
3263 if (i == ESCAPE) break;
3265 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3266 else if (isupper(i)) c = 'a' + i - 'A';
3276 if (!cmd_visuals_aux(i, &r, max_r_idx))
3282 while (!r_info[r].name);
3286 t = (int)r_ptr->x_attr;
3287 (void)cmd_visuals_aux(i, &t, 256);
3288 r_ptr->x_attr = (byte)t;
3292 t = (int)r_ptr->x_char;
3293 (void)cmd_visuals_aux(i, &t, 256);
3294 r_ptr->x_char = (byte)t;
3298 do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
3300 print_visuals_menu(choice_msg);
3308 /* Modify object attr/chars (numeric operation) */
3311 static concptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
3313 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3315 /* Hack -- query until done */
3318 object_kind *k_ptr = &k_info[k];
3322 TERM_COLOR da = k_ptr->d_attr;
3323 SYMBOL_CODE dc = k_ptr->d_char;
3324 TERM_COLOR ca = k_ptr->x_attr;
3325 SYMBOL_CODE cc = k_ptr->x_char;
3327 /* Label the object */
3328 Term_putstr(5, 17, -1, TERM_WHITE,
3329 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
3330 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
3332 /* Label the Default values */
3333 Term_putstr(10, 19, -1, TERM_WHITE,
3334 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3336 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3337 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3339 /* Label the Current values */
3340 Term_putstr(10, 20, -1, TERM_WHITE,
3341 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
3343 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3344 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3347 Term_putstr(0, 22, -1, TERM_WHITE,
3348 _("コマンド (n/N/^N/a/A/^A/c/C/^C/v/V/^V): ", "Command (n/N/^N/a/A/^A/c/C/^C/v/V/^V): "));
3353 if (i == ESCAPE) break;
3355 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3356 else if (isupper(i)) c = 'a' + i - 'A';
3366 if (!cmd_visuals_aux(i, &k, max_k_idx))
3372 while (!k_info[k].name);
3376 t = (int)k_ptr->x_attr;
3377 (void)cmd_visuals_aux(i, &t, 256);
3378 k_ptr->x_attr = (byte)t;
3382 t = (int)k_ptr->x_char;
3383 (void)cmd_visuals_aux(i, &t, 256);
3384 k_ptr->x_char = (byte)t;
3388 do_cmd_knowledge_objects(&need_redraw, TRUE, k);
3390 print_visuals_menu(choice_msg);
3398 /* Modify feature attr/chars (numeric operation) */
3401 static concptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
3403 static IDX lighting_level = F_LIT_STANDARD;
3404 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3406 /* Hack -- query until done */
3409 feature_type *f_ptr = &f_info[f];
3413 TERM_COLOR da = f_ptr->d_attr[lighting_level];
3414 byte dc = f_ptr->d_char[lighting_level];
3415 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
3416 byte cc = f_ptr->x_char[lighting_level];
3418 /* Label the object */
3420 Term_putstr(5, 17, -1, TERM_WHITE,
3421 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
3422 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
3424 /* Label the Default values */
3425 Term_putstr(10, 19, -1, TERM_WHITE,
3426 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3428 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3429 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3431 /* Label the Current values */
3433 Term_putstr(10, 20, -1, TERM_WHITE,
3434 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
3436 Term_putstr(10, 20, -1, TERM_WHITE,
3437 format("Current attr/char = %3d / %3d", ca, cc));
3440 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3441 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3445 Term_putstr(0, 22, -1, TERM_WHITE,
3446 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3448 Term_putstr(0, 22, -1, TERM_WHITE,
3449 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3455 if (i == ESCAPE) break;
3457 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3458 else if (isupper(i)) c = 'a' + i - 'A';
3468 if (!cmd_visuals_aux(i, &f, max_f_idx))
3474 while (!f_info[f].name || (f_info[f].mimic != f));
3478 t = (int)f_ptr->x_attr[lighting_level];
3479 (void)cmd_visuals_aux(i, &t, 256);
3480 f_ptr->x_attr[lighting_level] = (byte)t;
3484 t = (int)f_ptr->x_char[lighting_level];
3485 (void)cmd_visuals_aux(i, &t, 256);
3486 f_ptr->x_char[lighting_level] = (byte)t;
3490 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
3493 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
3497 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
3499 print_visuals_menu(choice_msg);
3507 /* Modify monster attr/chars (visual mode) */
3509 do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
3512 /* Modify object attr/chars (visual mode) */
3514 do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
3517 /* Modify feature attr/chars (visual mode) */
3520 IDX lighting_level = F_LIT_STANDARD;
3521 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
3525 #endif /* ALLOW_VISUALS */
3533 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
3537 /* Unknown option */
3547 if (need_redraw) do_cmd_redraw();
3552 * Interact with "colors"
3554 void do_cmd_colors(void)
3563 /* File type is "TEXT" */
3564 FILE_TYPE(FILE_TYPE_TEXT);
3569 /* Interact until done */
3574 /* Ask for a choice */
3575 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
3577 /* Give some choices */
3578 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
3581 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
3582 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
3586 prt(_("コマンド: ", "Command: "), 8, 0);
3590 if (i == ESCAPE) break;
3592 /* Load a 'pref' file */
3596 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
3599 prt(_("ファイル: ", "File: "), 10, 0);
3602 sprintf(tmp, "%s.prf", player_base);
3605 if (!askfor(tmp, 70)) continue;
3607 /* Process the given filename */
3608 (void)process_pref_file(tmp);
3610 /* Mega-Hack -- react to changes */
3611 Term_xtra(TERM_XTRA_REACT, 0);
3613 /* Mega-Hack -- redraw */
3622 static concptr mark = "Colors";
3625 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
3628 prt(_("ファイル: ", "File: "), 10, 0);
3630 /* Default filename */
3631 sprintf(tmp, "%s.prf", player_base);
3633 /* Get a filename */
3634 if (!askfor(tmp, 70)) continue;
3636 /* Build the filename */
3637 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3639 /* Append to the file */
3640 if (!open_auto_dump(buf, mark)) continue;
3643 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
3646 for (i = 0; i < 256; i++)
3648 int kv = angband_color_table[i][0];
3649 int rv = angband_color_table[i][1];
3650 int gv = angband_color_table[i][2];
3651 int bv = angband_color_table[i][3];
3653 concptr name = _("未知", "unknown");
3655 /* Skip non-entries */
3656 if (!kv && !rv && !gv && !bv) continue;
3658 /* Extract the color name */
3659 if (i < 16) name = color_names[i];
3661 /* Dump a comment */
3662 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
3664 /* Dump the monster attr/char info */
3665 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
3672 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
3681 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
3683 /* Hack -- query until done */
3692 /* Exhibit the normal colors */
3693 for (j = 0; j < 16; j++)
3695 /* Exhibit this color */
3696 Term_putstr(j*4, 20, -1, a, "###");
3698 /* Exhibit all colors */
3699 Term_putstr(j*4, 22, -1, j, format("%3d", j));
3702 /* Describe the color */
3703 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
3705 /* Describe the color */
3706 Term_putstr(5, 10, -1, TERM_WHITE,
3707 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
3709 /* Label the Current values */
3710 Term_putstr(5, 12, -1, TERM_WHITE,
3711 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
3712 angband_color_table[a][0],
3713 angband_color_table[a][1],
3714 angband_color_table[a][2],
3715 angband_color_table[a][3]));
3718 Term_putstr(0, 14, -1, TERM_WHITE,
3719 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
3724 if (i == ESCAPE) break;
3727 if (i == 'n') a = (byte)(a + 1);
3728 if (i == 'N') a = (byte)(a - 1);
3729 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
3730 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
3731 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
3732 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
3733 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
3734 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
3735 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
3736 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
3738 /* Hack -- react to changes */
3739 Term_xtra(TERM_XTRA_REACT, 0);
3741 /* Hack -- redraw */
3748 /* Unknown option */
3762 * Note something in the message recall
3764 void do_cmd_note(void)
3772 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
3774 /* Ignore empty notes */
3775 if (!buf[0] || (buf[0] == ' ')) return;
3777 /* Add the note to the message recall */
3778 msg_format(_("メモ: %s", "Note: %s"), buf);
3783 * Mention the current version
3785 void do_cmd_version(void)
3787 #if FAKE_VER_EXTRA > 0
3788 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
3789 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
3791 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
3792 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
3799 * Array of feeling strings
3801 static concptr do_cmd_feeling_text[11] =
3803 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3804 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3805 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
3806 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3807 _("とても悪い予感がする...", "You have a very bad feeling..."),
3808 _("悪い予感がする...", "You have a bad feeling..."),
3809 _("何か緊張する。", "You feel nervous."),
3810 _("少し不運な気がする...", "You feel your luck is turning..."),
3811 _("この場所は好きになれない。", "You don't like the look of this place."),
3812 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3813 _("なんて退屈なところだ...", "What a boring place...")
3816 static concptr do_cmd_feeling_text_combat[11] =
3818 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3819 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3820 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
3821 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3822 _("とても悪い予感がする...", "You have a very bad feeling..."),
3823 _("悪い予感がする...", "You have a bad feeling..."),
3824 _("何か緊張する。", "You feel nervous."),
3825 _("少し不運な気がする...", "You feel your luck is turning..."),
3826 _("この場所は好きになれない。", "You don't like the look of this place."),
3827 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3828 _("なんて退屈なところだ...", "What a boring place...")
3831 static concptr do_cmd_feeling_text_lucky[11] =
3833 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3834 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3835 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
3836 _("素晴らしい感じがする...", "You have an excellent feeling..."),
3837 _("とても良い感じがする...", "You have a very good feeling..."),
3838 _("良い感じがする...", "You have a good feeling..."),
3839 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
3840 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
3841 _("見た感じ悪くはない...", "You like the look of this place..."),
3842 _("全然駄目ということはないが...", "This level can't be all bad..."),
3843 _("なんて退屈なところだ...", "What a boring place...")
3848 * Note that "feeling" is set to zero unless some time has passed.
3849 * Note that this is done when the level is GENERATED, not entered.
3851 void do_cmd_feeling(void)
3853 if (p_ptr->wild_mode) return;
3855 /* No useful feeling in quests */
3856 if (p_ptr->inside_quest && !random_quest_number(dun_level))
3858 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
3862 /* No useful feeling in town */
3863 else if (p_ptr->town_num && !dun_level)
3865 if (!strcmp(town[p_ptr->town_num].name, _("荒野", "wilderness")))
3867 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
3872 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
3877 /* No useful feeling in the wilderness */
3878 else if (!dun_level)
3880 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
3884 /* Display the feeling */
3885 if (p_ptr->muta3 & MUT3_GOOD_LUCK)
3886 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
3887 else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
3888 inventory[INVEN_BOW].name1 == ART_CRIMSON)
3889 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
3891 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
3897 * Description of each monster group.
3899 static concptr monster_group_text[] =
3902 "ユニーク", /* "Uniques" */
3903 "乗馬可能なモンスター", /* "Riding" */
3904 "賞金首", /* "Wanted */
3905 "アンバーの王族", /* "Ambertite" */
3934 /* "古代ドラゴン/ワイアーム", */
3995 /* "Ancient Dragon/Wyrm", */
4004 "Multi-Headed Reptile",
4009 "Reptile/Amphibian",
4010 "Spider/Scorpion/Tick",
4012 /* "Major Demon", */
4029 * Symbols of monsters in each group. Note the "Uniques" group
4030 * is handled differently.
4032 static concptr monster_group_char[] =
4089 "!$&()+./=>?[\\]`{|~",
4099 * hook function to sort monsters by level
4101 static bool ang_sort_comp_monster_level(vptr u, vptr v, int a, int b)
4103 u16b *who = (u16b*)(u);
4108 monster_race *r_ptr1 = &r_info[w1];
4109 monster_race *r_ptr2 = &r_info[w2];
4114 if (r_ptr2->level > r_ptr1->level) return TRUE;
4115 if (r_ptr1->level > r_ptr2->level) return FALSE;
4117 if ((r_ptr2->flags1 & RF1_UNIQUE) && !(r_ptr1->flags1 & RF1_UNIQUE)) return TRUE;
4118 if ((r_ptr1->flags1 & RF1_UNIQUE) && !(r_ptr2->flags1 & RF1_UNIQUE)) return FALSE;
4123 * Build a list of monster indexes in the given group. Return the number
4124 * of monsters in the group.
4126 * mode & 0x01 : check for non-empty group
4127 * mode & 0x02 : visual operation only
4129 static IDX collect_monsters(IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
4135 /* Get a list of x_char in this group */
4136 concptr group_char = monster_group_char[grp_cur];
4138 /* XXX Hack -- Check if this is the "Uniques" group */
4139 bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
4141 /* XXX Hack -- Check if this is the "Riding" group */
4142 bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
4144 /* XXX Hack -- Check if this is the "Wanted" group */
4145 bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
4147 /* XXX Hack -- Check if this is the "Amberite" group */
4148 bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
4151 /* Check every race */
4152 for (i = 0; i < max_r_idx; i++)
4154 /* Access the race */
4155 monster_race *r_ptr = &r_info[i];
4157 /* Skip empty race */
4158 if (!r_ptr->name) continue ;
4160 /* Require known monsters */
4161 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
4165 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4168 else if (grp_riding)
4170 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
4173 else if (grp_wanted)
4175 bool wanted = FALSE;
4177 for (j = 0; j < MAX_KUBI; j++)
4179 if (kubi_r_idx[j] == i || kubi_r_idx[j] - 10000 == i ||
4180 (p_ptr->today_mon && p_ptr->today_mon == i))
4186 if (!wanted) continue;
4189 else if (grp_amberite)
4191 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
4196 /* Check for race in the group */
4197 if (!my_strchr(group_char, r_ptr->d_char)) continue;
4201 mon_idx[mon_cnt++] = i;
4203 /* XXX Hack -- Just checking for non-empty group */
4204 if (mode & 0x01) break;
4207 /* Terminate the list */
4208 mon_idx[mon_cnt] = -1;
4210 /* Select the sort method */
4211 ang_sort_comp = ang_sort_comp_monster_level;
4212 ang_sort_swap = ang_sort_swap_hook;
4214 /* Sort by monster level */
4215 ang_sort(mon_idx, &dummy_why, mon_cnt);
4217 /* Return the number of races */
4223 * Description of each monster group.
4225 static concptr object_group_text[] =
4228 "キノコ", /* "Mushrooms" */
4229 "薬", /* "Potions" */
4230 "油つぼ", /* "Flasks" */
4231 "巻物", /* "Scrolls" */
4233 "アミュレット", /* "Amulets" */
4234 "笛", /* "Whistle" */
4235 "光源", /* "Lanterns" */
4236 "魔法棒", /* "Wands" */
4239 "カード", /* "Cards" */
4250 "刀剣類", /* "Swords" */
4251 "鈍器", /* "Blunt Weapons" */
4252 "長柄武器", /* "Polearms" */
4253 "採掘道具", /* "Diggers" */
4254 "飛び道具", /* "Bows" */
4258 "軽装鎧", /* "Soft Armor" */
4259 "重装鎧", /* "Hard Armor" */
4260 "ドラゴン鎧", /* "Dragon Armor" */
4261 "盾", /* "Shields" */
4262 "クローク", /* "Cloaks" */
4263 "籠手", /* "Gloves" */
4264 "ヘルメット", /* "Helms" */
4266 "ブーツ", /* "Boots" */
4319 * TVALs of items in each group
4321 static byte object_group_tval[] =
4362 TV_LIFE_BOOK, /* Hack -- all spellbooks */
4370 * Build a list of object indexes in the given group. Return the number
4371 * of objects in the group.
4373 * mode & 0x01 : check for non-empty group
4374 * mode & 0x02 : visual operation only
4376 static KIND_OBJECT_IDX collect_objects(int grp_cur, KIND_OBJECT_IDX object_idx[], BIT_FLAGS8 mode)
4378 KIND_OBJECT_IDX i, object_cnt = 0;
4381 /* Get a list of x_char in this group */
4382 byte group_tval = object_group_tval[grp_cur];
4384 /* Check every object */
4385 for (i = 0; i < max_k_idx; i++)
4387 /* Access the object */
4388 object_kind *k_ptr = &k_info[i];
4390 /* Skip empty objects */
4391 if (!k_ptr->name) continue;
4395 /* Any objects will be displayed */
4401 /* Skip non-flavoured objects */
4402 if (!k_ptr->flavor) continue;
4404 /* Require objects ever seen */
4405 if (!k_ptr->aware) continue;
4408 /* Skip items with no distribution (special artifacts) */
4409 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
4413 /* Check for objects in the group */
4414 if (TV_LIFE_BOOK == group_tval)
4416 /* Hack -- All spell books */
4417 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
4419 /* Add the object */
4420 object_idx[object_cnt++] = i;
4424 else if (k_ptr->tval == group_tval)
4426 /* Add the object */
4427 object_idx[object_cnt++] = i;
4431 /* XXX Hack -- Just checking for non-empty group */
4432 if (mode & 0x01) break;
4435 /* Terminate the list */
4436 object_idx[object_cnt] = -1;
4438 /* Return the number of objects */
4444 * Description of each feature group.
4446 static concptr feature_group_text[] =
4454 * Build a list of feature indexes in the given group. Return the number
4455 * of features in the group.
4457 * mode & 0x01 : check for non-empty group
4459 static FEAT_IDX collect_features(int grp_cur, FEAT_IDX *feat_idx, BIT_FLAGS8 mode)
4462 FEAT_IDX feat_cnt = 0;
4464 /* Unused; There is a single group. */
4467 /* Check every feature */
4468 for (i = 0; i < max_f_idx; i++)
4470 /* Access the index */
4471 feature_type *f_ptr = &f_info[i];
4473 /* Skip empty index */
4474 if (!f_ptr->name) continue;
4476 /* Skip mimiccing features */
4477 if (f_ptr->mimic != i) continue;
4480 feat_idx[feat_cnt++] = i;
4482 /* XXX Hack -- Just checking for non-empty group */
4483 if (mode & 0x01) break;
4486 /* Terminate the list */
4487 feat_idx[feat_cnt] = -1;
4489 /* Return the number of races */
4496 * Build a list of monster indexes in the given group. Return the number
4497 * of monsters in the group.
4499 static int collect_artifacts(int grp_cur, int object_idx[])
4501 int i, object_cnt = 0;
4503 /* Get a list of x_char in this group */
4504 byte group_tval = object_group_tval[grp_cur];
4506 /* Check every object */
4507 for (i = 0; i < max_a_idx; i++)
4509 /* Access the artifact */
4510 artifact_type *a_ptr = &a_info[i];
4512 /* Skip empty artifacts */
4513 if (!a_ptr->name) continue;
4515 /* Skip "uncreated" artifacts */
4516 if (!a_ptr->cur_num) continue;
4518 /* Check for race in the group */
4519 if (a_ptr->tval == group_tval)
4522 object_idx[object_cnt++] = i;
4526 /* Terminate the list */
4527 object_idx[object_cnt] = 0;
4529 /* Return the number of races */
4536 * Encode the screen colors
4538 static char hack[17] = "dwsorgbuDWvyRGBU";
4542 * Hack -- load a screen dump from a file
4544 void do_cmd_load_screen(void)
4549 SYMBOL_CODE c = ' ';
4555 Term_get_size(&wid, &hgt);
4557 /* Build the filename */
4558 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4560 /* Append to the file */
4561 fff = my_fopen(buf, "r");
4564 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4572 /* Load the screen */
4573 for (y = 0; okay; y++)
4575 /* Get a line of data including control code */
4576 if (!fgets(buf, 1024, fff)) okay = FALSE;
4578 /* Get the blank line */
4579 if (buf[0] == '\n' || buf[0] == '\0') break;
4581 /* Ignore too large screen image */
4582 if (y >= hgt) continue;
4585 for (x = 0; x < wid - 1; x++)
4588 if (buf[x] == '\n' || buf[x] == '\0') break;
4590 /* Put the attr/char */
4591 Term_draw(x, y, TERM_WHITE, buf[x]);
4595 /* Dump the screen */
4596 for (y = 0; okay; y++)
4598 /* Get a line of data including control code */
4599 if (!fgets(buf, 1024, fff)) okay = FALSE;
4601 /* Get the blank line */
4602 if (buf[0] == '\n' || buf[0] == '\0') break;
4604 /* Ignore too large screen image */
4605 if (y >= hgt) continue;
4608 for (x = 0; x < wid - 1; x++)
4611 if (buf[x] == '\n' || buf[x] == '\0') break;
4613 /* Get the attr/char */
4614 (void)(Term_what(x, y, &a, &c));
4616 /* Look up the attr */
4617 for (i = 0; i < 16; i++)
4619 /* Use attr matches */
4620 if (hack[i] == buf[x]) a = (byte_hack)i;
4623 /* Put the attr/char */
4624 Term_draw(x, y, a, c);
4631 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4642 concptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4643 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4646 #define IM_FLAG_STR _("*", "* ")
4647 #define HAS_FLAG_STR _("+", "+ ")
4648 #define NO_FLAG_STR _("・", ". ")
4650 #define print_im_or_res_flag(IM, RES) \
4652 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4653 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4656 #define print_flag(TR) \
4658 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4662 /* XTRA HACK RESLIST */
4663 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
4665 GAME_TEXT o_name[MAX_NLEN];
4666 BIT_FLAGS flgs[TR_FLAG_SIZE];
4668 if (!o_ptr->k_idx) return;
4669 if (o_ptr->tval != tval) return;
4671 /* Identified items only */
4672 if (!object_is_known(o_ptr)) return;
4675 * HACK:Ring of Lordly protection and Dragon equipment
4676 * have random resistances.
4678 if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4679 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4680 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4681 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4682 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4683 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4684 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4685 || object_is_artifact(o_ptr))
4688 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4690 while (o_name[i] && (i < 26))
4693 if (iskanji(o_name[i])) i++;
4702 o_name[i] = ' '; i++;
4707 fprintf(fff, "%s %s", where, o_name);
4709 if (!(o_ptr->ident & (IDENT_MENTAL)))
4711 fputs(_("-------不明--------------- -------不明---------\n",
4712 "-------unknown------------ -------unknown------\n"), fff);
4716 object_flags_known(o_ptr, flgs);
4718 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4719 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4720 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4721 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4722 print_flag(TR_RES_POIS);
4723 print_flag(TR_RES_LITE);
4724 print_flag(TR_RES_DARK);
4725 print_flag(TR_RES_SHARDS);
4726 print_flag(TR_RES_SOUND);
4727 print_flag(TR_RES_NETHER);
4728 print_flag(TR_RES_NEXUS);
4729 print_flag(TR_RES_CHAOS);
4730 print_flag(TR_RES_DISEN);
4734 print_flag(TR_RES_BLIND);
4735 print_flag(TR_RES_FEAR);
4736 print_flag(TR_RES_CONF);
4737 print_flag(TR_FREE_ACT);
4738 print_flag(TR_SEE_INVIS);
4739 print_flag(TR_HOLD_EXP);
4740 print_flag(TR_TELEPATHY);
4741 print_flag(TR_SLOW_DIGEST);
4742 print_flag(TR_REGEN);
4743 print_flag(TR_LEVITATION);
4751 fprintf(fff, "%s\n", inven_res_label);
4757 * Display *ID* ed weapons/armors's resistances
4759 static void do_cmd_knowledge_inven(void)
4762 GAME_TEXT file_name[1024];
4764 OBJECT_TYPE_VALUE tval;
4770 /* Open a new file */
4771 fff = my_fopen_temp(file_name, 1024);
4774 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4778 fprintf(fff, "%s\n", inven_res_label);
4780 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4784 for (; j < 9; j++) fputc('\n', fff);
4786 fprintf(fff, "%s\n", inven_res_label);
4788 strcpy(where, _("装", "E "));
4789 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4791 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4793 strcpy(where, _("持", "I "));
4794 for (i = 0; i < INVEN_PACK; i++)
4796 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4799 st_ptr = &town[1].store[STORE_HOME];
4800 strcpy(where, _("家", "H "));
4801 for (i = 0; i < st_ptr->stock_num; i++)
4803 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
4808 /* Display the file contents */
4809 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
4811 /* Remove the file */
4816 void do_cmd_save_screen_html_aux(char *filename, int message)
4821 TERM_COLOR a = 0, old_a = 0;
4835 concptr html_head[] = {
4836 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
4840 concptr html_foot[] = {
4842 "</body>\n</html>\n",
4848 Term_get_size(&wid, &hgt);
4850 /* File type is "TEXT" */
4851 FILE_TYPE(FILE_TYPE_TEXT);
4853 /* Append to the file */
4854 fff = my_fopen(filename, "w");
4858 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
4864 if (message) screen_save();
4866 /* Build the filename */
4867 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
4868 tmpfff = my_fopen(buf, "r");
4870 for (i = 0; html_head[i]; i++)
4871 fputs(html_head[i], fff);
4875 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4877 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
4881 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
4883 fprintf(fff, "%s\n", buf);
4888 /* Dump the screen */
4889 for (y = 0; y < hgt; y++)
4896 for (x = 0; x < wid - 1; x++)
4900 /* Get the attr/char */
4901 (void)(Term_what(x, y, &a, &c));
4905 case '&': cc = "&"; break;
4906 case '<': cc = "<"; break;
4907 case '>': cc = ">"; break;
4909 case 0x1f: c = '.'; break;
4910 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
4915 if ((y == 0 && x == 0) || a != old_a) {
4916 rv = angband_color_table[a][1];
4917 gv = angband_color_table[a][2];
4918 bv = angband_color_table[a][3];
4919 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
4920 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
4924 fprintf(fff, "%s", cc);
4926 fprintf(fff, "%c", c);
4929 fprintf(fff, "</font>");
4932 for (i = 0; html_foot[i]; i++)
4933 fputs(html_foot[i], fff);
4938 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4940 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
4944 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
4946 fprintf(fff, "%s\n", buf);
4959 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4967 * Hack -- save a screen dump to a file
4969 static void do_cmd_save_screen_html(void)
4971 char buf[1024], tmp[256] = "screen.html";
4973 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
4976 /* Build the filename */
4977 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4981 do_cmd_save_screen_html_aux(buf, 1);
4986 * Redefinable "save_screen" action
4988 void (*screendump_aux)(void) = NULL;
4992 * Hack -- save a screen dump to a file
4994 void do_cmd_save_screen(void)
4996 bool old_use_graphics = use_graphics;
4997 bool html_dump = FALSE;
5001 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
5005 if (c == 'Y' || c == 'y')
5007 else if (c == 'H' || c == 'h')
5019 Term_get_size(&wid, &hgt);
5021 if (old_use_graphics)
5023 use_graphics = FALSE;
5025 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5031 do_cmd_save_screen_html();
5035 /* Do we use a special screendump function ? */
5036 else if (screendump_aux)
5038 /* Dump the screen to a graphics file */
5039 (*screendump_aux)();
5041 else /* Dump the screen as text */
5045 SYMBOL_CODE c = ' ';
5049 /* Build the filename */
5050 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5052 /* File type is "TEXT" */
5053 FILE_TYPE(FILE_TYPE_TEXT);
5055 /* Append to the file */
5056 fff = my_fopen(buf, "w");
5060 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5068 /* Dump the screen */
5069 for (y = 0; y < hgt; y++)
5072 for (x = 0; x < wid - 1; x++)
5074 /* Get the attr/char */
5075 (void)(Term_what(x, y, &a, &c));
5085 fprintf(fff, "%s\n", buf);
5092 /* Dump the screen */
5093 for (y = 0; y < hgt; y++)
5096 for (x = 0; x < wid - 1; x++)
5098 /* Get the attr/char */
5099 (void)(Term_what(x, y, &a, &c));
5102 buf[x] = hack[a&0x0F];
5109 fprintf(fff, "%s\n", buf);
5118 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5123 if (old_use_graphics)
5125 use_graphics = TRUE;
5127 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5134 * Sorting hook -- Comp function -- see below
5136 * We use "u" to point to array of monster indexes,
5137 * and "v" to select the type of sorting to perform on "u".
5139 static bool ang_sort_art_comp(vptr u, vptr v, int a, int b)
5141 u16b *who = (u16b*)(u);
5143 u16b *why = (u16b*)(v);
5150 /* Sort by total kills */
5153 /* Extract total kills */
5154 z1 = a_info[w1].tval;
5155 z2 = a_info[w2].tval;
5157 /* Compare total kills */
5158 if (z1 < z2) return (TRUE);
5159 if (z1 > z2) return (FALSE);
5163 /* Sort by monster level */
5166 /* Extract levels */
5167 z1 = a_info[w1].sval;
5168 z2 = a_info[w2].sval;
5170 /* Compare levels */
5171 if (z1 < z2) return (TRUE);
5172 if (z1 > z2) return (FALSE);
5176 /* Sort by monster experience */
5179 /* Extract experience */
5180 z1 = a_info[w1].level;
5181 z2 = a_info[w2].level;
5183 /* Compare experience */
5184 if (z1 < z2) return (TRUE);
5185 if (z1 > z2) return (FALSE);
5189 /* Compare indexes */
5195 * Sorting hook -- Swap function -- see below
5197 * We use "u" to point to array of monster indexes,
5198 * and "v" to select the type of sorting to perform.
5200 static void ang_sort_art_swap(vptr u, vptr v, int a, int b)
5202 u16b *who = (u16b*)(u);
5217 * Check the status of "artifacts"
5219 static void do_cmd_knowledge_artifacts(void)
5229 GAME_TEXT file_name[1024];
5230 GAME_TEXT base_name[MAX_NLEN];
5234 /* Open a new file */
5235 fff = my_fopen_temp(file_name, 1024);
5238 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5243 /* Allocate the "who" array */
5244 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
5246 /* Allocate the "okay" array */
5247 C_MAKE(okay, max_a_idx, bool);
5249 /* Scan the artifacts */
5250 for (k = 0; k < max_a_idx; k++)
5252 artifact_type *a_ptr = &a_info[k];
5257 /* Skip "empty" artifacts */
5258 if (!a_ptr->name) continue;
5260 /* Skip "uncreated" artifacts */
5261 if (!a_ptr->cur_num) continue;
5267 /* Check the dungeon */
5268 for (y = 0; y < cur_hgt; y++)
5270 for (x = 0; x < cur_wid; x++)
5272 cave_type *c_ptr = &cave[y][x];
5274 OBJECT_IDX this_o_idx, next_o_idx = 0;
5276 /* Scan all objects in the grid */
5277 for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5280 o_ptr = &o_list[this_o_idx];
5282 /* Acquire next object */
5283 next_o_idx = o_ptr->next_o_idx;
5285 /* Ignore non-artifacts */
5286 if (!object_is_fixed_artifact(o_ptr)) continue;
5288 /* Ignore known items */
5289 if (object_is_known(o_ptr)) continue;
5291 /* Note the artifact */
5292 okay[o_ptr->name1] = FALSE;
5297 /* Check the inventory and equipment */
5298 for (i = 0; i < INVEN_TOTAL; i++)
5300 object_type *o_ptr = &inventory[i];
5302 /* Ignore non-objects */
5303 if (!o_ptr->k_idx) continue;
5305 /* Ignore non-artifacts */
5306 if (!object_is_fixed_artifact(o_ptr)) continue;
5308 /* Ignore known items */
5309 if (object_is_known(o_ptr)) continue;
5311 /* Note the artifact */
5312 okay[o_ptr->name1] = FALSE;
5315 for (k = 0; k < max_a_idx; k++)
5317 if (okay[k]) who[n++] = k;
5320 /* Select the sort method */
5321 ang_sort_comp = ang_sort_art_comp;
5322 ang_sort_swap = ang_sort_art_swap;
5324 /* Sort the array by dungeon depth of monsters */
5325 ang_sort(who, &why, n);
5327 /* Scan the artifacts */
5328 for (k = 0; k < n; k++)
5330 artifact_type *a_ptr = &a_info[who[k]];
5333 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5335 /* Obtain the base object type */
5336 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5345 /* Create fake object */
5346 object_prep(q_ptr, z);
5348 /* Make it an artifact */
5349 q_ptr->name1 = (byte)who[k];
5351 /* Display as if known */
5352 q_ptr->ident |= IDENT_STORE;
5354 /* Describe the artifact */
5355 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5358 /* Hack -- Build the artifact name */
5359 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
5362 /* Free the "who" array */
5363 C_KILL(who, max_a_idx, ARTIFACT_IDX);
5365 /* Free the "okay" array */
5366 C_KILL(okay, max_a_idx, bool);
5369 /* Display the file contents */
5370 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5372 /* Remove the file */
5378 * Display known uniques
5379 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5381 static void do_cmd_knowledge_uniques(void)
5390 GAME_TEXT file_name[1024];
5393 int n_alive_surface = 0;
5394 int n_alive_over100 = 0;
5395 int n_alive_total = 0;
5398 for (i = 0; i < 10; i++) n_alive[i] = 0;
5400 /* Open a new file */
5401 fff = my_fopen_temp(file_name, 1024);
5405 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5410 /* Allocate the "who" array */
5411 C_MAKE(who, max_r_idx, MONRACE_IDX);
5413 /* Scan the monsters */
5414 for (i = 1; i < max_r_idx; i++)
5416 monster_race *r_ptr = &r_info[i];
5419 if (!r_ptr->name) continue;
5421 /* Require unique monsters */
5422 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5424 /* Only display "known" uniques */
5425 if (!cheat_know && !r_ptr->r_sights) continue;
5427 /* Only print rarity <= 100 uniques */
5428 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5430 /* Only "alive" uniques */
5431 if (r_ptr->max_num == 0) continue;
5435 lev = (r_ptr->level - 1) / 10;
5439 if (max_lev < lev) max_lev = lev;
5441 else n_alive_over100++;
5443 else n_alive_surface++;
5445 /* Collect "appropriate" monsters */
5449 /* Select the sort method */
5450 ang_sort_comp = ang_sort_comp_hook;
5451 ang_sort_swap = ang_sort_swap_hook;
5453 /* Sort the array by dungeon depth of monsters */
5454 ang_sort(who, &why, n);
5456 if (n_alive_surface)
5458 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
5459 n_alive_total += n_alive_surface;
5461 for (i = 0; i <= max_lev; i++)
5463 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5464 n_alive_total += n_alive[i];
5466 if (n_alive_over100)
5468 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
5469 n_alive_total += n_alive_over100;
5474 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
5475 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
5479 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5482 /* Scan the monster races */
5483 for (k = 0; k < n; k++)
5485 monster_race *r_ptr = &r_info[who[k]];
5487 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
5490 /* Free the "who" array */
5491 C_KILL(who, max_r_idx, s16b);
5494 /* Display the file contents */
5495 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5497 /* Remove the file */
5503 * Display weapon-exp
5505 static void do_cmd_knowledge_weapon_exp(void)
5513 GAME_TEXT file_name[1024];
5516 /* Open a new file */
5517 fff = my_fopen_temp(file_name, 1024);
5519 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5524 for (i = 0; i < 5; i++)
5526 for (num = 0; num < 64; num++)
5528 for (j = 0; j < max_k_idx; j++)
5530 object_kind *k_ptr = &k_info[j];
5532 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5534 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5536 weapon_exp = p_ptr->weapon_exp[4 - i][num];
5538 fprintf(fff, "%-25s ", tmp);
5539 if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5540 else fprintf(fff, " ");
5541 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5542 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5551 /* Display the file contents */
5552 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5554 /* Remove the file */
5560 * @brief 魔法の経験値を表示するコマンドのメインルーチン
5564 static void do_cmd_knowledge_spell_exp(void)
5571 const magic_type *s_ptr;
5573 GAME_TEXT file_name[1024];
5575 /* Open a new file */
5576 fff = my_fopen_temp(file_name, 1024);
5578 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5583 if (p_ptr->realm1 != REALM_NONE)
5585 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5586 for (i = 0; i < 32; i++)
5588 if (!is_magic(p_ptr->realm1))
5590 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5594 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5596 if (s_ptr->slevel >= 99) continue;
5597 spell_exp = p_ptr->spell_exp[i];
5598 exp_level = spell_exp_level(spell_exp);
5599 fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5600 if (p_ptr->realm1 == REALM_HISSATSU)
5601 fprintf(fff, "[--]");
5604 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5605 else fprintf(fff, " ");
5606 fprintf(fff, "%s", exp_level_str[exp_level]);
5608 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5613 if (p_ptr->realm2 != REALM_NONE)
5615 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5616 for (i = 0; i < 32; i++)
5618 if (!is_magic(p_ptr->realm1))
5620 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5624 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5626 if (s_ptr->slevel >= 99) continue;
5628 spell_exp = p_ptr->spell_exp[i + 32];
5629 exp_level = spell_exp_level(spell_exp);
5630 fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5631 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5632 else fprintf(fff, " ");
5633 fprintf(fff, "%s", exp_level_str[exp_level]);
5634 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5640 /* Display the file contents */
5641 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5643 /* Remove the file */
5649 * @brief スキル情報を表示するコマンドのメインルーチン /
5653 static void do_cmd_knowledge_skill_exp(void)
5655 int i = 0, skill_exp;
5659 char file_name[1024];
5660 char skill_name[GINOU_TEMPMAX][20] =
5662 _("マーシャルアーツ", "Martial Arts "),
5663 _("二刀流 ", "Dual Wielding "),
5664 _("乗馬 ", "Riding "),
5668 /* Open a new file */
5669 fff = my_fopen_temp(file_name, 1024);
5671 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5676 for (i = 0; i < GINOU_TEMPMAX; i++)
5678 skill_exp = p_ptr->skill_exp[i];
5679 fprintf(fff, "%-20s ", skill_name[i]);
5680 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5681 else fprintf(fff, " ");
5682 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5683 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5688 /* Display the file contents */
5689 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5691 /* Remove the file */
5697 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5698 * @param Name 変換したい文字列の参照ポインタ
5701 void plural_aux(char *Name)
5703 int NameLen = strlen(Name);
5705 if (my_strstr(Name, "Disembodied hand"))
5707 strcpy(Name, "Disembodied hands that strangled people");
5709 else if (my_strstr(Name, "Colour out of space"))
5711 strcpy(Name, "Colours out of space");
5713 else if (my_strstr(Name, "stairway to hell"))
5715 strcpy(Name, "stairways to hell");
5717 else if (my_strstr(Name, "Dweller on the threshold"))
5719 strcpy(Name, "Dwellers on the threshold");
5721 else if (my_strstr(Name, " of "))
5723 concptr aider = my_strstr(Name, " of ");
5734 if (dummy[i-1] == 's')
5736 strcpy(&(dummy[i]), "es");
5741 strcpy(&(dummy[i]), "s");
5744 strcpy(&(dummy[i+1]), aider);
5745 strcpy(Name, dummy);
5747 else if (my_strstr(Name, "coins"))
5750 strcpy(dummy, "piles of ");
5751 strcat(dummy, Name);
5752 strcpy(Name, dummy);
5755 else if (my_strstr(Name, "Manes"))
5759 else if (streq(&(Name[NameLen - 2]), "ey"))
5761 strcpy(&(Name[NameLen - 2]), "eys");
5763 else if (Name[NameLen - 1] == 'y')
5765 strcpy(&(Name[NameLen - 1]), "ies");
5767 else if (streq(&(Name[NameLen - 4]), "ouse"))
5769 strcpy(&(Name[NameLen - 4]), "ice");
5771 else if (streq(&(Name[NameLen - 2]), "us"))
5773 strcpy(&(Name[NameLen - 2]), "i");
5775 else if (streq(&(Name[NameLen - 6]), "kelman"))
5777 strcpy(&(Name[NameLen - 6]), "kelmen");
5779 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5781 strcpy(&(Name[NameLen - 8]), "wordsmen");
5783 else if (streq(&(Name[NameLen - 7]), "oodsman"))
5785 strcpy(&(Name[NameLen - 7]), "oodsmen");
5787 else if (streq(&(Name[NameLen - 7]), "eastman"))
5789 strcpy(&(Name[NameLen - 7]), "eastmen");
5791 else if (streq(&(Name[NameLen - 8]), "izardman"))
5793 strcpy(&(Name[NameLen - 8]), "izardmen");
5795 else if (streq(&(Name[NameLen - 5]), "geist"))
5797 strcpy(&(Name[NameLen - 5]), "geister");
5799 else if (streq(&(Name[NameLen - 2]), "ex"))
5801 strcpy(&(Name[NameLen - 2]), "ices");
5803 else if (streq(&(Name[NameLen - 2]), "lf"))
5805 strcpy(&(Name[NameLen - 2]), "lves");
5807 else if (suffix(Name, "ch") ||
5808 suffix(Name, "sh") ||
5809 suffix(Name, "nx") ||
5810 suffix(Name, "s") ||
5813 strcpy(&(Name[NameLen]), "es");
5817 strcpy(&(Name[NameLen]), "s");
5822 * @brief 現在のペットを表示するコマンドのメインルーチン /
5823 * Display current pets
5826 static void do_cmd_knowledge_pets(void)
5830 monster_type *m_ptr;
5831 GAME_TEXT pet_name[MAX_NLEN];
5833 int show_upkeep = 0;
5834 GAME_TEXT file_name[1024];
5837 /* Open a new file */
5838 fff = my_fopen_temp(file_name, 1024);
5840 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5845 /* Process the monsters (backwards) */
5846 for (i = m_max - 1; i >= 1; i--)
5848 /* Access the monster */
5851 /* Ignore "dead" monsters */
5852 if (!m_ptr->r_idx) continue;
5854 /* Calculate "upkeep" for pets */
5858 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
5859 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
5863 show_upkeep = calculate_upkeep();
5865 fprintf(fff, "----------------------------------------------\n");
5867 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
5869 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
5871 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
5876 /* Display the file contents */
5877 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
5879 /* Remove the file */
5885 * @brief 現在のペットを表示するコマンドのメインルーチン /
5888 * @note the player ghosts are ignored.
5890 static void do_cmd_knowledge_kill_count(void)
5897 GAME_TEXT file_name[1024];
5902 /* Open a new file */
5903 fff = my_fopen_temp(file_name, 1024);
5906 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5911 /* Allocate the "who" array */
5912 C_MAKE(who, max_r_idx, MONRACE_IDX);
5915 /* Monsters slain */
5918 for (kk = 1; kk < max_r_idx; kk++)
5920 monster_race *r_ptr = &r_info[kk];
5922 if (r_ptr->flags1 & (RF1_UNIQUE))
5924 bool dead = (r_ptr->max_num == 0);
5933 MONSTER_NUMBER This = r_ptr->r_pkills;
5943 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
5946 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
5948 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
5954 /* Scan the monsters */
5955 for (i = 1; i < max_r_idx; i++)
5957 monster_race *r_ptr = &r_info[i];
5959 /* Use that monster */
5960 if (r_ptr->name) who[n++] = i;
5963 /* Select the sort method */
5964 ang_sort_comp = ang_sort_comp_hook;
5965 ang_sort_swap = ang_sort_swap_hook;
5967 /* Sort the array by dungeon depth of monsters */
5968 ang_sort(who, &why, n);
5970 /* Scan the monster races */
5971 for (k = 0; k < n; k++)
5973 monster_race *r_ptr = &r_info[who[k]];
5975 if (r_ptr->flags1 & (RF1_UNIQUE))
5977 bool dead = (r_ptr->max_num == 0);
5981 fprintf(fff, " %s\n", (r_name + r_ptr->name));
5987 MONSTER_NUMBER This = r_ptr->r_pkills;
5992 /* p,tは人と数える by ita */
5993 if (my_strchr("pt", r_ptr->d_char))
5994 fprintf(fff, " %3d 人の %s\n", (int)This, r_name + r_ptr->name);
5996 fprintf(fff, " %3d 体の %s\n", (int)This, r_name + r_ptr->name);
6000 if (my_strstr(r_name + r_ptr->name, "coins"))
6002 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
6006 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
6012 strcpy(ToPlural, (r_name + r_ptr->name));
6013 plural_aux(ToPlural);
6014 fprintf(fff, " %d %s\n", This, ToPlural);
6024 fprintf(fff,"----------------------------------------------\n");
6026 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
6028 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)Total, (Total == 1 ? "" : "s"));
6032 /* Free the "who" array */
6033 C_KILL(who, max_r_idx, s16b);
6036 /* Display the file contents */
6037 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
6039 /* Remove the file */
6045 * @brief モンスター情報リスト中のグループを表示する /
6046 * Display the object groups.
6050 * @param per_page リストの表示行
6051 * @param grp_idx グループのID配列
6052 * @param group_text グループ名の文字列配列
6053 * @param grp_cur 現在の選択ID
6054 * @param grp_top 現在の選択リスト最上部ID
6057 static void display_group_list(int col, int row, int wid, int per_page, IDX grp_idx[], concptr group_text[], int grp_cur, int grp_top)
6061 /* Display lines until done */
6062 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
6064 /* Get the group index */
6065 int grp = grp_idx[grp_top + i];
6067 /* Choose a color */
6068 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
6070 /* Erase the entire line */
6071 Term_erase(col, row + i, wid);
6073 /* Display the group label */
6074 c_put_str(attr, group_text[grp], row + i, col);
6080 * Move the cursor in a browser window
6082 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
6083 IDX *list_cur, int list_cnt)
6088 IDX list = *list_cur;
6090 /* Extract direction */
6093 /* Hack -- scroll up full screen */
6098 /* Hack -- scroll down full screen */
6103 d = get_keymap_dir(ch);
6108 /* Diagonals - hack */
6109 if ((ddx[d] > 0) && ddy[d])
6114 Term_get_size(&wid, &hgt);
6116 browser_rows = hgt - 8;
6118 /* Browse group list */
6123 /* Move up or down */
6124 grp += ddy[d] * (browser_rows - 1);
6127 if (grp >= grp_cnt) grp = grp_cnt - 1;
6128 if (grp < 0) grp = 0;
6129 if (grp != old_grp) list = 0;
6132 /* Browse sub-list list */
6135 /* Move up or down */
6136 list += ddy[d] * browser_rows;
6139 if (list >= list_cnt) list = list_cnt - 1;
6140 if (list < 0) list = 0;
6152 if (col < 0) col = 0;
6153 if (col > 1) col = 1;
6160 /* Browse group list */
6165 /* Move up or down */
6169 if (grp >= grp_cnt) grp = grp_cnt - 1;
6170 if (grp < 0) grp = 0;
6171 if (grp != old_grp) list = 0;
6174 /* Browse sub-list list */
6177 /* Move up or down */
6181 if (list >= list_cnt) list = list_cnt - 1;
6182 if (list < 0) list = 0;
6193 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
6197 /* Clear the display lines */
6198 for (i = 0; i < height; i++)
6200 Term_erase(col, row + i, width);
6203 /* Bigtile mode uses double width */
6204 if (use_bigtile) width /= 2;
6206 /* Display lines until done */
6207 for (i = 0; i < height; i++)
6209 /* Display columns until done */
6210 for (j = 0; j < width; j++)
6214 TERM_LEN x = col + j;
6215 TERM_LEN y = row + i;
6218 /* Bigtile mode uses double width */
6219 if (use_bigtile) x += j;
6224 /* Ignore illegal characters */
6225 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6226 (!use_graphics && ic > 0x7f))
6232 /* Force correct code for both ASCII character and tile */
6233 if (c & 0x80) a |= 0x80;
6235 /* Display symbol */
6236 Term_queue_bigchar(x, y, a, c, 0, 0);
6243 * Place the cursor at the collect position for visual mode
6245 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
6247 int i = (a & 0x7f) - attr_top;
6248 int j = c - char_left;
6250 TERM_LEN x = col + j;
6251 TERM_LEN y = row + i;
6253 /* Bigtile mode uses double width */
6254 if (use_bigtile) x += j;
6256 /* Place the cursor */
6262 * Clipboard variables for copy&paste in visual mode
6264 static TERM_COLOR attr_idx = 0;
6265 static SYMBOL_CODE char_idx = 0;
6267 /* Hack -- for feature lighting */
6268 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
6269 static SYMBOL_CODE char_idx_feat[F_LIT_MAX];
6272 * Do visual mode command -- Change symbols
6274 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6275 int height, int width,
6276 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
6277 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
6279 static TERM_COLOR attr_old = 0;
6280 static SYMBOL_CODE char_old = 0;
6285 if (*visual_list_ptr)
6288 *cur_attr_ptr = attr_old;
6289 *cur_char_ptr = char_old;
6290 *visual_list_ptr = FALSE;
6298 if (*visual_list_ptr)
6301 *visual_list_ptr = FALSE;
6302 *need_redraw = TRUE;
6310 if (!*visual_list_ptr)
6312 *visual_list_ptr = TRUE;
6314 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6315 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6317 attr_old = *cur_attr_ptr;
6318 char_old = *cur_char_ptr;
6329 /* Set the visual */
6330 attr_idx = *cur_attr_ptr;
6331 char_idx = *cur_char_ptr;
6333 /* Hack -- for feature lighting */
6334 for (i = 0; i < F_LIT_MAX; i++)
6336 attr_idx_feat[i] = 0;
6337 char_idx_feat[i] = 0;
6344 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6347 *cur_attr_ptr = attr_idx;
6348 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6349 if (!*visual_list_ptr) *need_redraw = TRUE;
6355 *cur_char_ptr = char_idx;
6356 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6357 if (!*visual_list_ptr) *need_redraw = TRUE;
6363 if (*visual_list_ptr)
6366 int d = get_keymap_dir(ch);
6367 TERM_COLOR a = (*cur_attr_ptr & 0x7f);
6368 SYMBOL_CODE c = *cur_char_ptr;
6370 if (use_bigtile) eff_width = width / 2;
6371 else eff_width = width;
6373 /* Restrict direction */
6374 if ((a == 0) && (ddy[d] < 0)) d = 0;
6375 if ((c == 0) && (ddx[d] < 0)) d = 0;
6376 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6377 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6382 /* Force correct code for both ASCII character and tile */
6383 if (c & 0x80) a |= 0x80;
6385 /* Set the visual */
6390 /* Move the frame */
6391 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6392 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6393 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6394 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6400 /* Visual mode command is not used */
6406 * Display the monsters in a group.
6408 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6409 int mon_cur, int mon_top, bool visual_only)
6413 /* Display lines until done */
6414 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6418 /* Get the race index */
6419 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6421 /* Access the race */
6422 monster_race *r_ptr = &r_info[r_idx];
6424 /* Choose a color */
6425 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6427 /* Display the name */
6428 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6430 /* Hack -- visual_list mode */
6433 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6435 if (p_ptr->wizard || visual_only)
6437 c_prt(attr, format("%d", r_idx), row + i, 62);
6440 /* Erase chars before overwritten by the race letter */
6441 Term_erase(69, row + i, 255);
6443 /* Display symbol */
6444 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6449 if (!(r_ptr->flags1 & RF1_UNIQUE))
6450 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6452 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6453 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6457 /* Clear remaining lines */
6458 for (; i < per_page; i++)
6460 Term_erase(col, row + i, 255);
6466 * Display known monsters.
6468 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6472 IDX grp_cur, grp_top, old_grp_cur;
6473 IDX mon_cur, mon_top;
6474 IDX grp_cnt, grp_idx[100];
6482 bool visual_list = FALSE;
6483 TERM_COLOR attr_top = 0;
6491 Term_get_size(&wid, &hgt);
6493 browser_rows = hgt - 8;
6495 /* Allocate the "mon_idx" array */
6496 C_MAKE(mon_idx, max_r_idx, MONRACE_IDX);
6501 if (direct_r_idx < 0)
6503 mode = visual_only ? 0x03 : 0x01;
6505 /* Check every group */
6506 for (i = 0; monster_group_text[i] != NULL; i++)
6508 /* Measure the label */
6509 len = strlen(monster_group_text[i]);
6511 /* Save the maximum length */
6512 if (len > max) max = len;
6514 /* See if any monsters are known */
6515 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6517 /* Build a list of groups with known monsters */
6518 grp_idx[grp_cnt++] = i;
6526 mon_idx[0] = direct_r_idx;
6529 /* Terminate the list */
6532 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6533 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6536 /* Terminate the list */
6537 grp_idx[grp_cnt] = -1;
6540 grp_cur = grp_top = 0;
6541 mon_cur = mon_top = 0;
6546 mode = visual_only ? 0x02 : 0x00;
6551 monster_race *r_ptr;
6556 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
6557 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
6558 prt(_("名前", "Name"), 4, max + 3);
6559 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6560 prt(_("文字", "Sym"), 4, 67);
6561 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
6563 for (i = 0; i < 78; i++)
6565 Term_putch(i, 5, TERM_WHITE, '=');
6568 if (direct_r_idx < 0)
6570 for (i = 0; i < browser_rows; i++)
6572 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6579 if (direct_r_idx < 0)
6581 /* Scroll group list */
6582 if (grp_cur < grp_top) grp_top = grp_cur;
6583 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6585 /* Display a list of monster groups */
6586 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6588 if (old_grp_cur != grp_cur)
6590 old_grp_cur = grp_cur;
6592 /* Get a list of monsters in the current group */
6593 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6596 /* Scroll monster list */
6597 while (mon_cur < mon_top)
6598 mon_top = MAX(0, mon_top - browser_rows/2);
6599 while (mon_cur >= mon_top + browser_rows)
6600 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6605 /* Display a list of monsters in the current group */
6606 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6612 /* Display a monster name */
6613 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6615 /* Display visual list below first monster */
6616 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6620 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
6621 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
6622 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
6623 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
6626 /* Get the current monster */
6627 r_ptr = &r_info[mon_idx[mon_cur]];
6631 /* Mega Hack -- track this monster race */
6632 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6638 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6642 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6646 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6651 /* Do visual mode command if needed */
6652 if (visual_mode_command(ch, &visual_list, browser_rows-1, wid - (max + 3), &attr_top, &char_left, &r_ptr->x_attr, &r_ptr->x_char, need_redraw))
6654 if (direct_r_idx >= 0)
6679 /* Recall on screen */
6680 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6682 screen_roff(mon_idx[mon_cur], 0);
6693 /* Move the cursor */
6694 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6701 /* Free the "mon_idx" array */
6702 C_KILL(mon_idx, max_r_idx, MONRACE_IDX);
6707 * Display the objects in a group.
6709 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6710 int object_cur, int object_top, bool visual_only)
6714 /* Display lines until done */
6715 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6717 GAME_TEXT o_name[MAX_NLEN];
6720 object_kind *flavor_k_ptr;
6722 /* Get the object index */
6723 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6725 /* Access the object */
6726 object_kind *k_ptr = &k_info[k_idx];
6728 /* Choose a color */
6729 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6730 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6733 if (!visual_only && k_ptr->flavor)
6735 /* Appearance of this object is shuffled */
6736 flavor_k_ptr = &k_info[k_ptr->flavor];
6740 /* Appearance of this object is very normal */
6741 flavor_k_ptr = k_ptr;
6746 attr = ((i + object_top == object_cur) ? cursor : attr);
6748 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6751 strip_name(o_name, k_idx);
6756 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
6759 /* Display the name */
6760 c_prt(attr, o_name, row + i, col);
6762 /* Hack -- visual_list mode */
6765 c_prt(attr, format("%02x/%02x", flavor_k_ptr->x_attr, flavor_k_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 64 : 68);
6767 if (p_ptr->wizard || visual_only)
6769 c_prt(attr, format("%d", k_idx), row + i, 70);
6772 a = flavor_k_ptr->x_attr;
6773 c = flavor_k_ptr->x_char;
6775 /* Display symbol */
6776 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
6779 /* Clear remaining lines */
6780 for (; i < per_page; i++)
6782 Term_erase(col, row + i, 255);
6787 * Describe fake object
6789 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
6792 object_type object_type_body;
6793 o_ptr = &object_type_body;
6796 /* Create the artifact */
6797 object_prep(o_ptr, k_idx);
6799 /* It's fully know */
6800 o_ptr->ident |= IDENT_KNOWN;
6802 /* Track the object */
6803 /* object_actual_track(o_ptr); */
6805 /* Hack - mark as fake */
6806 /* term_obj_real = FALSE; */
6809 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
6811 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
6819 * Display known objects
6821 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
6825 IDX grp_cur, grp_top, old_grp_cur;
6826 IDX object_old, object_cur, object_top;
6830 OBJECT_IDX *object_idx;
6836 bool visual_list = FALSE;
6837 TERM_COLOR attr_top = 0;
6845 Term_get_size(&wid, &hgt);
6847 browser_rows = hgt - 8;
6849 /* Allocate the "object_idx" array */
6850 C_MAKE(object_idx, max_k_idx, KIND_OBJECT_IDX);
6855 if (direct_k_idx < 0)
6857 mode = visual_only ? 0x03 : 0x01;
6859 /* Check every group */
6860 for (i = 0; object_group_text[i] != NULL; i++)
6862 /* Measure the label */
6863 len = strlen(object_group_text[i]);
6865 /* Save the maximum length */
6866 if (len > max) max = len;
6868 /* See if any monsters are known */
6869 if (collect_objects(i, object_idx, mode))
6871 /* Build a list of groups with known monsters */
6872 grp_idx[grp_cnt++] = i;
6881 object_kind *k_ptr = &k_info[direct_k_idx];
6882 object_kind *flavor_k_ptr;
6884 if (!visual_only && k_ptr->flavor)
6886 /* Appearance of this object is shuffled */
6887 flavor_k_ptr = &k_info[k_ptr->flavor];
6891 /* Appearance of this object is very normal */
6892 flavor_k_ptr = k_ptr;
6895 object_idx[0] = direct_k_idx;
6896 object_old = direct_k_idx;
6899 /* Terminate the list */
6902 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6903 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
6906 /* Terminate the list */
6907 grp_idx[grp_cnt] = -1;
6910 grp_cur = grp_top = 0;
6911 object_cur = object_top = 0;
6916 mode = visual_only ? 0x02 : 0x00;
6921 object_kind *k_ptr, *flavor_k_ptr;
6928 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
6929 if (direct_k_idx < 0) prt("グループ", 4, 0);
6930 prt("名前", 4, max + 3);
6931 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6934 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6935 if (direct_k_idx < 0) prt("Group", 4, 0);
6936 prt("Name", 4, max + 3);
6937 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6941 for (i = 0; i < 78; i++)
6943 Term_putch(i, 5, TERM_WHITE, '=');
6946 if (direct_k_idx < 0)
6948 for (i = 0; i < browser_rows; i++)
6950 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6957 if (direct_k_idx < 0)
6959 /* Scroll group list */
6960 if (grp_cur < grp_top) grp_top = grp_cur;
6961 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6963 /* Display a list of object groups */
6964 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
6966 if (old_grp_cur != grp_cur)
6968 old_grp_cur = grp_cur;
6970 /* Get a list of objects in the current group */
6971 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
6974 /* Scroll object list */
6975 while (object_cur < object_top)
6976 object_top = MAX(0, object_top - browser_rows/2);
6977 while (object_cur >= object_top + browser_rows)
6978 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
6983 /* Display a list of objects in the current group */
6984 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
6988 object_top = object_cur;
6990 /* Display a list of objects in the current group */
6991 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
6993 /* Display visual list below first object */
6994 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6997 /* Get the current object */
6998 k_ptr = &k_info[object_idx[object_cur]];
7000 if (!visual_only && k_ptr->flavor)
7002 /* Appearance of this object is shuffled */
7003 flavor_k_ptr = &k_info[k_ptr->flavor];
7007 /* Appearance of this object is very normal */
7008 flavor_k_ptr = k_ptr;
7013 prt(format("<方向>%s%s%s, ESC",
7014 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
7015 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
7016 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
7019 prt(format("<dir>%s%s%s, ESC",
7020 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
7021 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
7022 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
7028 /* Mega Hack -- track this object */
7029 if (object_cnt) object_kind_track(object_idx[object_cur]);
7031 /* The "current" object changed */
7032 if (object_old != object_idx[object_cur])
7036 /* Remember the "current" object */
7037 object_old = object_idx[object_cur];
7043 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
7047 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7051 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
7056 /* Do visual mode command if needed */
7057 if (visual_mode_command(ch, &visual_list, browser_rows-1, wid - (max + 3), &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw))
7059 if (direct_k_idx >= 0)
7084 /* Recall on screen */
7085 if (!visual_list && !visual_only && (grp_cnt > 0))
7087 desc_obj_fake(object_idx[object_cur]);
7095 /* Move the cursor */
7096 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
7102 /* Free the "object_idx" array */
7103 C_KILL(object_idx, max_k_idx, KIND_OBJECT_IDX);
7108 * Display the features in a group.
7110 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
7111 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
7113 int lit_col[F_LIT_MAX], i, j;
7114 int f_idx_col = use_bigtile ? 62 : 64;
7116 /* Correct columns 1 and 4 */
7117 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
7118 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7119 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
7121 /* Display lines until done */
7122 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
7127 FEAT_IDX f_idx = feat_idx[feat_top + i];
7129 /* Access the index */
7130 feature_type *f_ptr = &f_info[f_idx];
7132 int row_i = row + i;
7134 /* Choose a color */
7135 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
7137 /* Display the name */
7138 c_prt(attr, f_name + f_ptr->name, row_i, col);
7140 /* Hack -- visual_list mode */
7143 /* Display lighting level */
7144 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
7146 c_prt(attr, format("%02x/%02x", f_ptr->x_attr[lighting_level], f_ptr->x_char[lighting_level]), row_i, f_idx_col - ((p_ptr->wizard || visual_only) ? 6 : 2));
7148 if (p_ptr->wizard || visual_only)
7150 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7153 /* Display symbol */
7154 Term_queue_bigchar(lit_col[F_LIT_STANDARD], row_i, f_ptr->x_attr[F_LIT_STANDARD], f_ptr->x_char[F_LIT_STANDARD], 0, 0);
7156 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7157 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7159 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7161 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7163 /* Mega-hack -- Use non-standard colour */
7164 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7166 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7170 /* Clear remaining lines */
7171 for (; i < per_page; i++)
7173 Term_erase(col, row + i, 255);
7179 * Interact with feature visuals.
7181 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7185 FEAT_IDX grp_cur, grp_top, old_grp_cur;
7186 FEAT_IDX feat_cur, feat_top;
7188 FEAT_IDX grp_idx[100];
7192 TERM_LEN column = 0;
7196 bool visual_list = FALSE;
7197 TERM_COLOR attr_top = 0;
7200 TERM_LEN browser_rows;
7203 TERM_COLOR attr_old[F_LIT_MAX];
7204 SYMBOL_CODE char_old[F_LIT_MAX];
7205 TERM_COLOR *cur_attr_ptr;
7206 SYMBOL_CODE *cur_char_ptr;
7208 (void)C_WIPE(attr_old, F_LIT_MAX, TERM_COLOR);
7209 (void)C_WIPE(char_old, F_LIT_MAX, SYMBOL_CODE);
7211 Term_get_size(&wid, &hgt);
7213 browser_rows = hgt - 8;
7215 /* Allocate the "feat_idx" array */
7216 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
7221 if (direct_f_idx < 0)
7223 /* Check every group */
7224 for (i = 0; feature_group_text[i] != NULL; i++)
7226 /* Measure the label */
7227 len = strlen(feature_group_text[i]);
7229 /* Save the maximum length */
7230 if (len > max) max = len;
7232 /* See if any features are known */
7233 if (collect_features(i, feat_idx, 0x01))
7235 /* Build a list of groups with known features */
7236 grp_idx[grp_cnt++] = i;
7244 feature_type *f_ptr = &f_info[direct_f_idx];
7246 feat_idx[0] = direct_f_idx;
7249 /* Terminate the list */
7252 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7253 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7255 for (i = 0; i < F_LIT_MAX; i++)
7257 attr_old[i] = f_ptr->x_attr[i];
7258 char_old[i] = f_ptr->x_char[i];
7262 /* Terminate the list */
7263 grp_idx[grp_cnt] = -1;
7266 grp_cur = grp_top = 0;
7267 feat_cur = feat_top = 0;
7275 feature_type *f_ptr;
7281 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
7282 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
7283 prt(_("名前", "Name"), 4, max + 3);
7286 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7287 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
7291 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7292 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
7295 for (i = 0; i < 78; i++)
7297 Term_putch(i, 5, TERM_WHITE, '=');
7300 if (direct_f_idx < 0)
7302 for (i = 0; i < browser_rows; i++)
7304 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7311 if (direct_f_idx < 0)
7313 /* Scroll group list */
7314 if (grp_cur < grp_top) grp_top = grp_cur;
7315 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7317 /* Display a list of feature groups */
7318 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7320 if (old_grp_cur != grp_cur)
7322 old_grp_cur = grp_cur;
7324 /* Get a list of features in the current group */
7325 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7328 /* Scroll feature list */
7329 while (feat_cur < feat_top)
7330 feat_top = MAX(0, feat_top - browser_rows/2);
7331 while (feat_cur >= feat_top + browser_rows)
7332 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7337 /* Display a list of features in the current group */
7338 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7342 feat_top = feat_cur;
7344 /* Display a list of features in the current group */
7345 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7347 /* Display visual list below first object */
7348 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7352 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
7353 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
7354 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
7357 /* Get the current feature */
7358 f_ptr = &f_info[feat_idx[feat_cur]];
7359 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7360 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7364 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7368 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7372 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7377 if (visual_list && ((ch == 'A') || (ch == 'a')))
7379 int prev_lighting_level = *lighting_level;
7383 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7384 else (*lighting_level)--;
7388 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7389 else (*lighting_level)++;
7392 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7393 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7395 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7396 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7401 else if ((ch == 'D') || (ch == 'd'))
7403 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
7404 byte prev_x_char = f_ptr->x_char[*lighting_level];
7406 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7410 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7411 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7413 if (prev_x_char != f_ptr->x_char[*lighting_level])
7414 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7416 else *need_redraw = TRUE;
7421 /* Do visual mode command if needed */
7422 else if (visual_mode_command(ch, &visual_list, browser_rows-1, wid - (max + 3), &attr_top, &char_left, cur_attr_ptr, cur_char_ptr, need_redraw))
7426 /* Restore previous visual settings */
7428 for (i = 0; i < F_LIT_MAX; i++)
7430 f_ptr->x_attr[i] = attr_old[i];
7431 f_ptr->x_char[i] = char_old[i];
7438 if (direct_f_idx >= 0) flag = TRUE;
7439 else *lighting_level = F_LIT_STANDARD;
7442 /* Preserve current visual settings */
7445 for (i = 0; i < F_LIT_MAX; i++)
7447 attr_old[i] = f_ptr->x_attr[i];
7448 char_old[i] = f_ptr->x_char[i];
7450 *lighting_level = F_LIT_STANDARD;
7457 for (i = 0; i < F_LIT_MAX; i++)
7459 attr_idx_feat[i] = f_ptr->x_attr[i];
7460 char_idx_feat[i] = f_ptr->x_char[i];
7469 /* Allow TERM_DARK text */
7470 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7472 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7473 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7491 /* Move the cursor */
7492 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7498 /* Free the "feat_idx" array */
7499 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
7504 * List wanted monsters
7506 static void do_cmd_knowledge_kubi(void)
7511 GAME_TEXT file_name[1024];
7514 /* Open a new file */
7515 fff = my_fopen_temp(file_name, 1024);
7517 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7524 bool listed = FALSE;
7526 fprintf(fff, _("今日のターゲット : %s\n", "Today target : %s\n"),
7527 (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : _("不明", "unknown")));
7529 fprintf(fff, _("賞金首リスト\n", "List of wanted monsters\n"));
7530 fprintf(fff, "----------------------------------------------\n");
7532 for (i = 0; i < MAX_KUBI; i++)
7534 if (kubi_r_idx[i] <= 10000)
7536 fprintf(fff,"%s\n", r_name + r_info[kubi_r_idx[i]].name);
7544 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7549 /* Display the file contents */
7550 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7552 /* Remove the file */
7557 * List virtues & status
7559 static void do_cmd_knowledge_virtues(void)
7562 GAME_TEXT file_name[1024];
7564 /* Open a new file */
7565 fff = my_fopen_temp(file_name, 1024);
7567 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7574 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7579 /* Display the file contents */
7580 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7582 /* Remove the file */
7589 static void do_cmd_knowledge_dungeon(void)
7593 GAME_TEXT file_name[1024];
7596 /* Open a new file */
7597 fff = my_fopen_temp(file_name, 1024);
7599 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7606 for (i = 1; i < max_d_idx; i++)
7610 if (!d_info[i].maxdepth) continue;
7611 if (!max_dlv[i]) continue;
7612 if (d_info[i].final_guardian)
7614 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7616 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7618 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7623 /* Display the file contents */
7624 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7626 /* Remove the file */
7631 * List virtues & status
7634 static void do_cmd_knowledge_stat(void)
7638 GAME_TEXT file_name[1024];
7641 /* Open a new file */
7642 fff = my_fopen_temp(file_name, 1024);
7644 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7651 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7652 (2 * p_ptr->hitdie +
7653 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7655 if (p_ptr->knowledge & KNOW_HPRATE)
7656 fprintf(fff, _("現在の体力ランク : %d/100\n\n", "Your current Life Rating is %d/100.\n\n"), percent);
7657 else fprintf(fff, _("現在の体力ランク : ???\n\n", "Your current Life Rating is ???.\n\n"));
7659 fprintf(fff, _("能力の最大値\n\n", "Limits of maximum stats\n\n"));
7660 for (v_nr = 0; v_nr < A_MAX; v_nr++)
7662 if ((p_ptr->knowledge & KNOW_STAT) || p_ptr->stat_max[v_nr] == p_ptr->stat_max_max[v_nr]) fprintf(fff, "%s 18/%d\n", stat_names[v_nr], p_ptr->stat_max_max[v_nr]-18);
7663 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7670 /* Display the file contents */
7671 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7673 /* Remove the file */
7679 * Print all active quests
7681 static void do_cmd_knowledge_quests_current(FILE *fff)
7684 char rand_tmp_str[120] = "\0";
7685 GAME_TEXT name[MAX_NLEN];
7686 monster_race *r_ptr;
7688 int rand_level = 100;
7691 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7693 for (i = 1; i < max_q_idx; i++)
7695 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7696 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7697 (quest[i].status == QUEST_STATUS_COMPLETED))
7699 /* Set the quest number temporary */
7700 QUEST_IDX old_quest = p_ptr->inside_quest;
7703 /* Clear the text */
7704 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7705 quest_text_line = 0;
7707 p_ptr->inside_quest = i;
7709 /* Get the quest text */
7710 init_flags = INIT_SHOW_TEXT;
7712 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7714 /* Reset the old quest number */
7715 p_ptr->inside_quest = old_quest;
7717 /* No info from "silent" quests */
7718 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7722 if (quest[i].type != QUEST_TYPE_RANDOM)
7724 char note[80] = "\0";
7726 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
7728 switch (quest[i].type)
7730 case QUEST_TYPE_KILL_LEVEL:
7731 case QUEST_TYPE_KILL_ANY_LEVEL:
7732 r_ptr = &r_info[quest[i].r_idx];
7733 strcpy(name, r_name + r_ptr->name);
7734 if (quest[i].max_num > 1)
7737 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
7738 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7741 sprintf(note," - kill %d %s, have killed %d.",
7742 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7746 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
7749 case QUEST_TYPE_FIND_ARTIFACT:
7752 artifact_type *a_ptr = &a_info[quest[i].k_idx];
7754 object_type *q_ptr = &forge;
7755 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
7756 object_prep(q_ptr, k_idx);
7757 q_ptr->name1 = quest[i].k_idx;
7758 q_ptr->ident = IDENT_STORE;
7759 object_desc(name, q_ptr, OD_NAME_ONLY);
7761 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find out %s."), name);
7763 case QUEST_TYPE_FIND_EXIT:
7764 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
7767 case QUEST_TYPE_KILL_NUMBER:
7769 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
7770 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
7772 sprintf(note," - Kill %d monsters, have killed %d.",
7773 (int)quest[i].max_num, (int)quest[i].cur_num);
7777 case QUEST_TYPE_KILL_ALL:
7778 case QUEST_TYPE_TOWER:
7779 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
7784 /* Print the quest info */
7785 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
7786 quest[i].name, (int)quest[i].level, note);
7788 fputs(tmp_str, fff);
7790 if (quest[i].status == QUEST_STATUS_COMPLETED)
7792 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
7793 fputs(tmp_str, fff);
7799 while (quest_text[j][0] && j < 10)
7801 fprintf(fff, " %s\n", quest_text[j]);
7806 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
7809 rand_level = quest[i].level;
7811 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
7813 /* Print the quest info */
7814 r_ptr = &r_info[quest[i].r_idx];
7815 strcpy(name, r_name + r_ptr->name);
7817 if (quest[i].max_num > 1)
7820 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
7821 quest[i].name, (int)quest[i].level,
7822 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7826 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
7827 quest[i].name, (int)quest[i].level,
7828 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7833 sprintf(rand_tmp_str,_(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
7834 quest[i].name, (int)quest[i].level, name);
7841 /* Print the current random quest */
7842 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
7844 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7848 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
7851 char playtime_str[16];
7852 quest_type* const q_ptr = &quest[q_idx];
7854 if (is_fixed_quest_idx(q_idx))
7856 /* Set the quest number temporary */
7857 IDX old_quest = p_ptr->inside_quest;
7859 p_ptr->inside_quest = q_idx;
7862 init_flags = INIT_NAME_ONLY;
7864 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7866 /* Reset the old quest number */
7867 p_ptr->inside_quest = old_quest;
7869 /* No info from "silent" quests */
7870 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
7873 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
7874 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
7876 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
7878 /* Print the quest info */
7879 if (q_ptr->complev == 0)
7882 _(" %-35s (%3d階) - 不戦勝 - %s\n",
7883 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
7884 r_name+r_info[q_ptr->r_idx].name,
7885 (int)q_ptr->level, playtime_str);
7890 _(" %-35s (%3d階) - レベル%2d - %s\n",
7891 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
7892 r_name+r_info[q_ptr->r_idx].name,
7900 /* Print the quest info */
7902 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
7903 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
7904 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
7907 fputs(tmp_str, fff);
7913 * Print all finished quests
7915 void do_cmd_knowledge_quests_completed(FILE *fff, QUEST_IDX quest_num[])
7918 QUEST_IDX total = 0;
7920 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
7921 for (i = 1; i < max_q_idx; i++)
7923 QUEST_IDX q_idx = quest_num[i];
7924 quest_type* const q_ptr = &quest[q_idx];
7926 if (q_ptr->status == QUEST_STATUS_FINISHED && do_cmd_knowledge_quests_aux(fff, q_idx))
7931 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7936 * Print all failed quests
7938 void do_cmd_knowledge_quests_failed(FILE *fff, QUEST_IDX quest_num[])
7941 QUEST_IDX total = 0;
7943 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
7944 for (i = 1; i < max_q_idx; i++)
7946 QUEST_IDX q_idx = quest_num[i];
7947 quest_type* const q_ptr = &quest[q_idx];
7949 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
7950 do_cmd_knowledge_quests_aux(fff, q_idx))
7955 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7960 * Print all random quests
7962 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
7964 GAME_TEXT tmp_str[120];
7966 QUEST_IDX total = 0;
7968 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
7969 for (i = 1; i < max_q_idx; i++)
7971 /* No info from "silent" quests */
7972 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7974 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
7978 /* Print the quest info */
7979 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
7980 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
7981 fputs(tmp_str, fff);
7984 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7988 bool ang_sort_comp_quest_num(vptr u, vptr v, int a, int b)
7990 QUEST_IDX *q_num = (QUEST_IDX *)u;
7991 quest_type *qa = &quest[q_num[a]];
7992 quest_type *qb = &quest[q_num[b]];
7997 return (qa->comptime != qb->comptime) ?
7998 (qa->comptime < qb->comptime) :
7999 (qa->level <= qb->level);
8002 void ang_sort_swap_quest_num(vptr u, vptr v, int a, int b)
8004 QUEST_IDX *q_num = (QUEST_IDX *)u;
8011 q_num[a] = q_num[b];
8017 * Print quest status of all active quests
8019 static void do_cmd_knowledge_quests(void)
8022 GAME_TEXT file_name[1024];
8027 /* Open a new file */
8028 fff = my_fopen_temp(file_name, 1024);
8031 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8036 /* Allocate Memory */
8037 C_MAKE(quest_num, max_q_idx, QUEST_IDX);
8039 /* Sort by compete level */
8040 for (i = 1; i < max_q_idx; i++) quest_num[i] = i;
8041 ang_sort_comp = ang_sort_comp_quest_num;
8042 ang_sort_swap = ang_sort_swap_quest_num;
8043 ang_sort(quest_num, &dummy, max_q_idx);
8045 /* Dump Quest Information */
8046 do_cmd_knowledge_quests_current(fff);
8048 do_cmd_knowledge_quests_completed(fff, quest_num);
8050 do_cmd_knowledge_quests_failed(fff, quest_num);
8054 do_cmd_knowledge_quests_wiz_random(fff);
8058 /* Display the file contents */
8059 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
8061 /* Remove the file */
8065 C_KILL(quest_num, max_q_idx, QUEST_IDX);
8072 static void do_cmd_knowledge_home(void)
8077 GAME_TEXT file_name[1024];
8079 GAME_TEXT o_name[MAX_NLEN];
8080 concptr paren = ")";
8082 process_dungeon_file("w_info.txt", 0, 0, max_wild_y, max_wild_x);
8084 /* Open a new file */
8085 fff = my_fopen_temp(file_name, 1024);
8087 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8094 /* Print all homes in the different towns */
8095 st_ptr = &town[1].store[STORE_HOME];
8097 /* Home -- if anything there */
8098 if (st_ptr->stock_num)
8103 /* Header with name of the town */
8104 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
8106 /* Dump all available items */
8107 for (i = 0; i < st_ptr->stock_num; i++)
8110 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
8111 object_desc(o_name, &st_ptr->stock[i], 0);
8112 if (strlen(o_name) <= 80-3)
8114 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8120 for (n = 0, t = o_name; n < 80-3; n++, t++)
8121 if(iskanji(*t)) {t++; n++;}
8122 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
8124 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
8125 fprintf(fff, " %.77s\n", o_name+n);
8128 object_desc(o_name, &st_ptr->stock[i], 0);
8129 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8134 /* Add an empty line */
8135 fprintf(fff, "\n\n");
8140 /* Display the file contents */
8141 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
8143 /* Remove the file */
8149 * Check the status of "autopick"
8151 static void do_cmd_knowledge_autopick(void)
8155 GAME_TEXT file_name[1024];
8157 /* Open a new file */
8158 fff = my_fopen_temp(file_name, 1024);
8162 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8169 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
8173 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
8174 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
8177 for (k = 0; k < max_autopick; k++)
8180 byte act = autopick_list[k].action;
8181 if (act & DONT_AUTOPICK)
8183 tmp = _("放置", "Leave");
8185 else if (act & DO_AUTODESTROY)
8187 tmp = _("破壊", "Destroy");
8189 else if (act & DO_AUTOPICK)
8191 tmp = _("拾う", "Pickup");
8195 tmp = _("確認", "Query");
8198 if (act & DO_DISPLAY)
8199 fprintf(fff, "%11s", format("[%s]", tmp));
8201 fprintf(fff, "%11s", format("(%s)", tmp));
8203 tmp = autopick_line_from_entry(&autopick_list[k]);
8204 fprintf(fff, " %s", tmp);
8209 /* Display the file contents */
8210 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8212 /* Remove the file */
8218 * Interact with "knowledge"
8220 void do_cmd_knowledge(void)
8223 bool need_redraw = FALSE;
8225 /* File type is "TEXT" */
8226 FILE_TYPE(FILE_TYPE_TEXT);
8229 /* Interact until done */
8234 /* Ask for a choice */
8235 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
8236 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
8238 /* Give some choices */
8242 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8243 prt("(2) 既知のアイテム の一覧", 7, 5);
8244 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8245 prt("(4) 既知のモンスター の一覧", 9, 5);
8246 prt("(5) 倒した敵の数 の一覧", 10, 5);
8247 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8248 prt("(7) 現在のペット の一覧", 12, 5);
8249 prt("(8) 我が家のアイテム の一覧", 13, 5);
8250 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8251 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8255 prt("(a) 自分に関する情報 の一覧", 6, 5);
8256 prt("(b) 突然変異 の一覧", 7, 5);
8257 prt("(c) 武器の経験値 の一覧", 8, 5);
8258 prt("(d) 魔法の経験値 の一覧", 9, 5);
8259 prt("(e) 技能の経験値 の一覧", 10, 5);
8260 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8261 prt("(g) 入ったダンジョン の一覧", 12, 5);
8262 prt("(h) 実行中のクエスト の一覧", 13, 5);
8263 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8268 prt("(1) Display known artifacts", 6, 5);
8269 prt("(2) Display known objects", 7, 5);
8270 prt("(3) Display remaining uniques", 8, 5);
8271 prt("(4) Display known monster", 9, 5);
8272 prt("(5) Display kill count", 10, 5);
8273 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8274 prt("(7) Display current pets", 12, 5);
8275 prt("(8) Display home inventory", 13, 5);
8276 prt("(9) Display *identified* equip.", 14, 5);
8277 prt("(0) Display terrain symbols.", 15, 5);
8281 prt("(a) Display about yourself", 6, 5);
8282 prt("(b) Display mutations", 7, 5);
8283 prt("(c) Display weapon proficiency", 8, 5);
8284 prt("(d) Display spell proficiency", 9, 5);
8285 prt("(e) Display misc. proficiency", 10, 5);
8286 prt("(f) Display virtues", 11, 5);
8287 prt("(g) Display dungeons", 12, 5);
8288 prt("(h) Display current quests", 13, 5);
8289 prt("(i) Display auto pick/destroy", 14, 5);
8293 prt(_("-続く-", "-more-"), 17, 8);
8294 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
8295 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
8296 /*prt("-) 前ページ", 21, 60);*/
8297 prt(_("コマンド:", "Command: "), 20, 0);
8300 if (i == ESCAPE) break;
8303 case ' ': /* Page change */
8307 case '1': /* Artifacts */
8308 do_cmd_knowledge_artifacts();
8310 case '2': /* Objects */
8311 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8313 case '3': /* Uniques */
8314 do_cmd_knowledge_uniques();
8316 case '4': /* Monsters */
8317 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8319 case '5': /* Kill count */
8320 do_cmd_knowledge_kill_count();
8322 case '6': /* wanted */
8323 if (!vanilla_town) do_cmd_knowledge_kubi();
8325 case '7': /* Pets */
8326 do_cmd_knowledge_pets();
8328 case '8': /* Home */
8329 do_cmd_knowledge_home();
8331 case '9': /* Resist list */
8332 do_cmd_knowledge_inven();
8334 case '0': /* Feature list */
8336 IDX lighting_level = F_LIT_STANDARD;
8337 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8341 case 'a': /* Max stat */
8342 do_cmd_knowledge_stat();
8344 case 'b': /* Mutations */
8345 do_cmd_knowledge_mutations();
8347 case 'c': /* weapon-exp */
8348 do_cmd_knowledge_weapon_exp();
8350 case 'd': /* spell-exp */
8351 do_cmd_knowledge_spell_exp();
8353 case 'e': /* skill-exp */
8354 do_cmd_knowledge_skill_exp();
8356 case 'f': /* Virtues */
8357 do_cmd_knowledge_virtues();
8359 case 'g': /* Dungeon */
8360 do_cmd_knowledge_dungeon();
8362 case 'h': /* Quests */
8363 do_cmd_knowledge_quests();
8365 case 'i': /* Autopick */
8366 do_cmd_knowledge_autopick();
8368 default: /* Unknown option */
8376 if (need_redraw) do_cmd_redraw();
8381 * Check on the status of an active quest
8383 void do_cmd_checkquest(void)
8385 /* File type is "TEXT" */
8386 FILE_TYPE(FILE_TYPE_TEXT);
8390 do_cmd_knowledge_quests();
8396 * Display the time and date
8398 void do_cmd_time(void)
8400 int day, hour, min, full, start, end, num;
8408 extract_day_hour_min(&day, &hour, &min);
8410 full = hour * 100 + min;
8417 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8419 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8420 else strcpy(day_buf, "*****");
8422 msg_format(_("%s日目, 時刻は%d:%02d %sです。", "This is day %s. The time is %d:%02d %s."),
8423 day_buf, (hour % 12 == 0) ? 12 : (hour % 12), min, (hour < 12) ? "AM" : "PM");
8426 if (!randint0(10) || p_ptr->image)
8428 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8432 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8435 /* Open this file */
8436 fff = my_fopen(buf, "rt");
8440 /* Find this time */
8441 while (!my_fgets(fff, buf, sizeof(buf)))
8443 /* Ignore comments */
8444 if (!buf[0] || (buf[0] == '#')) continue;
8446 /* Ignore invalid lines */
8447 if (buf[1] != ':') continue;
8449 /* Process 'Start' */
8452 /* Extract the starting time */
8453 start = atoi(buf + 2);
8455 /* Assume valid for an hour */
8465 /* Extract the ending time */
8466 end = atoi(buf + 2);
8472 /* Ignore incorrect range */
8473 if ((start > full) || (full > end)) continue;
8475 /* Process 'Description' */
8480 /* Apply the randomizer */
8481 if (!randint0(num)) strcpy(desc, buf + 2);