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"
52 * Mark strings for auto dump
54 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
55 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
58 * Variables for auto dump
60 static FILE *auto_dump_stream;
61 static cptr auto_dump_mark;
62 static int auto_dump_line_num;
66 * @brief prf出力内容を消去する /
67 * Remove old lines automatically generated before.
68 * @param orig_file 消去を行うファイル名
70 static void remove_auto_dump(cptr orig_file)
72 FILE *tmp_fff, *orig_fff;
76 bool between_mark = FALSE;
79 long header_location = 0;
80 char header_mark_str[80];
81 char footer_mark_str[80];
84 /* Prepare a header/footer mark string */
85 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
86 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
88 mark_len = strlen(footer_mark_str);
90 /* Open an old dump file in read-only mode */
91 orig_fff = my_fopen(orig_file, "r");
93 /* If original file does not exist, nothing to do */
94 if (!orig_fff) return;
96 /* Open a new (temporary) file */
97 tmp_fff = my_fopen_temp(tmp_file, 1024);
101 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
106 /* Loop for every line */
110 if (my_fgets(orig_fff, buf, sizeof(buf)))
112 /* Read error: Assume End of File */
115 * Was looking for the footer, but not found.
117 * Since automatic dump might be edited by hand,
118 * it's dangerous to kill these lines.
119 * Seek back to the next line of the (pseudo) header,
124 fseek(orig_fff, header_location, SEEK_SET);
125 between_mark = FALSE;
129 /* Success -- End the loop */
136 /* We are looking for the header mark of automatic dump */
139 /* Is this line a header? */
140 if (!strcmp(buf, header_mark_str))
142 /* Memorise seek point of this line */
143 header_location = ftell(orig_fff);
145 /* Initialize counter for number of lines */
148 /* Look for the footer from now */
151 /* There are some changes */
158 /* Copy orginally lines */
159 fprintf(tmp_fff, "%s\n", buf);
163 /* We are looking for the footer mark of automatic dump */
166 /* Is this line a footer? */
167 if (!strncmp(buf, footer_mark_str, mark_len))
172 * Compare the number of lines
174 * If there is an inconsistency between
175 * actual number of lines and the
176 * number here, the automatic dump
177 * might be edited by hand. So it's
178 * dangerous to kill these lines.
179 * Seek back to the next line of the
180 * (pseudo) header, and read again.
182 if (!sscanf(buf + mark_len, " (%d)", &tmp)
185 fseek(orig_fff, header_location, SEEK_SET);
188 /* Look for another header */
189 between_mark = FALSE;
195 /* Ignore old line, and count number of lines */
205 /* If there are some changes, overwrite the original file with new one */
208 /* Copy contents of temporary file */
210 tmp_fff = my_fopen(tmp_file, "r");
211 orig_fff = my_fopen(orig_file, "w");
213 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
214 fprintf(orig_fff, "%s\n", buf);
220 /* Kill the temporary file */
228 * @brief prfファイルのフォーマットに従った内容を出力する /
229 * Dump a formatted line, using "vstrnfmt()".
232 static void auto_dump_printf(cptr fmt, ...)
239 /* Begin the Varargs Stuff */
242 /* Format the args, save the length */
243 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
245 /* End the Varargs Stuff */
248 /* Count number of lines */
249 for (p = buf; *p; p++)
251 if (*p == '\n') auto_dump_line_num++;
255 fprintf(auto_dump_stream, "%s", buf);
260 * @brief prfファイルをファイルオープンする /
261 * Open file to append auto dump.
263 * @param mark 出力するヘッダマーク
264 * @return ファイルポインタを取得できたらTRUEを返す
266 static bool open_auto_dump(cptr buf, cptr mark)
269 char header_mark_str[80];
271 /* Save the mark string */
272 auto_dump_mark = mark;
274 /* Prepare a header mark string */
275 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
277 /* Remove old macro dumps */
278 remove_auto_dump(buf);
280 /* Append to the file */
281 auto_dump_stream = my_fopen(buf, "a");
284 if (!auto_dump_stream) {
285 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
293 fprintf(auto_dump_stream, "%s\n", header_mark_str);
295 /* Initialize counter */
296 auto_dump_line_num = 0;
298 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
299 "# *Warning!* The lines below are an automatic dump.\n"));
300 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
301 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
307 * @brief prfファイルをファイルクローズする /
308 * Append foot part and close auto dump.
311 static void close_auto_dump(void)
313 char footer_mark_str[80];
315 /* Prepare a footer mark string */
316 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
318 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
319 "# *Warning!* The lines below are an automatic dump.\n"));
320 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
321 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
323 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
326 my_fclose(auto_dump_stream);
335 * @brief Return suffix of ordinal number
337 * @return pointer of suffix string.
339 cptr get_ordinal_number_suffix(int num)
341 num = ABS(num) % 100;
345 return (num == 11) ? "th" : "st";
347 return (num == 12) ? "th" : "nd";
349 return (num == 13) ? "th" : "rd";
358 * @brief 日記にメッセージを追加する /
359 * Take note to the diary.
360 * @param type 日記内容のID
361 * @param num 日記内容のIDに応じた数値
362 * @param note 日記内容のIDに応じた文字列参照ポインタ
365 errr do_cmd_write_nikki(int type, int num, cptr note)
369 GAME_TEXT file_name[MAX_NLEN];
371 cptr note_level = "";
372 bool do_level = TRUE;
373 char note_level_buf[40];
376 static bool disable_nikki = FALSE;
378 extract_day_hour_min(&day, &hour, &min);
380 if (disable_nikki) return(-1);
382 if (type == NIKKI_FIX_QUEST_C ||
383 type == NIKKI_FIX_QUEST_F ||
384 type == NIKKI_RAND_QUEST_C ||
385 type == NIKKI_RAND_QUEST_F ||
386 type == NIKKI_TO_QUEST)
390 old_quest = p_ptr->inside_quest;
391 p_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
393 /* Get the quest text */
394 init_flags = INIT_NAME_ONLY;
396 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
398 /* Reset the old quest number */
399 p_ptr->inside_quest = old_quest;
402 /* different filne name to avoid mixing */
403 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
405 /* Build the filename */
406 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
408 /* File type is "TEXT" */
409 FILE_TYPE(FILE_TYPE_TEXT);
411 fff = my_fopen(buf, "a");
416 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporally."), buf);
422 q_idx = quest_number(dun_level);
426 if (p_ptr->inside_arena)
427 note_level = _("アリーナ:", "Arane:");
429 note_level = _("地上:", "Surface:");
430 else if (q_idx && (is_fixed_quest_idx(q_idx)
431 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
432 note_level = _("クエスト:", "Quest:");
436 sprintf(note_level_buf, "%d階(%s):", (int)dun_level, d_name+d_info[dungeon_type].name);
438 sprintf(note_level_buf, "%s L%d:", d_name+d_info[dungeon_type].name, (int)dun_level);
440 note_level = note_level_buf;
448 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
449 else fputs(_("*****日目\n", "Day *****\n"), fff);
457 fprintf(fff, "%s\n",note);
461 fprintf(fff, " %2d:%02d %20s %s\n",hour, min, note_level, note);
466 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
469 case NIKKI_ART_SCROLL:
471 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
476 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
479 case NIKKI_FIX_QUEST_C:
481 if (quest[num].flags & QUEST_FLAG_SILENT) break;
482 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
483 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
486 case NIKKI_FIX_QUEST_F:
488 if (quest[num].flags & QUEST_FLAG_SILENT) break;
489 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
490 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
493 case NIKKI_RAND_QUEST_C:
495 GAME_TEXT name[MAX_NLEN];
496 strcpy(name, r_name+r_info[quest[num].r_idx].name);
497 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
498 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
501 case NIKKI_RAND_QUEST_F:
503 GAME_TEXT name[MAX_NLEN];
504 strcpy(name, r_name+r_info[quest[num].r_idx].name);
505 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
506 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
509 case NIKKI_MAXDEAPTH:
511 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
512 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
513 _(d_name+d_info[dungeon_type].name, num),
514 _(num, d_name+d_info[dungeon_type].name));
519 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
520 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
521 _(d_name + d_info[num].name, (int)max_dlv[num]),
522 _((int)max_dlv[num], d_name + d_info[num].name));
528 if (q_idx && (is_fixed_quest_idx(q_idx)
529 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
531 to = _("地上", "the surface");
535 if (!(dun_level+num)) to = _("地上", "the surface");
536 else to = format(_("%d階", "level %d"), dun_level+num);
538 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
544 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
545 hour, min, note_level, _(d_name+d_info[dungeon_type].name, (int)max_dlv[dungeon_type]),
546 _((int)max_dlv[dungeon_type], d_name+d_info[dungeon_type].name));
548 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
553 if (quest[num].flags & QUEST_FLAG_SILENT) break;
554 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
555 hour, min, note_level, quest[num].name);
560 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
561 hour, min, note_level);
566 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
571 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
579 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
580 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
583 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
584 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
586 if (num == MAX_ARENA_MONS)
588 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
589 " won all fight to become a Chanpion.\n"));
596 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
603 to = _("地上", "the surface");
605 to = format(_("%d階(%s)", "level %d of %s"), dun_level, d_name+d_info[dungeon_type].name);
607 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
608 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
615 to = _("地上", "the surface");
617 to = format(_("%d階(%s)", "level %d of %s"), dun_level, d_name+d_info[dungeon_type].name);
619 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
620 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
625 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
628 case NIKKI_GAMESTART:
630 time_t ct = time((time_t*)0);
634 fprintf(fff, "%s %s",note, ctime(&ct));
637 fprintf(fff, " %2d:%02d %20s %s %s",hour, min, note_level, note, ctime(&ct));
640 case NIKKI_NAMED_PET:
642 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
645 case RECORD_NAMED_PET_NAME:
646 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
648 case RECORD_NAMED_PET_UNNAME:
649 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
651 case RECORD_NAMED_PET_DISMISS:
652 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
654 case RECORD_NAMED_PET_DEATH:
655 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
657 case RECORD_NAMED_PET_MOVED:
658 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
660 case RECORD_NAMED_PET_LOST_SIGHT:
661 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
663 case RECORD_NAMED_PET_DESTROY:
664 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was made disappeared by *destruction*.\n"), note);
666 case RECORD_NAMED_PET_EARTHQUAKE:
667 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
669 case RECORD_NAMED_PET_GENOCIDE:
670 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was made disappeared by genocide.\n"), note);
672 case RECORD_NAMED_PET_WIZ_ZAP:
673 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
675 case RECORD_NAMED_PET_TELE_LEVEL:
676 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was made disappeared by teleport level.\n"), note);
678 case RECORD_NAMED_PET_BLAST:
679 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
681 case RECORD_NAMED_PET_HEAL_LEPER:
682 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
684 case RECORD_NAMED_PET_COMPACT:
685 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was made disappeared by compacting monsters.\n"), note);
687 case RECORD_NAMED_PET_LOSE_PARENT:
688 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because there does not exist summoner.\n"), note);
699 case NIKKI_WIZARD_LOG:
700 fprintf(fff, "%s\n", note);
709 if (do_level) write_level = FALSE;
715 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
718 * @brief 日記のタイトル表記と内容出力 /
721 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
723 static void do_cmd_disp_nikki(void)
725 char nikki_title[256];
726 GAME_TEXT file_name[MAX_NLEN];
731 static const char subtitle[][30] = {"最強の肉体を求めて",
762 static const char subtitle[][51] ={"Quest of The World's Toughest Body",
763 "Attack is the best form of defence.",
765 "An unexpected windfall",
766 "A drowning man will catch at a straw",
767 "Don't count your chickens before they are hatched.",
768 "It is no use crying over spilt milk.",
769 "Seeing is believing.",
770 "Strike the iron while it is hot.",
771 "I don't care what follows.",
772 "To dig a well to put out a house on fire.",
773 "Tomorrow is another day.",
774 "Easy come, easy go.",
775 "The more haste, the less speed.",
776 "Where there is life, there is hope.",
777 "There is no royal road to *WINNER*.",
778 "Danger past, God forgotten.",
779 "The best thing to do now is to run away.",
780 "Life is but an empty dream.",
781 "Dead men tell no tales.",
782 "A book that remains shut is but a block.",
783 "Misfortunes never come singly.",
784 "A little knowledge is a dangerous thing.",
785 "History repeats itself.",
786 "*WINNER* was not built in a day.",
787 "Ignorance is bliss.",
788 "To lose is to win?",
789 "No medicine can cure folly.",
790 "All good things come to an end.",
791 "M$ Empire strikes back.",
792 "To see is to believe",
794 "Quest of The World's Greatest Brain"};
796 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
798 /* Build the filename */
799 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
801 if (p_ptr->pclass == CLASS_WARRIOR || p_ptr->pclass == CLASS_MONK || p_ptr->pclass == CLASS_SAMURAI || p_ptr->pclass == CLASS_BERSERKER)
802 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)]);
803 else if (IS_WIZARD_CLASS())
804 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)+1]);
805 else strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-2)+1]);
808 sprintf(nikki_title, "「%s%s%sの伝説 -%s-」",
809 ap_ptr->title, ap_ptr->no ? "の" : "", p_ptr->name, tmp);
811 sprintf(nikki_title, "Legend of %s %s '%s'",
812 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];
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 cptr 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 cptr 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(cptr 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(cptr 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, cptr 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 cptr 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 cptr 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(cptr fname)
2302 static cptr 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(cptr fname)
2443 static cptr 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 cptr 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(cptr 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 cptr 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 cptr 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 cptr 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 cptr 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 cptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
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 cptr 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 cptr 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 cptr 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 cptr 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 cptr 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 cptr 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 cptr 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 cptr 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 cptr 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 cptr 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 cptr 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 int collect_objects(int grp_cur, IDX object_idx[], BIT_FLAGS8 mode)
4379 int j, k, 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 cptr 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 int collect_features(int grp_cur, IDX *feat_idx, BIT_FLAGS8 mode)
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)
4559 Term_get_size(&wid, &hgt);
4561 /* Build the filename */
4562 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4564 /* Append to the file */
4565 fff = my_fopen(buf, "r");
4568 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4576 /* Load the screen */
4577 for (y = 0; okay; y++)
4579 /* Get a line of data including control code */
4580 if (!fgets(buf, 1024, fff)) okay = FALSE;
4582 /* Get the blank line */
4583 if (buf[0] == '\n' || buf[0] == '\0') break;
4585 /* Ignore too large screen image */
4586 if (y >= hgt) continue;
4589 for (x = 0; x < wid - 1; x++)
4592 if (buf[x] == '\n' || buf[x] == '\0') break;
4594 /* Put the attr/char */
4595 Term_draw(x, y, TERM_WHITE, buf[x]);
4599 /* Dump the screen */
4600 for (y = 0; okay; y++)
4602 /* Get a line of data including control code */
4603 if (!fgets(buf, 1024, fff)) okay = FALSE;
4605 /* Get the blank line */
4606 if (buf[0] == '\n' || buf[0] == '\0') break;
4608 /* Ignore too large screen image */
4609 if (y >= hgt) continue;
4612 for (x = 0; x < wid - 1; x++)
4615 if (buf[x] == '\n' || buf[x] == '\0') break;
4617 /* Get the attr/char */
4618 (void)(Term_what(x, y, &a, &c));
4620 /* Look up the attr */
4621 for (i = 0; i < 16; i++)
4623 /* Use attr matches */
4624 if (hack[i] == buf[x]) a = (byte_hack)i;
4627 /* Put the attr/char */
4628 Term_draw(x, y, a, c);
4637 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4648 cptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4649 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4652 #define IM_FLAG_STR _("*", "* ")
4653 #define HAS_FLAG_STR _("+", "+ ")
4654 #define NO_FLAG_STR _("・", ". ")
4656 #define print_im_or_res_flag(IM, RES) \
4658 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4659 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4662 #define print_flag(TR) \
4664 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4668 /* XTRA HACK RESLIST */
4669 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
4671 GAME_TEXT o_name[MAX_NLEN];
4672 BIT_FLAGS flgs[TR_FLAG_SIZE];
4674 if (!o_ptr->k_idx) return;
4675 if (o_ptr->tval != tval) return;
4677 /* Identified items only */
4678 if (!object_is_known(o_ptr)) return;
4681 * HACK:Ring of Lordly protection and Dragon equipment
4682 * have random resistances.
4684 if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4685 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4686 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4687 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4688 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4689 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4690 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4691 || object_is_artifact(o_ptr))
4694 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4696 while (o_name[i] && (i < 26))
4699 if (iskanji(o_name[i])) i++;
4708 o_name[i] = ' '; i++;
4713 fprintf(fff, "%s %s", where, o_name);
4715 if (!(o_ptr->ident & (IDENT_MENTAL)))
4717 fputs(_("-------不明--------------- -------不明---------\n",
4718 "-------unknown------------ -------unknown------\n"), fff);
4722 object_flags_known(o_ptr, flgs);
4724 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4725 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4726 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4727 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4728 print_flag(TR_RES_POIS);
4729 print_flag(TR_RES_LITE);
4730 print_flag(TR_RES_DARK);
4731 print_flag(TR_RES_SHARDS);
4732 print_flag(TR_RES_SOUND);
4733 print_flag(TR_RES_NETHER);
4734 print_flag(TR_RES_NEXUS);
4735 print_flag(TR_RES_CHAOS);
4736 print_flag(TR_RES_DISEN);
4740 print_flag(TR_RES_BLIND);
4741 print_flag(TR_RES_FEAR);
4742 print_flag(TR_RES_CONF);
4743 print_flag(TR_FREE_ACT);
4744 print_flag(TR_SEE_INVIS);
4745 print_flag(TR_HOLD_EXP);
4746 print_flag(TR_TELEPATHY);
4747 print_flag(TR_SLOW_DIGEST);
4748 print_flag(TR_REGEN);
4749 print_flag(TR_LEVITATION);
4757 fprintf(fff, "%s\n", inven_res_label);
4763 * Display *ID* ed weapons/armors's resistances
4765 static void do_cmd_knowledge_inven(void)
4769 GAME_TEXT file_name[1024];
4773 OBJECT_TYPE_VALUE tval;
4779 /* Open a new file */
4780 fff = my_fopen_temp(file_name, 1024);
4783 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4787 fprintf(fff, "%s\n", inven_res_label);
4789 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4793 for (; j < 9; j++) fputc('\n', fff);
4795 fprintf(fff, "%s\n", inven_res_label);
4797 strcpy(where, _("装", "E "));
4798 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4800 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4802 strcpy(where, _("持", "I "));
4803 for (i = 0; i < INVEN_PACK; i++)
4805 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4808 st_ptr = &town[1].store[STORE_HOME];
4809 strcpy(where, _("家", "H "));
4810 for (i = 0; i < st_ptr->stock_num; i++)
4812 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
4817 /* Display the file contents */
4818 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
4820 /* Remove the file */
4825 void do_cmd_save_screen_html_aux(char *filename, int message)
4829 TERM_COLOR a = 0, old_a = 0;
4843 cptr html_head[] = {
4844 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
4848 cptr html_foot[] = {
4850 "</body>\n</html>\n",
4856 Term_get_size(&wid, &hgt);
4858 /* File type is "TEXT" */
4859 FILE_TYPE(FILE_TYPE_TEXT);
4861 /* Append to the file */
4862 fff = my_fopen(filename, "w");
4866 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
4872 if (message) screen_save();
4874 /* Build the filename */
4875 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
4876 tmpfff = my_fopen(buf, "r");
4878 for (i = 0; html_head[i]; i++)
4879 fputs(html_head[i], fff);
4883 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4885 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
4889 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
4891 fprintf(fff, "%s\n", buf);
4896 /* Dump the screen */
4897 for (y = 0; y < hgt; y++)
4904 for (x = 0; x < wid - 1; x++)
4908 /* Get the attr/char */
4909 (void)(Term_what(x, y, &a, &c));
4913 case '&': cc = "&"; break;
4914 case '<': cc = "<"; break;
4915 case '>': cc = ">"; break;
4917 case 0x1f: c = '.'; break;
4918 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
4923 if ((y == 0 && x == 0) || a != old_a) {
4924 rv = angband_color_table[a][1];
4925 gv = angband_color_table[a][2];
4926 bv = angband_color_table[a][3];
4927 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
4928 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
4932 fprintf(fff, "%s", cc);
4934 fprintf(fff, "%c", c);
4937 fprintf(fff, "</font>");
4940 for (i = 0; html_foot[i]; i++)
4941 fputs(html_foot[i], fff);
4946 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4948 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
4952 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
4954 fprintf(fff, "%s\n", buf);
4967 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4975 * Hack -- save a screen dump to a file
4977 static void do_cmd_save_screen_html(void)
4979 char buf[1024], tmp[256] = "screen.html";
4981 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
4984 /* Build the filename */
4985 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4989 do_cmd_save_screen_html_aux(buf, 1);
4994 * Redefinable "save_screen" action
4996 void (*screendump_aux)(void) = NULL;
5000 * Hack -- save a screen dump to a file
5002 void do_cmd_save_screen(void)
5004 bool old_use_graphics = use_graphics;
5005 bool html_dump = FALSE;
5009 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
5013 if (c == 'Y' || c == 'y')
5015 else if (c == 'H' || c == 'h')
5027 Term_get_size(&wid, &hgt);
5029 if (old_use_graphics)
5031 use_graphics = FALSE;
5033 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5039 do_cmd_save_screen_html();
5043 /* Do we use a special screendump function ? */
5044 else if (screendump_aux)
5046 /* Dump the screen to a graphics file */
5047 (*screendump_aux)();
5049 else /* Dump the screen as text */
5060 /* Build the filename */
5061 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5063 /* File type is "TEXT" */
5064 FILE_TYPE(FILE_TYPE_TEXT);
5066 /* Append to the file */
5067 fff = my_fopen(buf, "w");
5071 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5079 /* Dump the screen */
5080 for (y = 0; y < hgt; y++)
5083 for (x = 0; x < wid - 1; x++)
5085 /* Get the attr/char */
5086 (void)(Term_what(x, y, &a, &c));
5096 fprintf(fff, "%s\n", buf);
5103 /* Dump the screen */
5104 for (y = 0; y < hgt; y++)
5107 for (x = 0; x < wid - 1; x++)
5109 /* Get the attr/char */
5110 (void)(Term_what(x, y, &a, &c));
5113 buf[x] = hack[a&0x0F];
5120 fprintf(fff, "%s\n", buf);
5129 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5134 if (old_use_graphics)
5136 use_graphics = TRUE;
5138 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5145 * Sorting hook -- Comp function -- see below
5147 * We use "u" to point to array of monster indexes,
5148 * and "v" to select the type of sorting to perform on "u".
5150 static bool ang_sort_art_comp(vptr u, vptr v, int a, int b)
5152 u16b *who = (u16b*)(u);
5154 u16b *why = (u16b*)(v);
5161 /* Sort by total kills */
5164 /* Extract total kills */
5165 z1 = a_info[w1].tval;
5166 z2 = a_info[w2].tval;
5168 /* Compare total kills */
5169 if (z1 < z2) return (TRUE);
5170 if (z1 > z2) return (FALSE);
5174 /* Sort by monster level */
5177 /* Extract levels */
5178 z1 = a_info[w1].sval;
5179 z2 = a_info[w2].sval;
5181 /* Compare levels */
5182 if (z1 < z2) return (TRUE);
5183 if (z1 > z2) return (FALSE);
5187 /* Sort by monster experience */
5190 /* Extract experience */
5191 z1 = a_info[w1].level;
5192 z2 = a_info[w2].level;
5194 /* Compare experience */
5195 if (z1 < z2) return (TRUE);
5196 if (z1 > z2) return (FALSE);
5200 /* Compare indexes */
5206 * Sorting hook -- Swap function -- see below
5208 * We use "u" to point to array of monster indexes,
5209 * and "v" to select the type of sorting to perform.
5211 static void ang_sort_art_swap(vptr u, vptr v, int a, int b)
5213 u16b *who = (u16b*)(u);
5228 * Check the status of "artifacts"
5230 static void do_cmd_knowledge_artifacts(void)
5240 GAME_TEXT file_name[1024];
5241 GAME_TEXT base_name[MAX_NLEN];
5245 /* Open a new file */
5246 fff = my_fopen_temp(file_name, 1024);
5249 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5254 /* Allocate the "who" array */
5255 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
5257 /* Allocate the "okay" array */
5258 C_MAKE(okay, max_a_idx, bool);
5260 /* Scan the artifacts */
5261 for (k = 0; k < max_a_idx; k++)
5263 artifact_type *a_ptr = &a_info[k];
5268 /* Skip "empty" artifacts */
5269 if (!a_ptr->name) continue;
5271 /* Skip "uncreated" artifacts */
5272 if (!a_ptr->cur_num) continue;
5278 /* Check the dungeon */
5279 for (y = 0; y < cur_hgt; y++)
5281 for (x = 0; x < cur_wid; x++)
5283 cave_type *c_ptr = &cave[y][x];
5285 OBJECT_IDX this_o_idx, next_o_idx = 0;
5287 /* Scan all objects in the grid */
5288 for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5291 o_ptr = &o_list[this_o_idx];
5293 /* Acquire next object */
5294 next_o_idx = o_ptr->next_o_idx;
5296 /* Ignore non-artifacts */
5297 if (!object_is_fixed_artifact(o_ptr)) continue;
5299 /* Ignore known items */
5300 if (object_is_known(o_ptr)) continue;
5302 /* Note the artifact */
5303 okay[o_ptr->name1] = FALSE;
5308 /* Check the inventory and equipment */
5309 for (i = 0; i < INVEN_TOTAL; i++)
5311 object_type *o_ptr = &inventory[i];
5313 /* Ignore non-objects */
5314 if (!o_ptr->k_idx) continue;
5316 /* Ignore non-artifacts */
5317 if (!object_is_fixed_artifact(o_ptr)) continue;
5319 /* Ignore known items */
5320 if (object_is_known(o_ptr)) continue;
5322 /* Note the artifact */
5323 okay[o_ptr->name1] = FALSE;
5326 for (k = 0; k < max_a_idx; k++)
5328 if (okay[k]) who[n++] = k;
5331 /* Select the sort method */
5332 ang_sort_comp = ang_sort_art_comp;
5333 ang_sort_swap = ang_sort_art_swap;
5335 /* Sort the array by dungeon depth of monsters */
5336 ang_sort(who, &why, n);
5338 /* Scan the artifacts */
5339 for (k = 0; k < n; k++)
5341 artifact_type *a_ptr = &a_info[who[k]];
5344 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5346 /* Obtain the base object type */
5347 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5356 /* Create fake object */
5357 object_prep(q_ptr, z);
5359 /* Make it an artifact */
5360 q_ptr->name1 = (byte)who[k];
5362 /* Display as if known */
5363 q_ptr->ident |= IDENT_STORE;
5365 /* Describe the artifact */
5366 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5369 /* Hack -- Build the artifact name */
5370 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
5373 /* Free the "who" array */
5374 C_KILL(who, max_a_idx, ARTIFACT_IDX);
5376 /* Free the "okay" array */
5377 C_KILL(okay, max_a_idx, bool);
5380 /* Display the file contents */
5381 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5383 /* Remove the file */
5389 * Display known uniques
5390 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5392 static void do_cmd_knowledge_uniques(void)
5401 GAME_TEXT file_name[1024];
5404 int n_alive_surface = 0;
5405 int n_alive_over100 = 0;
5406 int n_alive_total = 0;
5409 for (i = 0; i < 10; i++) n_alive[i] = 0;
5411 /* Open a new file */
5412 fff = my_fopen_temp(file_name, 1024);
5416 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5421 /* Allocate the "who" array */
5422 C_MAKE(who, max_r_idx, s16b);
5424 /* Scan the monsters */
5425 for (i = 1; i < max_r_idx; i++)
5427 monster_race *r_ptr = &r_info[i];
5430 if (!r_ptr->name) continue;
5432 /* Require unique monsters */
5433 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5435 /* Only display "known" uniques */
5436 if (!cheat_know && !r_ptr->r_sights) continue;
5438 /* Only print rarity <= 100 uniques */
5439 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5441 /* Only "alive" uniques */
5442 if (r_ptr->max_num == 0) continue;
5446 lev = (r_ptr->level - 1) / 10;
5450 if (max_lev < lev) max_lev = lev;
5452 else n_alive_over100++;
5454 else n_alive_surface++;
5456 /* Collect "appropriate" monsters */
5460 /* Select the sort method */
5461 ang_sort_comp = ang_sort_comp_hook;
5462 ang_sort_swap = ang_sort_swap_hook;
5464 /* Sort the array by dungeon depth of monsters */
5465 ang_sort(who, &why, n);
5467 if (n_alive_surface)
5469 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
5470 n_alive_total += n_alive_surface;
5472 for (i = 0; i <= max_lev; i++)
5474 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5475 n_alive_total += n_alive[i];
5477 if (n_alive_over100)
5479 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
5480 n_alive_total += n_alive_over100;
5485 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
5486 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
5490 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5493 /* Scan the monster races */
5494 for (k = 0; k < n; k++)
5496 monster_race *r_ptr = &r_info[who[k]];
5498 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
5501 /* Free the "who" array */
5502 C_KILL(who, max_r_idx, s16b);
5505 /* Display the file contents */
5506 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5508 /* Remove the file */
5514 * Display weapon-exp
5516 static void do_cmd_knowledge_weapon_exp(void)
5518 int i, num, weapon_exp;
5523 GAME_TEXT file_name[1024];
5526 /* Open a new file */
5527 fff = my_fopen_temp(file_name, 1024);
5529 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5534 for (i = 0; i < 5; i++)
5536 for (num = 0; num < 64; num++)
5538 for (j = 0; j < max_k_idx; j++)
5540 object_kind *k_ptr = &k_info[j];
5542 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5544 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5546 weapon_exp = p_ptr->weapon_exp[4 - i][num];
5548 fprintf(fff, "%-25s ", tmp);
5549 if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5550 else fprintf(fff, " ");
5551 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5552 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5561 /* Display the file contents */
5562 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5564 /* Remove the file */
5570 * @brief 魔法の経験値を表示するコマンドのメインルーチン
5574 static void do_cmd_knowledge_spell_exp(void)
5577 int spell_exp, exp_level;
5580 const magic_type *s_ptr;
5582 GAME_TEXT file_name[1024];
5584 /* Open a new file */
5585 fff = my_fopen_temp(file_name, 1024);
5587 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5592 if (p_ptr->realm1 != REALM_NONE)
5594 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5595 for (i = 0; i < 32; i++)
5597 if (!is_magic(p_ptr->realm1))
5599 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5603 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5605 if (s_ptr->slevel >= 99) continue;
5606 spell_exp = p_ptr->spell_exp[i];
5607 exp_level = spell_exp_level(spell_exp);
5608 fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5609 if (p_ptr->realm1 == REALM_HISSATSU)
5610 fprintf(fff, "[--]");
5613 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5614 else fprintf(fff, " ");
5615 fprintf(fff, "%s", exp_level_str[exp_level]);
5617 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5622 if (p_ptr->realm2 != REALM_NONE)
5624 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5625 for (i = 0; i < 32; i++)
5627 if (!is_magic(p_ptr->realm1))
5629 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5633 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5635 if (s_ptr->slevel >= 99) continue;
5637 spell_exp = p_ptr->spell_exp[i + 32];
5638 exp_level = spell_exp_level(spell_exp);
5639 fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5640 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5641 else fprintf(fff, " ");
5642 fprintf(fff, "%s", exp_level_str[exp_level]);
5643 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5649 /* Display the file contents */
5650 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5652 /* Remove the file */
5658 * @brief スキル情報を表示するコマンドのメインルーチン /
5662 static void do_cmd_knowledge_skill_exp(void)
5664 int i = 0, skill_exp;
5668 GAME_TEXT file_name[1024];
5669 GAME_TEXT skill_name[3][20]={_("マーシャルアーツ", "Martial Arts "),
5670 _("二刀流 ", "Dual Wielding "),
5671 _("乗馬 ", "Riding ")};
5673 /* Open a new file */
5674 fff = my_fopen_temp(file_name, 1024);
5676 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5681 for (i = 0; i < 3; i++)
5683 skill_exp = p_ptr->skill_exp[i];
5684 fprintf(fff, "%-20s ", skill_name[i]);
5685 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5686 else fprintf(fff, " ");
5687 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5688 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5693 /* Display the file contents */
5694 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5696 /* Remove the file */
5702 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5703 * @param Name 変換したい文字列の参照ポインタ
5706 void plural_aux(char *Name)
5708 int NameLen = strlen(Name);
5710 if (my_strstr(Name, "Disembodied hand"))
5712 strcpy(Name, "Disembodied hands that strangled people");
5714 else if (my_strstr(Name, "Colour out of space"))
5716 strcpy(Name, "Colours out of space");
5718 else if (my_strstr(Name, "stairway to hell"))
5720 strcpy(Name, "stairways to hell");
5722 else if (my_strstr(Name, "Dweller on the threshold"))
5724 strcpy(Name, "Dwellers on the threshold");
5726 else if (my_strstr(Name, " of "))
5728 cptr aider = my_strstr(Name, " of ");
5739 if (dummy[i-1] == 's')
5741 strcpy(&(dummy[i]), "es");
5746 strcpy(&(dummy[i]), "s");
5749 strcpy(&(dummy[i+1]), aider);
5750 strcpy(Name, dummy);
5752 else if (my_strstr(Name, "coins"))
5755 strcpy(dummy, "piles of ");
5756 strcat(dummy, Name);
5757 strcpy(Name, dummy);
5760 else if (my_strstr(Name, "Manes"))
5764 else if (streq(&(Name[NameLen - 2]), "ey"))
5766 strcpy(&(Name[NameLen - 2]), "eys");
5768 else if (Name[NameLen - 1] == 'y')
5770 strcpy(&(Name[NameLen - 1]), "ies");
5772 else if (streq(&(Name[NameLen - 4]), "ouse"))
5774 strcpy(&(Name[NameLen - 4]), "ice");
5776 else if (streq(&(Name[NameLen - 2]), "us"))
5778 strcpy(&(Name[NameLen - 2]), "i");
5780 else if (streq(&(Name[NameLen - 6]), "kelman"))
5782 strcpy(&(Name[NameLen - 6]), "kelmen");
5784 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5786 strcpy(&(Name[NameLen - 8]), "wordsmen");
5788 else if (streq(&(Name[NameLen - 7]), "oodsman"))
5790 strcpy(&(Name[NameLen - 7]), "oodsmen");
5792 else if (streq(&(Name[NameLen - 7]), "eastman"))
5794 strcpy(&(Name[NameLen - 7]), "eastmen");
5796 else if (streq(&(Name[NameLen - 8]), "izardman"))
5798 strcpy(&(Name[NameLen - 8]), "izardmen");
5800 else if (streq(&(Name[NameLen - 5]), "geist"))
5802 strcpy(&(Name[NameLen - 5]), "geister");
5804 else if (streq(&(Name[NameLen - 2]), "ex"))
5806 strcpy(&(Name[NameLen - 2]), "ices");
5808 else if (streq(&(Name[NameLen - 2]), "lf"))
5810 strcpy(&(Name[NameLen - 2]), "lves");
5812 else if (suffix(Name, "ch") ||
5813 suffix(Name, "sh") ||
5814 suffix(Name, "nx") ||
5815 suffix(Name, "s") ||
5818 strcpy(&(Name[NameLen]), "es");
5822 strcpy(&(Name[NameLen]), "s");
5827 * @brief 現在のペットを表示するコマンドのメインルーチン /
5828 * Display current pets
5831 static void do_cmd_knowledge_pets(void)
5835 monster_type *m_ptr;
5836 GAME_TEXT pet_name[MAX_NLEN];
5838 int show_upkeep = 0;
5839 GAME_TEXT file_name[1024];
5842 /* Open a new file */
5843 fff = my_fopen_temp(file_name, 1024);
5845 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5850 /* Process the monsters (backwards) */
5851 for (i = m_max - 1; i >= 1; i--)
5853 /* Access the monster */
5856 /* Ignore "dead" monsters */
5857 if (!m_ptr->r_idx) continue;
5859 /* Calculate "upkeep" for pets */
5863 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
5864 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
5868 show_upkeep = calculate_upkeep();
5870 fprintf(fff, "----------------------------------------------\n");
5872 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
5874 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
5876 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
5881 /* Display the file contents */
5882 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
5884 /* Remove the file */
5890 * @brief 現在のペットを表示するコマンドのメインルーチン /
5893 * @note the player ghosts are ignored.
5895 static void do_cmd_knowledge_kill_count(void)
5902 GAME_TEXT file_name[1024];
5907 /* Open a new file */
5908 fff = my_fopen_temp(file_name, 1024);
5911 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5916 /* Allocate the "who" array */
5917 C_MAKE(who, max_r_idx, MONRACE_IDX);
5920 /* Monsters slain */
5923 for (kk = 1; kk < max_r_idx; kk++)
5925 monster_race *r_ptr = &r_info[kk];
5927 if (r_ptr->flags1 & (RF1_UNIQUE))
5929 bool dead = (r_ptr->max_num == 0);
5938 MONSTER_NUMBER This = r_ptr->r_pkills;
5948 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
5951 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
5953 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
5959 /* Scan the monsters */
5960 for (i = 1; i < max_r_idx; i++)
5962 monster_race *r_ptr = &r_info[i];
5964 /* Use that monster */
5965 if (r_ptr->name) who[n++] = i;
5968 /* Select the sort method */
5969 ang_sort_comp = ang_sort_comp_hook;
5970 ang_sort_swap = ang_sort_swap_hook;
5972 /* Sort the array by dungeon depth of monsters */
5973 ang_sort(who, &why, n);
5975 /* Scan the monster races */
5976 for (k = 0; k < n; k++)
5978 monster_race *r_ptr = &r_info[who[k]];
5980 if (r_ptr->flags1 & (RF1_UNIQUE))
5982 bool dead = (r_ptr->max_num == 0);
5986 fprintf(fff, " %s\n", (r_name + r_ptr->name));
5992 MONSTER_NUMBER This = r_ptr->r_pkills;
5997 /* p,tは人と数える by ita */
5998 if (my_strchr("pt", r_ptr->d_char))
5999 fprintf(fff, " %3d 人の %s\n", (int)This, r_name + r_ptr->name);
6001 fprintf(fff, " %3d 体の %s\n", (int)This, r_name + r_ptr->name);
6005 if (my_strstr(r_name + r_ptr->name, "coins"))
6007 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
6011 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
6017 strcpy(ToPlural, (r_name + r_ptr->name));
6018 plural_aux(ToPlural);
6019 fprintf(fff, " %d %s\n", This, ToPlural);
6029 fprintf(fff,"----------------------------------------------\n");
6031 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
6033 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)Total, (Total == 1 ? "" : "s"));
6037 /* Free the "who" array */
6038 C_KILL(who, max_r_idx, s16b);
6041 /* Display the file contents */
6042 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
6044 /* Remove the file */
6050 * @brief モンスター情報リスト中のグループを表示する /
6051 * Display the object groups.
6055 * @param per_page リストの表示行
6056 * @param grp_idx グループのID配列
6057 * @param group_text グループ名の文字列配列
6058 * @param grp_cur 現在の選択ID
6059 * @param grp_top 現在の選択リスト最上部ID
6062 static void display_group_list(int col, int row, int wid, int per_page, IDX grp_idx[], cptr group_text[], int grp_cur, int grp_top)
6066 /* Display lines until done */
6067 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
6069 /* Get the group index */
6070 int grp = grp_idx[grp_top + i];
6072 /* Choose a color */
6073 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
6075 /* Erase the entire line */
6076 Term_erase(col, row + i, wid);
6078 /* Display the group label */
6079 c_put_str(attr, group_text[grp], row + i, col);
6085 * Move the cursor in a browser window
6087 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
6088 IDX *list_cur, int list_cnt)
6093 IDX list = *list_cur;
6095 /* Extract direction */
6098 /* Hack -- scroll up full screen */
6103 /* Hack -- scroll down full screen */
6108 d = get_keymap_dir(ch);
6113 /* Diagonals - hack */
6114 if ((ddx[d] > 0) && ddy[d])
6119 Term_get_size(&wid, &hgt);
6121 browser_rows = hgt - 8;
6123 /* Browse group list */
6128 /* Move up or down */
6129 grp += ddy[d] * (browser_rows - 1);
6132 if (grp >= grp_cnt) grp = grp_cnt - 1;
6133 if (grp < 0) grp = 0;
6134 if (grp != old_grp) list = 0;
6137 /* Browse sub-list list */
6140 /* Move up or down */
6141 list += ddy[d] * browser_rows;
6144 if (list >= list_cnt) list = list_cnt - 1;
6145 if (list < 0) list = 0;
6157 if (col < 0) col = 0;
6158 if (col > 1) col = 1;
6165 /* Browse group list */
6170 /* Move up or down */
6174 if (grp >= grp_cnt) grp = grp_cnt - 1;
6175 if (grp < 0) grp = 0;
6176 if (grp != old_grp) list = 0;
6179 /* Browse sub-list list */
6182 /* Move up or down */
6186 if (list >= list_cnt) list = list_cnt - 1;
6187 if (list < 0) list = 0;
6198 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
6202 /* Clear the display lines */
6203 for (i = 0; i < height; i++)
6205 Term_erase(col, row + i, width);
6208 /* Bigtile mode uses double width */
6209 if (use_bigtile) width /= 2;
6211 /* Display lines until done */
6212 for (i = 0; i < height; i++)
6214 /* Display columns until done */
6215 for (j = 0; j < width; j++)
6219 TERM_LEN x = col + j;
6220 TERM_LEN y = row + i;
6223 /* Bigtile mode uses double width */
6224 if (use_bigtile) x += j;
6229 /* Ignore illegal characters */
6230 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6231 (!use_graphics && ic > 0x7f))
6237 /* Force correct code for both ASCII character and tile */
6238 if (c & 0x80) a |= 0x80;
6240 /* Display symbol */
6241 Term_queue_bigchar(x, y, a, c, 0, 0);
6248 * Place the cursor at the collect position for visual mode
6250 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
6252 int i = (a & 0x7f) - attr_top;
6253 int j = c - char_left;
6255 TERM_LEN x = col + j;
6256 TERM_LEN y = row + i;
6258 /* Bigtile mode uses double width */
6259 if (use_bigtile) x += j;
6261 /* Place the cursor */
6267 * Clipboard variables for copy&paste in visual mode
6269 static TERM_COLOR attr_idx = 0;
6270 static byte char_idx = 0;
6272 /* Hack -- for feature lighting */
6273 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
6274 static byte char_idx_feat[F_LIT_MAX];
6277 * Do visual mode command -- Change symbols
6279 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6280 int height, int width,
6281 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
6282 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
6284 static TERM_COLOR attr_old = 0;
6285 static SYMBOL_CODE char_old = 0;
6290 if (*visual_list_ptr)
6293 *cur_attr_ptr = attr_old;
6294 *cur_char_ptr = char_old;
6295 *visual_list_ptr = FALSE;
6303 if (*visual_list_ptr)
6306 *visual_list_ptr = FALSE;
6307 *need_redraw = TRUE;
6315 if (!*visual_list_ptr)
6317 *visual_list_ptr = TRUE;
6319 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6320 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6322 attr_old = *cur_attr_ptr;
6323 char_old = *cur_char_ptr;
6334 /* Set the visual */
6335 attr_idx = *cur_attr_ptr;
6336 char_idx = *cur_char_ptr;
6338 /* Hack -- for feature lighting */
6339 for (i = 0; i < F_LIT_MAX; i++)
6341 attr_idx_feat[i] = 0;
6342 char_idx_feat[i] = 0;
6349 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6352 *cur_attr_ptr = attr_idx;
6353 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6354 if (!*visual_list_ptr) *need_redraw = TRUE;
6360 *cur_char_ptr = char_idx;
6361 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6362 if (!*visual_list_ptr) *need_redraw = TRUE;
6368 if (*visual_list_ptr)
6371 int d = get_keymap_dir(ch);
6372 byte a = (*cur_attr_ptr & 0x7f);
6373 byte c = *cur_char_ptr;
6375 if (use_bigtile) eff_width = width / 2;
6376 else eff_width = width;
6378 /* Restrict direction */
6379 if ((a == 0) && (ddy[d] < 0)) d = 0;
6380 if ((c == 0) && (ddx[d] < 0)) d = 0;
6381 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6382 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6387 /* Force correct code for both ASCII character and tile */
6388 if (c & 0x80) a |= 0x80;
6390 /* Set the visual */
6395 /* Move the frame */
6396 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6397 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6398 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6399 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6405 /* Visual mode command is not used */
6411 * Display the monsters in a group.
6413 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6414 int mon_cur, int mon_top, bool visual_only)
6418 /* Display lines until done */
6419 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6423 /* Get the race index */
6424 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6426 /* Access the race */
6427 monster_race *r_ptr = &r_info[r_idx];
6429 /* Choose a color */
6430 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6432 /* Display the name */
6433 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6435 /* Hack -- visual_list mode */
6438 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6440 if (p_ptr->wizard || visual_only)
6442 c_prt(attr, format("%d", r_idx), row + i, 62);
6445 /* Erase chars before overwritten by the race letter */
6446 Term_erase(69, row + i, 255);
6448 /* Display symbol */
6449 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6454 if (!(r_ptr->flags1 & RF1_UNIQUE))
6455 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6457 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6458 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6462 /* Clear remaining lines */
6463 for (; i < per_page; i++)
6465 Term_erase(col, row + i, 255);
6471 * Display known monsters.
6473 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6477 IDX grp_cur, grp_top, old_grp_cur;
6478 IDX mon_cur, mon_top;
6479 IDX grp_cnt, grp_idx[100];
6487 bool visual_list = FALSE;
6488 TERM_COLOR attr_top = 0;
6496 Term_get_size(&wid, &hgt);
6498 browser_rows = hgt - 8;
6500 /* Allocate the "mon_idx" array */
6501 C_MAKE(mon_idx, max_r_idx, s16b);
6506 if (direct_r_idx < 0)
6508 mode = visual_only ? 0x03 : 0x01;
6510 /* Check every group */
6511 for (i = 0; monster_group_text[i] != NULL; i++)
6513 /* Measure the label */
6514 len = strlen(monster_group_text[i]);
6516 /* Save the maximum length */
6517 if (len > max) max = len;
6519 /* See if any monsters are known */
6520 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6522 /* Build a list of groups with known monsters */
6523 grp_idx[grp_cnt++] = i;
6531 mon_idx[0] = direct_r_idx;
6534 /* Terminate the list */
6537 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6538 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6541 /* Terminate the list */
6542 grp_idx[grp_cnt] = -1;
6545 grp_cur = grp_top = 0;
6546 mon_cur = mon_top = 0;
6551 mode = visual_only ? 0x02 : 0x00;
6556 monster_race *r_ptr;
6561 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
6562 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
6563 prt(_("名前", "Name"), 4, max + 3);
6564 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6565 prt(_("文字", "Sym"), 4, 67);
6566 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
6568 for (i = 0; i < 78; i++)
6570 Term_putch(i, 5, TERM_WHITE, '=');
6573 if (direct_r_idx < 0)
6575 for (i = 0; i < browser_rows; i++)
6577 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6584 if (direct_r_idx < 0)
6586 /* Scroll group list */
6587 if (grp_cur < grp_top) grp_top = grp_cur;
6588 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6590 /* Display a list of monster groups */
6591 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6593 if (old_grp_cur != grp_cur)
6595 old_grp_cur = grp_cur;
6597 /* Get a list of monsters in the current group */
6598 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6601 /* Scroll monster list */
6602 while (mon_cur < mon_top)
6603 mon_top = MAX(0, mon_top - browser_rows/2);
6604 while (mon_cur >= mon_top + browser_rows)
6605 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6610 /* Display a list of monsters in the current group */
6611 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6617 /* Display a monster name */
6618 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6620 /* Display visual list below first monster */
6621 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6625 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
6626 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
6627 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
6628 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
6631 /* Get the current monster */
6632 r_ptr = &r_info[mon_idx[mon_cur]];
6636 /* Mega Hack -- track this monster race */
6637 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6643 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6647 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6651 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6656 /* Do visual mode command if needed */
6657 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))
6659 if (direct_r_idx >= 0)
6684 /* Recall on screen */
6685 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6687 screen_roff(mon_idx[mon_cur], 0);
6698 /* Move the cursor */
6699 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6706 /* Free the "mon_idx" array */
6707 C_KILL(mon_idx, max_r_idx, s16b);
6712 * Display the objects in a group.
6714 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6715 int object_cur, int object_top, bool visual_only)
6719 /* Display lines until done */
6720 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6722 GAME_TEXT o_name[MAX_NLEN];
6725 object_kind *flavor_k_ptr;
6727 /* Get the object index */
6728 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6730 /* Access the object */
6731 object_kind *k_ptr = &k_info[k_idx];
6733 /* Choose a color */
6734 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6735 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6738 if (!visual_only && k_ptr->flavor)
6740 /* Appearance of this object is shuffled */
6741 flavor_k_ptr = &k_info[k_ptr->flavor];
6745 /* Appearance of this object is very normal */
6746 flavor_k_ptr = k_ptr;
6751 attr = ((i + object_top == object_cur) ? cursor : attr);
6753 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6756 strip_name(o_name, k_idx);
6761 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
6764 /* Display the name */
6765 c_prt(attr, o_name, row + i, col);
6767 /* Hack -- visual_list mode */
6770 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);
6772 if (p_ptr->wizard || visual_only)
6774 c_prt(attr, format("%d", k_idx), row + i, 70);
6777 a = flavor_k_ptr->x_attr;
6778 c = flavor_k_ptr->x_char;
6780 /* Display symbol */
6781 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
6784 /* Clear remaining lines */
6785 for (; i < per_page; i++)
6787 Term_erase(col, row + i, 255);
6792 * Describe fake object
6794 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
6797 object_type object_type_body;
6798 o_ptr = &object_type_body;
6801 /* Create the artifact */
6802 object_prep(o_ptr, k_idx);
6804 /* It's fully know */
6805 o_ptr->ident |= IDENT_KNOWN;
6807 /* Track the object */
6808 /* object_actual_track(o_ptr); */
6810 /* Hack - mark as fake */
6811 /* term_obj_real = FALSE; */
6814 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
6816 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
6824 * Display known objects
6826 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
6830 IDX grp_cur, grp_top, old_grp_cur;
6831 IDX object_old, object_cur, object_top;
6841 bool visual_list = FALSE;
6842 TERM_COLOR attr_top = 0;
6850 Term_get_size(&wid, &hgt);
6852 browser_rows = hgt - 8;
6854 /* Allocate the "object_idx" array */
6855 C_MAKE(object_idx, max_k_idx, IDX);
6860 if (direct_k_idx < 0)
6862 mode = visual_only ? 0x03 : 0x01;
6864 /* Check every group */
6865 for (i = 0; object_group_text[i] != NULL; i++)
6867 /* Measure the label */
6868 len = strlen(object_group_text[i]);
6870 /* Save the maximum length */
6871 if (len > max) max = len;
6873 /* See if any monsters are known */
6874 if (collect_objects(i, object_idx, mode))
6876 /* Build a list of groups with known monsters */
6877 grp_idx[grp_cnt++] = i;
6886 object_kind *k_ptr = &k_info[direct_k_idx];
6887 object_kind *flavor_k_ptr;
6889 if (!visual_only && k_ptr->flavor)
6891 /* Appearance of this object is shuffled */
6892 flavor_k_ptr = &k_info[k_ptr->flavor];
6896 /* Appearance of this object is very normal */
6897 flavor_k_ptr = k_ptr;
6900 object_idx[0] = direct_k_idx;
6901 object_old = direct_k_idx;
6904 /* Terminate the list */
6907 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6908 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
6911 /* Terminate the list */
6912 grp_idx[grp_cnt] = -1;
6915 grp_cur = grp_top = 0;
6916 object_cur = object_top = 0;
6921 mode = visual_only ? 0x02 : 0x00;
6926 object_kind *k_ptr, *flavor_k_ptr;
6933 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
6934 if (direct_k_idx < 0) prt("グループ", 4, 0);
6935 prt("名前", 4, max + 3);
6936 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6939 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6940 if (direct_k_idx < 0) prt("Group", 4, 0);
6941 prt("Name", 4, max + 3);
6942 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6946 for (i = 0; i < 78; i++)
6948 Term_putch(i, 5, TERM_WHITE, '=');
6951 if (direct_k_idx < 0)
6953 for (i = 0; i < browser_rows; i++)
6955 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6962 if (direct_k_idx < 0)
6964 /* Scroll group list */
6965 if (grp_cur < grp_top) grp_top = grp_cur;
6966 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6968 /* Display a list of object groups */
6969 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
6971 if (old_grp_cur != grp_cur)
6973 old_grp_cur = grp_cur;
6975 /* Get a list of objects in the current group */
6976 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
6979 /* Scroll object list */
6980 while (object_cur < object_top)
6981 object_top = MAX(0, object_top - browser_rows/2);
6982 while (object_cur >= object_top + browser_rows)
6983 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
6988 /* Display a list of objects in the current group */
6989 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
6993 object_top = object_cur;
6995 /* Display a list of objects in the current group */
6996 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
6998 /* Display visual list below first object */
6999 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7002 /* Get the current object */
7003 k_ptr = &k_info[object_idx[object_cur]];
7005 if (!visual_only && k_ptr->flavor)
7007 /* Appearance of this object is shuffled */
7008 flavor_k_ptr = &k_info[k_ptr->flavor];
7012 /* Appearance of this object is very normal */
7013 flavor_k_ptr = k_ptr;
7018 prt(format("<方向>%s%s%s, ESC",
7019 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
7020 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
7021 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
7024 prt(format("<dir>%s%s%s, ESC",
7025 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
7026 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
7027 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
7033 /* Mega Hack -- track this object */
7034 if (object_cnt) object_kind_track(object_idx[object_cur]);
7036 /* The "current" object changed */
7037 if (object_old != object_idx[object_cur])
7041 /* Remember the "current" object */
7042 object_old = object_idx[object_cur];
7048 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
7052 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7056 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
7061 /* Do visual mode command if needed */
7062 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))
7064 if (direct_k_idx >= 0)
7089 /* Recall on screen */
7090 if (!visual_list && !visual_only && (grp_cnt > 0))
7092 desc_obj_fake(object_idx[object_cur]);
7100 /* Move the cursor */
7101 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
7107 /* Free the "object_idx" array */
7108 C_KILL(object_idx, max_k_idx, IDX);
7113 * Display the features in a group.
7115 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
7116 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
7118 int lit_col[F_LIT_MAX], i, j;
7119 int f_idx_col = use_bigtile ? 62 : 64;
7121 /* Correct columns 1 and 4 */
7122 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
7123 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7124 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
7126 /* Display lines until done */
7127 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
7132 FEAT_IDX f_idx = feat_idx[feat_top + i];
7134 /* Access the index */
7135 feature_type *f_ptr = &f_info[f_idx];
7137 int row_i = row + i;
7139 /* Choose a color */
7140 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
7142 /* Display the name */
7143 c_prt(attr, f_name + f_ptr->name, row_i, col);
7145 /* Hack -- visual_list mode */
7148 /* Display lighting level */
7149 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
7151 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));
7153 if (p_ptr->wizard || visual_only)
7155 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7158 /* Display symbol */
7159 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);
7161 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7162 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7164 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7166 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7168 /* Mega-hack -- Use non-standard colour */
7169 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7171 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7175 /* Clear remaining lines */
7176 for (; i < per_page; i++)
7178 Term_erase(col, row + i, 255);
7184 * Interact with feature visuals.
7186 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7190 FEAT_IDX grp_cur, grp_top, old_grp_cur;
7191 FEAT_IDX feat_cur, feat_top;
7193 FEAT_IDX grp_idx[100];
7197 TERM_LEN column = 0;
7201 bool visual_list = FALSE;
7202 TERM_COLOR attr_top = 0;
7205 TERM_LEN browser_rows;
7208 TERM_COLOR attr_old[F_LIT_MAX];
7209 SYMBOL_CODE char_old[F_LIT_MAX];
7210 TERM_COLOR *cur_attr_ptr;
7211 SYMBOL_CODE *cur_char_ptr;
7213 (void)C_WIPE(attr_old, F_LIT_MAX, byte);
7214 (void)C_WIPE(char_old, F_LIT_MAX, byte);
7216 Term_get_size(&wid, &hgt);
7218 browser_rows = hgt - 8;
7220 /* Allocate the "feat_idx" array */
7221 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
7226 if (direct_f_idx < 0)
7228 /* Check every group */
7229 for (i = 0; feature_group_text[i] != NULL; i++)
7231 /* Measure the label */
7232 len = strlen(feature_group_text[i]);
7234 /* Save the maximum length */
7235 if (len > max) max = len;
7237 /* See if any features are known */
7238 if (collect_features(i, feat_idx, 0x01))
7240 /* Build a list of groups with known features */
7241 grp_idx[grp_cnt++] = i;
7249 feature_type *f_ptr = &f_info[direct_f_idx];
7251 feat_idx[0] = direct_f_idx;
7254 /* Terminate the list */
7257 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7258 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7260 for (i = 0; i < F_LIT_MAX; i++)
7262 attr_old[i] = f_ptr->x_attr[i];
7263 char_old[i] = f_ptr->x_char[i];
7267 /* Terminate the list */
7268 grp_idx[grp_cnt] = -1;
7271 grp_cur = grp_top = 0;
7272 feat_cur = feat_top = 0;
7280 feature_type *f_ptr;
7286 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
7287 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
7288 prt(_("名前", "Name"), 4, max + 3);
7291 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7292 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
7296 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7297 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
7300 for (i = 0; i < 78; i++)
7302 Term_putch(i, 5, TERM_WHITE, '=');
7305 if (direct_f_idx < 0)
7307 for (i = 0; i < browser_rows; i++)
7309 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7316 if (direct_f_idx < 0)
7318 /* Scroll group list */
7319 if (grp_cur < grp_top) grp_top = grp_cur;
7320 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7322 /* Display a list of feature groups */
7323 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7325 if (old_grp_cur != grp_cur)
7327 old_grp_cur = grp_cur;
7329 /* Get a list of features in the current group */
7330 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7333 /* Scroll feature list */
7334 while (feat_cur < feat_top)
7335 feat_top = MAX(0, feat_top - browser_rows/2);
7336 while (feat_cur >= feat_top + browser_rows)
7337 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7342 /* Display a list of features in the current group */
7343 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7347 feat_top = feat_cur;
7349 /* Display a list of features in the current group */
7350 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7352 /* Display visual list below first object */
7353 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7357 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
7358 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
7359 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
7362 /* Get the current feature */
7363 f_ptr = &f_info[feat_idx[feat_cur]];
7364 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7365 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7369 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7373 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7377 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7382 if (visual_list && ((ch == 'A') || (ch == 'a')))
7384 int prev_lighting_level = *lighting_level;
7388 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7389 else (*lighting_level)--;
7393 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7394 else (*lighting_level)++;
7397 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7398 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7400 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7401 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7406 else if ((ch == 'D') || (ch == 'd'))
7408 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
7409 byte prev_x_char = f_ptr->x_char[*lighting_level];
7411 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7415 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7416 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7418 if (prev_x_char != f_ptr->x_char[*lighting_level])
7419 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7421 else *need_redraw = TRUE;
7426 /* Do visual mode command if needed */
7427 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))
7431 /* Restore previous visual settings */
7433 for (i = 0; i < F_LIT_MAX; i++)
7435 f_ptr->x_attr[i] = attr_old[i];
7436 f_ptr->x_char[i] = char_old[i];
7443 if (direct_f_idx >= 0) flag = TRUE;
7444 else *lighting_level = F_LIT_STANDARD;
7447 /* Preserve current visual settings */
7450 for (i = 0; i < F_LIT_MAX; i++)
7452 attr_old[i] = f_ptr->x_attr[i];
7453 char_old[i] = f_ptr->x_char[i];
7455 *lighting_level = F_LIT_STANDARD;
7462 for (i = 0; i < F_LIT_MAX; i++)
7464 attr_idx_feat[i] = f_ptr->x_attr[i];
7465 char_idx_feat[i] = f_ptr->x_char[i];
7474 /* Allow TERM_DARK text */
7475 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7477 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7478 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7496 /* Move the cursor */
7497 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7503 /* Free the "feat_idx" array */
7504 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
7509 * List wanted monsters
7511 static void do_cmd_knowledge_kubi(void)
7516 GAME_TEXT file_name[1024];
7519 /* Open a new file */
7520 fff = my_fopen_temp(file_name, 1024);
7522 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7529 bool listed = FALSE;
7532 fprintf(fff, "今日のターゲット : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "不明"));
7534 fprintf(fff, "賞金首リスト\n");
7536 fprintf(fff, "Today target : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "unknown"));
7538 fprintf(fff, "List of wanted monsters\n");
7540 fprintf(fff, "----------------------------------------------\n");
7542 for (i = 0; i < MAX_KUBI; i++)
7544 if (kubi_r_idx[i] <= 10000)
7546 fprintf(fff,"%s\n", r_name + r_info[kubi_r_idx[i]].name);
7554 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7559 /* Display the file contents */
7560 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7562 /* Remove the file */
7567 * List virtues & status
7569 static void do_cmd_knowledge_virtues(void)
7572 GAME_TEXT file_name[1024];
7574 /* Open a new file */
7575 fff = my_fopen_temp(file_name, 1024);
7577 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7584 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7589 /* Display the file contents */
7590 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7592 /* Remove the file */
7600 static void do_cmd_knowledge_dungeon(void)
7604 GAME_TEXT file_name[1024];
7607 /* Open a new file */
7608 fff = my_fopen_temp(file_name, 1024);
7610 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7617 for (i = 1; i < max_d_idx; i++)
7621 if (!d_info[i].maxdepth) continue;
7622 if (!max_dlv[i]) continue;
7623 if (d_info[i].final_guardian)
7625 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7627 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7629 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7634 /* Display the file contents */
7635 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7637 /* Remove the file */
7642 * List virtues & status
7645 static void do_cmd_knowledge_stat(void)
7649 GAME_TEXT file_name[1024];
7652 /* Open a new file */
7653 fff = my_fopen_temp(file_name, 1024);
7655 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7662 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7663 (2 * p_ptr->hitdie +
7664 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7667 if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "現在の体力ランク : %d/100\n\n", percent);
7668 else fprintf(fff, "現在の体力ランク : ???\n\n");
7669 fprintf(fff, "能力の最大値\n\n");
7671 if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "Your current Life Rating is %d/100.\n\n", percent);
7672 else fprintf(fff, "Your current Life Rating is ???.\n\n");
7673 fprintf(fff, "Limits of maximum stats\n\n");
7675 for (v_nr = 0; v_nr < A_MAX; v_nr++)
7677 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);
7678 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7685 /* Display the file contents */
7686 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7688 /* Remove the file */
7694 * Print all active quests
7696 static void do_cmd_knowledge_quests_current(FILE *fff)
7699 char rand_tmp_str[120] = "\0";
7700 GAME_TEXT name[MAX_NLEN];
7701 monster_race *r_ptr;
7703 int rand_level = 100;
7706 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7708 for (i = 1; i < max_q_idx; i++)
7710 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7711 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7712 (quest[i].status == QUEST_STATUS_COMPLETED))
7714 /* Set the quest number temporary */
7715 IDX old_quest = p_ptr->inside_quest;
7718 /* Clear the text */
7719 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7720 quest_text_line = 0;
7722 p_ptr->inside_quest = i;
7724 /* Get the quest text */
7725 init_flags = INIT_SHOW_TEXT;
7727 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7729 /* Reset the old quest number */
7730 p_ptr->inside_quest = old_quest;
7732 /* No info from "silent" quests */
7733 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7737 if (quest[i].type != QUEST_TYPE_RANDOM)
7739 char note[80] = "\0";
7741 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
7743 switch (quest[i].type)
7745 case QUEST_TYPE_KILL_LEVEL:
7746 case QUEST_TYPE_KILL_ANY_LEVEL:
7747 r_ptr = &r_info[quest[i].r_idx];
7748 strcpy(name, r_name + r_ptr->name);
7749 if (quest[i].max_num > 1)
7752 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
7753 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7756 sprintf(note," - kill %d %s, have killed %d.",
7757 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7761 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
7764 case QUEST_TYPE_FIND_ARTIFACT:
7767 artifact_type *a_ptr = &a_info[quest[i].k_idx];
7769 object_type *q_ptr = &forge;
7770 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
7771 object_prep(q_ptr, k_idx);
7772 q_ptr->name1 = quest[i].k_idx;
7773 q_ptr->ident = IDENT_STORE;
7774 object_desc(name, q_ptr, OD_NAME_ONLY);
7776 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find out %s."), name);
7778 case QUEST_TYPE_FIND_EXIT:
7779 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
7782 case QUEST_TYPE_KILL_NUMBER:
7784 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
7785 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
7787 sprintf(note," - Kill %d monsters, have killed %d.",
7788 (int)quest[i].max_num, (int)quest[i].cur_num);
7792 case QUEST_TYPE_KILL_ALL:
7793 case QUEST_TYPE_TOWER:
7794 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
7799 /* Print the quest info */
7800 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
7801 quest[i].name, (int)quest[i].level, note);
7803 fputs(tmp_str, fff);
7805 if (quest[i].status == QUEST_STATUS_COMPLETED)
7807 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
7808 fputs(tmp_str, fff);
7814 while (quest_text[j][0] && j < 10)
7816 fprintf(fff, " %s\n", quest_text[j]);
7821 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
7824 rand_level = quest[i].level;
7826 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
7828 /* Print the quest info */
7829 r_ptr = &r_info[quest[i].r_idx];
7830 strcpy(name, r_name + r_ptr->name);
7832 if (quest[i].max_num > 1)
7835 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
7836 quest[i].name, (int)quest[i].level,
7837 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7841 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
7842 quest[i].name, (int)quest[i].level,
7843 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7848 sprintf(rand_tmp_str,_(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
7849 quest[i].name, (int)quest[i].level, name);
7856 /* Print the current random quest */
7857 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
7859 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7863 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
7866 char playtime_str[16];
7867 quest_type* const q_ptr = &quest[q_idx];
7869 if (is_fixed_quest_idx(q_idx))
7871 /* Set the quest number temporary */
7872 IDX old_quest = p_ptr->inside_quest;
7874 p_ptr->inside_quest = q_idx;
7877 init_flags = INIT_NAME_ONLY;
7879 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7881 /* Reset the old quest number */
7882 p_ptr->inside_quest = old_quest;
7884 /* No info from "silent" quests */
7885 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
7888 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
7889 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
7891 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
7893 /* Print the quest info */
7894 if (q_ptr->complev == 0)
7897 _(" %-35s (%3d階) - 不戦勝 - %s\n",
7898 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
7899 r_name+r_info[q_ptr->r_idx].name,
7900 (int)q_ptr->level, playtime_str);
7905 _(" %-35s (%3d階) - レベル%2d - %s\n",
7906 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
7907 r_name+r_info[q_ptr->r_idx].name,
7915 /* Print the quest info */
7917 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
7918 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
7919 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
7922 fputs(tmp_str, fff);
7928 * Print all finished quests
7930 void do_cmd_knowledge_quests_completed(FILE *fff, IDX quest_num[])
7935 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
7936 for (i = 1; i < max_q_idx; i++)
7938 IDX q_idx = quest_num[i];
7939 quest_type* const q_ptr = &quest[q_idx];
7941 if (q_ptr->status == QUEST_STATUS_FINISHED &&
7942 do_cmd_knowledge_quests_aux(fff, q_idx))
7947 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7952 * Print all failed quests
7954 void do_cmd_knowledge_quests_failed(FILE *fff, IDX quest_num[])
7959 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
7960 for (i = 1; i < max_q_idx; i++)
7962 IDX q_idx = quest_num[i];
7963 quest_type* const q_ptr = &quest[q_idx];
7965 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
7966 do_cmd_knowledge_quests_aux(fff, q_idx))
7971 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7976 * Print all random quests
7978 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
7984 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
7985 for (i = 1; i < max_q_idx; i++)
7987 /* No info from "silent" quests */
7988 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7990 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
7994 /* Print the quest info */
7995 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
7996 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
7997 fputs(tmp_str, fff);
8000 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
8004 bool ang_sort_comp_quest_num(vptr u, vptr v, int a, int b)
8006 QUEST_IDX *q_num = (QUEST_IDX *)u;
8007 quest_type *qa = &quest[q_num[a]];
8008 quest_type *qb = &quest[q_num[b]];
8013 return (qa->comptime != qb->comptime) ?
8014 (qa->comptime < qb->comptime) :
8015 (qa->level <= qb->level);
8018 void ang_sort_swap_quest_num(vptr u, vptr v, int a, int b)
8020 QUEST_IDX *q_num = (QUEST_IDX *)u;
8027 q_num[a] = q_num[b];
8033 * Print quest status of all active quests
8035 static void do_cmd_knowledge_quests(void)
8038 GAME_TEXT file_name[1024];
8043 /* Open a new file */
8044 fff = my_fopen_temp(file_name, 1024);
8047 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8052 /* Allocate Memory */
8053 C_MAKE(quest_num, max_q_idx, IDX);
8055 /* Sort by compete level */
8056 for (i = 1; i < max_q_idx; i++) quest_num[i] = i;
8057 ang_sort_comp = ang_sort_comp_quest_num;
8058 ang_sort_swap = ang_sort_swap_quest_num;
8059 ang_sort(quest_num, &dummy, max_q_idx);
8061 /* Dump Quest Information */
8062 do_cmd_knowledge_quests_current(fff);
8064 do_cmd_knowledge_quests_completed(fff, quest_num);
8066 do_cmd_knowledge_quests_failed(fff, quest_num);
8070 do_cmd_knowledge_quests_wiz_random(fff);
8074 /* Display the file contents */
8075 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
8077 /* Remove the file */
8081 C_KILL(quest_num, max_q_idx, IDX);
8088 static void do_cmd_knowledge_home(void)
8093 GAME_TEXT file_name[1024];
8095 GAME_TEXT o_name[MAX_NLEN];
8098 process_dungeon_file("w_info.txt", 0, 0, max_wild_y, max_wild_x);
8100 /* Open a new file */
8101 fff = my_fopen_temp(file_name, 1024);
8103 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8110 /* Print all homes in the different towns */
8111 st_ptr = &town[1].store[STORE_HOME];
8113 /* Home -- if anything there */
8114 if (st_ptr->stock_num)
8119 /* Header with name of the town */
8120 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
8122 /* Dump all available items */
8123 for (i = 0; i < st_ptr->stock_num; i++)
8126 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
8127 object_desc(o_name, &st_ptr->stock[i], 0);
8128 if (strlen(o_name) <= 80-3)
8130 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8136 for (n = 0, t = o_name; n < 80-3; n++, t++)
8137 if(iskanji(*t)) {t++; n++;}
8138 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
8140 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
8141 fprintf(fff, " %.77s\n", o_name+n);
8144 object_desc(o_name, &st_ptr->stock[i], 0);
8145 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8150 /* Add an empty line */
8151 fprintf(fff, "\n\n");
8156 /* Display the file contents */
8157 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
8159 /* Remove the file */
8165 * Check the status of "autopick"
8167 static void do_cmd_knowledge_autopick(void)
8171 GAME_TEXT file_name[1024];
8173 /* Open a new file */
8174 fff = my_fopen_temp(file_name, 1024);
8178 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8185 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
8189 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
8190 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
8193 for (k = 0; k < max_autopick; k++)
8196 byte act = autopick_list[k].action;
8197 if (act & DONT_AUTOPICK)
8199 tmp = _("放置", "Leave");
8201 else if (act & DO_AUTODESTROY)
8203 tmp = _("破壊", "Destroy");
8205 else if (act & DO_AUTOPICK)
8207 tmp = _("拾う", "Pickup");
8211 tmp = _("確認", "Query");
8214 if (act & DO_DISPLAY)
8215 fprintf(fff, "%11s", format("[%s]", tmp));
8217 fprintf(fff, "%11s", format("(%s)", tmp));
8219 tmp = autopick_line_from_entry(&autopick_list[k]);
8220 fprintf(fff, " %s", tmp);
8225 /* Display the file contents */
8226 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8228 /* Remove the file */
8234 * Interact with "knowledge"
8236 void do_cmd_knowledge(void)
8239 bool need_redraw = FALSE;
8241 /* File type is "TEXT" */
8242 FILE_TYPE(FILE_TYPE_TEXT);
8245 /* Interact until done */
8250 /* Ask for a choice */
8251 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
8252 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
8254 /* Give some choices */
8258 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8259 prt("(2) 既知のアイテム の一覧", 7, 5);
8260 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8261 prt("(4) 既知のモンスター の一覧", 9, 5);
8262 prt("(5) 倒した敵の数 の一覧", 10, 5);
8263 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8264 prt("(7) 現在のペット の一覧", 12, 5);
8265 prt("(8) 我が家のアイテム の一覧", 13, 5);
8266 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8267 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8271 prt("(a) 自分に関する情報 の一覧", 6, 5);
8272 prt("(b) 突然変異 の一覧", 7, 5);
8273 prt("(c) 武器の経験値 の一覧", 8, 5);
8274 prt("(d) 魔法の経験値 の一覧", 9, 5);
8275 prt("(e) 技能の経験値 の一覧", 10, 5);
8276 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8277 prt("(g) 入ったダンジョン の一覧", 12, 5);
8278 prt("(h) 実行中のクエスト の一覧", 13, 5);
8279 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8284 prt("(1) Display known artifacts", 6, 5);
8285 prt("(2) Display known objects", 7, 5);
8286 prt("(3) Display remaining uniques", 8, 5);
8287 prt("(4) Display known monster", 9, 5);
8288 prt("(5) Display kill count", 10, 5);
8289 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8290 prt("(7) Display current pets", 12, 5);
8291 prt("(8) Display home inventory", 13, 5);
8292 prt("(9) Display *identified* equip.", 14, 5);
8293 prt("(0) Display terrain symbols.", 15, 5);
8297 prt("(a) Display about yourself", 6, 5);
8298 prt("(b) Display mutations", 7, 5);
8299 prt("(c) Display weapon proficiency", 8, 5);
8300 prt("(d) Display spell proficiency", 9, 5);
8301 prt("(e) Display misc. proficiency", 10, 5);
8302 prt("(f) Display virtues", 11, 5);
8303 prt("(g) Display dungeons", 12, 5);
8304 prt("(h) Display current quests", 13, 5);
8305 prt("(i) Display auto pick/destroy", 14, 5);
8309 prt(_("-続く-", "-more-"), 17, 8);
8310 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
8311 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
8312 /*prt("-) 前ページ", 21, 60);*/
8313 prt(_("コマンド:", "Command: "), 20, 0);
8316 if (i == ESCAPE) break;
8319 case ' ': /* Page change */
8323 case '1': /* Artifacts */
8324 do_cmd_knowledge_artifacts();
8326 case '2': /* Objects */
8327 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8329 case '3': /* Uniques */
8330 do_cmd_knowledge_uniques();
8332 case '4': /* Monsters */
8333 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8335 case '5': /* Kill count */
8336 do_cmd_knowledge_kill_count();
8338 case '6': /* wanted */
8339 if (!vanilla_town) do_cmd_knowledge_kubi();
8341 case '7': /* Pets */
8342 do_cmd_knowledge_pets();
8344 case '8': /* Home */
8345 do_cmd_knowledge_home();
8347 case '9': /* Resist list */
8348 do_cmd_knowledge_inven();
8350 case '0': /* Feature list */
8352 IDX lighting_level = F_LIT_STANDARD;
8353 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8357 case 'a': /* Max stat */
8358 do_cmd_knowledge_stat();
8360 case 'b': /* Mutations */
8361 do_cmd_knowledge_mutations();
8363 case 'c': /* weapon-exp */
8364 do_cmd_knowledge_weapon_exp();
8366 case 'd': /* spell-exp */
8367 do_cmd_knowledge_spell_exp();
8369 case 'e': /* skill-exp */
8370 do_cmd_knowledge_skill_exp();
8372 case 'f': /* Virtues */
8373 do_cmd_knowledge_virtues();
8375 case 'g': /* Dungeon */
8376 do_cmd_knowledge_dungeon();
8378 case 'h': /* Quests */
8379 do_cmd_knowledge_quests();
8381 case 'i': /* Autopick */
8382 do_cmd_knowledge_autopick();
8384 default: /* Unknown option */
8392 if (need_redraw) do_cmd_redraw();
8397 * Check on the status of an active quest
8399 void do_cmd_checkquest(void)
8401 /* File type is "TEXT" */
8402 FILE_TYPE(FILE_TYPE_TEXT);
8406 do_cmd_knowledge_quests();
8412 * Display the time and date
8414 void do_cmd_time(void)
8416 int day, hour, min, full, start, end, num;
8424 extract_day_hour_min(&day, &hour, &min);
8426 full = hour * 100 + min;
8433 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8435 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8436 else strcpy(day_buf, "*****");
8439 msg_format("%s日目, 時刻は%d:%02d %sです。",
8440 day_buf, (hour % 12 == 0) ? 12 : (hour % 12),
8441 min, (hour < 12) ? "AM" : "PM");
8443 msg_format("This is day %s. The time is %d:%02d %s.",
8444 day_buf, (hour % 12 == 0) ? 12 : (hour % 12),
8445 min, (hour < 12) ? "AM" : "PM");
8450 if (!randint0(10) || p_ptr->image)
8452 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8456 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8459 /* Open this file */
8460 fff = my_fopen(buf, "rt");
8464 /* Find this time */
8465 while (!my_fgets(fff, buf, sizeof(buf)))
8467 /* Ignore comments */
8468 if (!buf[0] || (buf[0] == '#')) continue;
8470 /* Ignore invalid lines */
8471 if (buf[1] != ':') continue;
8473 /* Process 'Start' */
8476 /* Extract the starting time */
8477 start = atoi(buf + 2);
8479 /* Assume valid for an hour */
8489 /* Extract the ending time */
8490 end = atoi(buf + 2);
8496 /* Ignore incorrect range */
8497 if ((start > full) || (full > end)) continue;
8499 /* Process 'Description' */
8504 /* Apply the randomizer */
8505 if (!randint0(num)) strcpy(desc, buf + 2);