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)
971 /* Hack -- react to changes */
972 Term_xtra(TERM_XTRA_REACT, 0);
975 /* Combine and Reorder the pack (later) */
976 p_ptr->notice |= (PN_COMBINE | PN_REORDER);
979 p_ptr->update |= (PU_TORCH);
980 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
981 p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
982 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
983 p_ptr->update |= (PU_MONSTERS);
985 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
987 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
988 p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
994 if (p_ptr->prace == RACE_ANDROID) calc_android_exp();
997 /* Redraw every window */
998 for (j = 0; j < 8; j++)
1001 if (!angband_term[j]) continue;
1004 Term_activate(angband_term[j]);
1013 * @brief 名前を変更するコマンドのメインルーチン
1014 * Hack -- change name
1017 void do_cmd_change_name(void)
1032 /* Display the player */
1033 display_player(mode);
1038 display_player(mode);
1043 Term_putstr(2, 23, -1, TERM_WHITE,
1044 "['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]");
1046 Term_putstr(2, 23, -1, TERM_WHITE,
1047 "['c' to change name, 'f' to file, 'h' to change mode, or ESC]");
1055 if (c == ESCAPE) break;
1062 /* Process the player name */
1063 process_player_name(FALSE);
1069 sprintf(tmp, "%s.txt", player_base);
1070 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1072 if (tmp[0] && (tmp[0] != ' '))
1074 file_character(tmp);
1092 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1099 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1100 * Recall the most recent message
1103 void do_cmd_message_one(void)
1105 /* Recall one message */
1106 prt(format("> %s", message_str(0)), 0, 0);
1111 * @brief メッセージのログを表示するコマンドのメインルーチン
1112 * Recall the most recent message
1116 * Show previous messages to the user -BEN-
1118 * The screen format uses line 0 and 23 for headers and prompts,
1119 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1121 * This command shows you which commands you are viewing, and allows
1122 * you to "search" for strings in the recall.
1124 * Note that messages may be longer than 80 characters, but they are
1125 * displayed using "infinite" length, with a special sub-command to
1126 * "slide" the virtual display to the left or right.
1128 * Attempt to only hilite the matching portions of the string.
1131 void do_cmd_messages(int num_now)
1135 char shower_str[81];
1136 char finder_str[81];
1142 Term_get_size(&wid, &hgt);
1144 /* Number of message lines in a screen */
1145 num_lines = hgt - 4;
1148 strcpy(finder_str, "");
1151 strcpy(shower_str, "");
1153 /* Total messages */
1156 /* Start on first message */
1161 /* Process requests until done */
1167 /* Dump up to 20 lines of messages */
1168 for (j = 0; (j < num_lines) && (i + j < n); j++)
1170 cptr msg = message_str(i+j);
1172 /* Dump the messages, bottom to top */
1173 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1175 /* Hilite "shower" */
1176 if (shower && shower[0])
1180 /* Display matches */
1181 while ((str = my_strstr(str, shower)) != NULL)
1183 int len = strlen(shower);
1185 /* Display the match */
1186 Term_putstr(str-msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1194 /* Erase remaining lines */
1195 for (; j < num_lines; j++)
1197 Term_erase(0, num_lines + 1 - j, 255);
1200 /* Display header */
1202 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1203 i, i + j - 1, n), 0, 0);
1205 /* Display prompt (not very informative) */
1206 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1207 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1209 skey = inkey_special(TRUE);
1211 /* Exit on Escape */
1212 if (skey == ESCAPE) break;
1214 /* Hack -- Save the old index */
1219 /* Hack -- handle show */
1222 prt(_("強調: ", "Show: "), hgt - 1, 0);
1224 /* Get a "shower" string, or continue */
1225 strcpy(back_str, shower_str);
1226 if (askfor(shower_str, 80))
1229 shower = shower_str[0] ? shower_str : NULL;
1231 else strcpy(shower_str, back_str);
1235 /* Hack -- handle find */
1242 prt(_("検索: ", "Find: "), hgt - 1, 0);
1244 /* Get a "finder" string, or continue */
1245 strcpy(back_str, finder_str);
1246 if (!askfor(finder_str, 80))
1248 strcpy(finder_str, back_str);
1251 else if (!finder_str[0])
1253 shower = NULL; /* Stop showing */
1258 shower = finder_str;
1261 for (z = i + 1; z < n; z++)
1263 cptr msg = message_str(z);
1266 if (my_strstr(msg, finder_str))
1277 /* Recall 1 older message */
1279 /* Go to the oldest line */
1283 /* Recall 1 newer message */
1285 /* Go to the newest line */
1289 /* Recall 1 older message */
1294 /* Go older if legal */
1295 i = MIN(i + 1, n - num_lines);
1298 /* Recall 10 older messages */
1300 /* Go older if legal */
1301 i = MIN(i + 10, n - num_lines);
1304 /* Recall 20 older messages */
1309 /* Go older if legal */
1310 i = MIN(i + num_lines, n - num_lines);
1313 /* Recall 20 newer messages */
1317 /* Go newer (if able) */
1318 i = MAX(0, i - num_lines);
1321 /* Recall 10 newer messages */
1323 /* Go newer (if able) */
1327 /* Recall 1 newer messages */
1330 /* Go newer (if able) */
1335 /* Hack -- Error of some kind */
1343 * @brief チートオプションを変更するコマンドのメインルーチン
1344 * Interact with some options for cheating
1345 * @param info 表示メッセージ
1348 static void do_cmd_options_cheat(cptr info)
1351 int i, k = 0, n = CHEAT_MAX;
1355 /* Interact with the player */
1361 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, ESC で決定 )", "%s (RET to advance, y/n to set, ESC to accept) "), info);
1366 /* 詐欺オプションをうっかりいじってしまう人がいるようなので注意 */
1367 prt(" << 注意 >>", 11, 0);
1368 prt(" 詐欺オプションを一度でも設定すると、スコア記録が残らなくなります!", 12, 0);
1369 prt(" 後に解除してもダメですので、勝利者を目指す方はここのオプションはい", 13, 0);
1370 prt(" じらないようにして下さい。", 14, 0);
1372 /* Display the options */
1373 for (i = 0; i < n; i++)
1375 byte a = TERM_WHITE;
1377 /* Color current option */
1378 if (i == k) a = TERM_L_BLUE;
1380 /* Display the option text */
1381 sprintf(buf, "%-48s: %s (%s)",
1382 cheat_info[i].o_desc,
1383 (*cheat_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1384 cheat_info[i].o_text);
1385 c_prt(a, buf, i + 2, 0);
1388 /* Hilite current option */
1389 move_cursor(k + 2, 50);
1395 * HACK - Try to translate the key into a direction
1396 * to allow using the roguelike keys for navigation.
1398 dir = get_keymap_dir(ch);
1399 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1413 k = (n + k - 1) % n;
1431 do_cmd_write_nikki(NIKKI_BUNSHOU, 0,
1432 _("詐欺オプションをONにして、スコアを残せなくなった。", "give up sending score to use cheating options."));
1433 p_ptr->noscore |= (cheat_info[k].o_set * 256 + cheat_info[k].o_bit);
1434 (*cheat_info[k].o_var) = TRUE;
1443 (*cheat_info[k].o_var) = FALSE;
1450 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), cheat_info[k].o_text);
1451 /* Peruse the help file */
1452 (void)show_file(TRUE, buf, NULL, 0, 0);
1469 * @brief セーブ頻度ターンの次の値を返す
1470 * @param current 現在のセーブ頻度ターン値
1471 * @return 次のセーブ頻度ターン値
1473 static s16b toggle_frequency(s16b current)
1478 case 50: return 100;
1479 case 100: return 250;
1480 case 250: return 500;
1481 case 500: return 1000;
1482 case 1000: return 2500;
1483 case 2500: return 5000;
1484 case 5000: return 10000;
1485 case 10000: return 25000;
1492 * @brief 自動セーブオプションを変更するコマンドのメインルーチン
1493 * @param info 表示メッセージ
1496 static void do_cmd_options_autosave(cptr info)
1499 int i, k = 0, n = 2;
1504 /* Interact with the player */
1508 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ",
1509 "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info);
1513 /* Display the options */
1514 for (i = 0; i < n; i++)
1516 byte a = TERM_WHITE;
1518 /* Color current option */
1519 if (i == k) a = TERM_L_BLUE;
1521 /* Display the option text */
1522 sprintf(buf, "%-48s: %s (%s)",
1523 autosave_info[i].o_desc,
1524 (*autosave_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1525 autosave_info[i].o_text);
1526 c_prt(a, buf, i + 2, 0);
1528 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1530 /* Hilite current option */
1531 move_cursor(k + 2, 50);
1547 k = (n + k - 1) % n;
1565 (*autosave_info[k].o_var) = TRUE;
1574 (*autosave_info[k].o_var) = FALSE;
1582 autosave_freq = toggle_frequency(autosave_freq);
1583 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1589 (void)show_file(TRUE, _("joption.txt#Autosave", "option.txt#Autosave"), NULL, 0, 0);
1605 * @brief 標準オプションを変更するコマンドのサブルーチン /
1606 * Interact with some options
1607 * @param page オプションページ番号
1608 * @param info 表示メッセージ
1611 void do_cmd_options_aux(int page, cptr info)
1614 int i, k = 0, n = 0, l;
1617 bool browse_only = (page == OPT_PAGE_BIRTH) && character_generated &&
1618 (!p_ptr->wizard || !allow_debug_opts);
1621 /* Lookup the options */
1622 for (i = 0; i < 24; i++) opt[i] = 0;
1624 /* Scan the options */
1625 for (i = 0; option_info[i].o_desc; i++)
1627 /* Notice options on this "page" */
1628 if (option_info[i].o_page == page) opt[n++] = i;
1632 /* Interact with the player */
1638 sprintf(buf, _("%s (リターン:次, %sESC:終了, ?:ヘルプ) ", "%s (RET:next, %s, ?:help) "),
1639 info, browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept"));
1642 /* HACK -- description for easy-auto-destroy options */
1643 if (page == OPT_PAGE_AUTODESTROY)
1644 c_prt(TERM_YELLOW, _("以下のオプションは、簡易自動破壊を使用するときのみ有効",
1645 "Following options will protect items from easy auto-destroyer."), 6, _(6, 3));
1647 /* Display the options */
1648 for (i = 0; i < n; i++)
1650 byte a = TERM_WHITE;
1652 /* Color current option */
1653 if (i == k) a = TERM_L_BLUE;
1655 /* Display the option text */
1656 sprintf(buf, "%-48s: %s (%.19s)",
1657 option_info[opt[i]].o_desc,
1658 (*option_info[opt[i]].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1659 option_info[opt[i]].o_text);
1660 if ((page == OPT_PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
1661 else c_prt(a, buf, i + 2, 0);
1664 if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) l = 3;
1667 /* Hilite current option */
1668 move_cursor(k + 2 + l, 50);
1674 * HACK - Try to translate the key into a direction
1675 * to allow using the roguelike keys for navigation.
1677 dir = get_keymap_dir(ch);
1678 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1692 k = (n + k - 1) % n;
1709 if (browse_only) break;
1710 (*option_info[opt[k]].o_var) = TRUE;
1719 if (browse_only) break;
1720 (*option_info[opt[k]].o_var) = FALSE;
1728 if (!browse_only) (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
1734 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), option_info[opt[k]].o_text);
1735 /* Peruse the help file */
1736 (void)show_file(TRUE, buf, NULL, 0, 0);
1753 * @brief ウィンドウオプションを変更するコマンドのメインルーチン /
1754 * Modify the "window" options
1757 static void do_cmd_options_win(void)
1767 /* Memorize old flags */
1768 for (j = 0; j < 8; j++)
1770 /* Acquire current flags */
1771 old_flag[j] = window_flag[j];
1780 prt(_("ウィンドウ・フラグ (<方向>で移動, tでチェンジ, y/n でセット, ESC)", "Window Flags (<dir>, t, y, n, ESC) "), 0, 0);
1782 /* Display the windows */
1783 for (j = 0; j < 8; j++)
1785 byte a = TERM_WHITE;
1787 cptr s = angband_term_name[j];
1790 if (j == x) a = TERM_L_BLUE;
1792 /* Window name, staggered, centered */
1793 Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
1796 /* Display the options */
1797 for (i = 0; i < 16; i++)
1799 byte a = TERM_WHITE;
1801 cptr str = window_flag_desc[i];
1804 if (i == y) a = TERM_L_BLUE;
1807 if (!str) str = _("(未使用)", "(Unused option)");
1810 Term_putstr(0, i + 5, -1, a, str);
1812 /* Display the windows */
1813 for (j = 0; j < 8; j++)
1819 if ((i == y) && (j == x)) a = TERM_L_BLUE;
1822 if (window_flag[j] & (1L << i)) c = 'X';
1825 Term_putch(35 + j * 5, i + 5, a, c);
1830 Term_gotoxy(35 + x * 5, y + 5);
1848 for (j = 0; j < 8; j++)
1850 window_flag[j] &= ~(1L << y);
1854 for (i = 0; i < 16; i++)
1856 window_flag[x] &= ~(1L << i);
1869 window_flag[x] |= (1L << y);
1877 window_flag[x] &= ~(1L << y);
1883 (void)show_file(TRUE, _("joption.txt#Window", "option.txt#Window"), NULL, 0, 0);
1891 d = get_keymap_dir(ch);
1893 x = (x + ddx[d] + 8) % 8;
1894 y = (y + ddy[d] + 16) % 16;
1901 /* Notice changes */
1902 for (j = 0; j < 8; j++)
1907 if (!angband_term[j]) continue;
1909 /* Ignore non-changes */
1910 if (window_flag[j] == old_flag[j]) continue;
1913 Term_activate(angband_term[j]);
1930 option_fields[OPT_NUM] =
1933 { '1', " キー入力 オプション", 3 },
1934 { '2', " マップ画面 オプション", 4 },
1935 { '3', " テキスト表示 オプション", 5 },
1936 { '4', " ゲームプレイ オプション", 6 },
1937 { '5', " 行動中止関係 オプション", 7 },
1938 { '6', " 簡易自動破壊 オプション", 8 },
1939 { 'r', " プレイ記録 オプション", 9 },
1941 { 'p', "自動拾いエディタ", 11 },
1942 { 'd', " 基本ウェイト量 ", 12 },
1943 { 'h', "低ヒットポイント", 13 },
1944 { 'm', " 低魔力色閾値 ", 14 },
1945 { 'a', " 自動セーブ オプション", 15 },
1946 { 'w', "ウインドウフラグ", 16 },
1948 { 'b', " 初期 オプション (参照のみ)", 18 },
1949 { 'c', " 詐欺 オプション", 19 },
1951 { '1', "Input Options", 3 },
1952 { '2', "Map Screen Options", 4 },
1953 { '3', "Text Display Options", 5 },
1954 { '4', "Game-Play Options", 6 },
1955 { '5', "Disturbance Options", 7 },
1956 { '6', "Easy Auto-Destroyer Options", 8 },
1957 { 'r', "Play record Options", 9 },
1959 { 'p', "Auto-picker/destroyer editor", 11 },
1960 { 'd', "Base Delay Factor", 12 },
1961 { 'h', "Hitpoint Warning", 13 },
1962 { 'm', "Mana Color Threshold", 14 },
1963 { 'a', "Autosave Options", 15 },
1964 { 'w', "Window Flags", 16 },
1966 { 'b', "Birth Options (Browse Only)", 18 },
1967 { 'c', "Cheat Options", 19 },
1973 * @brief 標準オプションを変更するコマンドのメインルーチン /
1974 * Set or unset various options.
1978 * The user must use the "Ctrl-R" command to "adapt" to changes
1979 * in any options which control "visual" aspects of the game.
1982 void do_cmd_options(void)
1994 /* Does not list cheat option when cheat option is off */
1995 if (!p_ptr->noscore && !allow_debug_opts) n--;
1998 /* Why are we here */
1999 prt(_("[ オプションの設定 ]", "TinyAngband options"), 1, 0);
2003 /* Give some choices */
2004 for (i = 0; i < n; i++)
2006 byte a = TERM_WHITE;
2007 if (i == y) a = TERM_L_BLUE;
2008 Term_putstr(5, option_fields[i].row, -1, a,
2009 format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name));
2012 prt(_("<方向>で移動, Enterで決定, ESCでキャンセル, ?でヘルプ: ", "Move to <dir>, Select to Enter, Cancel to ESC, ? to help: "), 21, 0);
2015 skey = inkey_special(TRUE);
2016 if (!(skey & SKEY_MASK)) k = (char)skey;
2020 if (k == ESCAPE) break;
2022 if (my_strchr("\n\r ", k))
2024 k = option_fields[y].key;
2028 for (i = 0; i < n; i++)
2030 if (tolower(k) == option_fields[i].key) break;
2033 /* Command is found */
2036 /* Hack -- browse help */
2037 if (k == '?') break;
2041 if (skey == SKEY_UP) d = 8;
2042 if (skey == SKEY_DOWN) d = 2;
2043 y = (y + ddy[d] + n) % n;
2048 if (k == ESCAPE) break;
2055 /* Process the general options */
2056 do_cmd_options_aux(OPT_PAGE_INPUT, _("キー入力オプション", "Input Options"));
2062 /* Process the general options */
2063 do_cmd_options_aux(OPT_PAGE_MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
2070 do_cmd_options_aux(OPT_PAGE_TEXT, _("テキスト表示オプション", "Text Display Options"));
2077 do_cmd_options_aux(OPT_PAGE_GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
2084 do_cmd_options_aux(OPT_PAGE_DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
2091 do_cmd_options_aux(OPT_PAGE_AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
2095 /* Play-record Options */
2100 do_cmd_options_aux(OPT_PAGE_PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
2109 do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ?
2110 _("初期オプション(参照のみ)", "Birth Options(browse only)") :
2111 _("初期オプション((*)はスコアに影響)", "Birth Options((*)s effect score)"));
2115 /* Cheating Options */
2118 if (!p_ptr->noscore && !allow_debug_opts)
2120 /* Cheat options are not permitted */
2126 do_cmd_options_cheat(_("詐欺師は決して勝利できない!", "Cheaters never win"));
2133 do_cmd_options_autosave(_("自動セーブ", "Autosave"));
2142 do_cmd_options_win();
2143 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL |
2144 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
2145 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
2146 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON |
2151 /* Auto-picker/destroyer editor */
2155 do_cmd_edit_autopick();
2159 /* Hack -- Delay Speed */
2165 prt(_("コマンド: 基本ウェイト量", "Command: Base Delay Factor"), 19, 0);
2167 /* Get a new value */
2170 int msec = delay_factor * delay_factor * delay_factor;
2171 prt(format(_("現在のウェイト: %d (%dミリ秒)", "Current base delay factor: %d (%d msec)"), delay_factor, msec), 22, 0);
2172 prt(_("ウェイト (0-9) ESCで決定: ", "Delay Factor (0-9 or ESC to accept): "), 20, 0);
2174 if (k == ESCAPE) break;
2177 (void)show_file(TRUE, _("joption.txt#BaseDelay", "option.txt#BaseDelay"), NULL, 0, 0);
2180 else if (isdigit(k)) delay_factor = D2I(k);
2187 /* Hack -- hitpoint warning factor */
2193 prt(_("コマンド: 低ヒットポイント警告", "Command: Hitpoint Warning"), 19, 0);
2195 /* Get a new value */
2198 prt(format(_("現在の低ヒットポイント警告: %d0%%", "Current hitpoint warning: %d0%%"), hitpoint_warn), 22, 0);
2199 prt(_("低ヒットポイント警告 (0-9) ESCで決定: ", "Hitpoint Warning (0-9 or ESC to accept): "), 20, 0);
2201 if (k == ESCAPE) break;
2204 (void)show_file(TRUE, _("joption.txt#Hitpoint", "option.txt#Hitpoint"), NULL, 0, 0);
2207 else if (isdigit(k)) hitpoint_warn = D2I(k);
2214 /* Hack -- mana color factor */
2220 prt(_("コマンド: 低魔力色閾値", "Command: Mana Color Threshold"), 19, 0);
2222 /* Get a new value */
2225 prt(format(_("現在の低魔力色閾値: %d0%%", "Current mana color threshold: %d0%%"), mana_warn), 22, 0);
2226 prt(_("低魔力閾値 (0-9) ESCで決定: ", "Mana color Threshold (0-9 or ESC to accept): "), 20, 0);
2228 if (k == ESCAPE) break;
2231 (void)show_file(TRUE, _("joption.txt#Manapoint", "option.txt#Manapoint"), NULL, 0, 0);
2234 else if (isdigit(k)) mana_warn = D2I(k);
2242 (void)show_file(TRUE, _("joption.txt", "option.txt"), NULL, 0, 0);
2246 /* Unknown option */
2259 /* Hack - Redraw equippy chars */
2260 p_ptr->redraw |= (PR_EQUIPPY);
2266 * @brief prefファイルを選択して処理する /
2267 * Ask for a "user pref line" and process it
2270 * Allow absolute file names?
2272 void do_cmd_pref(void)
2279 /* Ask for a "user pref command" */
2280 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
2282 /* Process that pref command */
2283 (void)process_pref_file_command(buf);
2287 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
2290 void do_cmd_reload_autopick(void)
2292 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
2293 /* Load the file with messages */
2294 autopick_load_pref(TRUE);
2300 * @brief マクロ情報をprefファイルに保存する /
2301 * @param fname ファイル名
2304 static errr macro_dump(cptr fname)
2306 static cptr mark = "Macro Dump";
2312 /* Build the filename */
2313 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2315 /* File type is "TEXT" */
2316 FILE_TYPE(FILE_TYPE_TEXT);
2318 /* Append to the file */
2319 if (!open_auto_dump(buf, mark)) return (-1);
2322 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
2325 for (i = 0; i < macro__num; i++)
2327 /* Extract the action */
2328 ascii_to_text(buf, macro__act[i]);
2330 /* Dump the macro */
2331 auto_dump_printf("A:%s\n", buf);
2333 /* Extract the action */
2334 ascii_to_text(buf, macro__pat[i]);
2336 /* Dump normal macros */
2337 auto_dump_printf("P:%s\n", buf);
2340 auto_dump_printf("\n");
2352 * @brief マクロのトリガーキーを取得する /
2353 * Hack -- ask for a "trigger" (see below)
2354 * @param buf キー表記を保管するバッファ
2358 * Note the complex use of the "inkey()" function from "util.c".
2360 * Note that both "flush()" calls are extremely important.
2363 static void do_cmd_macro_aux(char *buf)
2371 /* Do not process macros */
2377 /* Read the pattern */
2383 /* Do not process macros */
2386 /* Do not wait for keys */
2389 /* Attempt to read a key */
2398 /* Convert the trigger */
2399 ascii_to_text(tmp, buf);
2401 /* Hack -- display the trigger */
2402 Term_addstr(-1, TERM_WHITE, tmp);
2408 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
2409 * Hack -- ask for a keymap "trigger" (see below)
2410 * @param buf キー表記を取得するバッファ
2414 * Note that both "flush()" calls are extremely important. This may
2415 * no longer be true, since "util.c" is much simpler now.
2418 static void do_cmd_macro_aux_keymap(char *buf)
2428 /* Convert to ascii */
2429 ascii_to_text(tmp, buf);
2431 /* Hack -- display the trigger */
2432 Term_addstr(-1, TERM_WHITE, tmp);
2439 * @brief キーマップをprefファイルにダンプする /
2440 * Hack -- append all keymaps to the given file
2441 * @param fname ファイルネーム
2445 static errr keymap_dump(cptr fname)
2447 static cptr mark = "Keymap Dump";
2456 if (rogue_like_commands)
2458 mode = KEYMAP_MODE_ROGUE;
2464 mode = KEYMAP_MODE_ORIG;
2468 /* Build the filename */
2469 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2471 /* File type is "TEXT" */
2472 FILE_TYPE(FILE_TYPE_TEXT);
2474 /* Append to the file */
2475 if (!open_auto_dump(buf, mark)) return -1;
2478 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
2481 for (i = 0; i < 256; i++)
2485 /* Loop up the keymap */
2486 act = keymap_act[mode][i];
2488 /* Skip empty keymaps */
2491 /* Encode the key */
2494 ascii_to_text(key, buf);
2496 /* Encode the action */
2497 ascii_to_text(buf, act);
2499 /* Dump the macro */
2500 auto_dump_printf("A:%s\n", buf);
2501 auto_dump_printf("C:%d:%s\n", mode, key);
2513 * @brief マクロを設定するコマンドのメインルーチン /
2514 * Interact with "macros"
2518 * Note that the macro "action" must be defined before the trigger.
2520 * Could use some helpful instructions on this page.
2523 void do_cmd_macros(void)
2535 if (rogue_like_commands)
2537 mode = KEYMAP_MODE_ROGUE;
2543 mode = KEYMAP_MODE_ORIG;
2546 /* File type is "TEXT" */
2547 FILE_TYPE(FILE_TYPE_TEXT);
2552 /* Process requests until done */
2556 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
2558 /* Describe that action */
2559 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
2561 /* Analyze the current action */
2562 ascii_to_text(buf, macro__buf);
2564 /* Display the current action */
2569 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2571 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
2572 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
2573 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
2574 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
2575 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
2576 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
2577 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
2578 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
2579 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
2580 #endif /* ALLOW_MACROS */
2583 prt(_("コマンド: ", "Command: "), 16, 0);
2588 if (i == ESCAPE) break;
2590 /* Load a 'macro' file */
2596 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
2599 prt(_("ファイル: ", "File: "), 18, 0);
2601 /* Default filename */
2602 sprintf(tmp, "%s.prf", player_base);
2604 /* Ask for a file */
2605 if (!askfor(tmp, 80)) continue;
2607 /* Process the given filename */
2608 err = process_pref_file(tmp);
2611 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
2616 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
2620 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
2630 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
2633 prt(_("ファイル: ", "File: "), 18, 0);
2635 /* Default filename */
2636 sprintf(tmp, "%s.prf", player_base);
2638 /* Ask for a file */
2639 if (!askfor(tmp, 80)) continue;
2641 /* Dump the macros */
2642 (void)macro_dump(tmp);
2645 msg_print(_("マクロを追加しました。", "Appended macros."));
2654 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
2658 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2660 /* Get a macro trigger */
2661 do_cmd_macro_aux(buf);
2663 /* Acquire action */
2664 k = macro_find_exact(buf);
2670 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
2676 /* Obtain the action */
2677 strcpy(macro__buf, macro__act[k]);
2679 /* Analyze the current action */
2680 ascii_to_text(buf, macro__buf);
2682 /* Display the current action */
2686 msg_print(_("マクロを確認しました。", "Found a macro."));
2690 /* Create a macro */
2694 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
2697 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2699 /* Get a macro trigger */
2700 do_cmd_macro_aux(buf);
2706 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2707 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2710 prt(_("マクロ行動: ", "Action: "), 20, 0);
2712 /* Convert to text */
2713 ascii_to_text(tmp, macro__buf);
2715 /* Get an encoded action */
2716 if (askfor(tmp, 80))
2718 /* Convert to ascii */
2719 text_to_ascii(macro__buf, tmp);
2721 /* Link the macro */
2722 macro_add(buf, macro__buf);
2725 msg_print(_("マクロを追加しました。", "Added a macro."));
2729 /* Remove a macro */
2733 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
2736 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2738 /* Get a macro trigger */
2739 do_cmd_macro_aux(buf);
2741 /* Link the macro */
2742 macro_add(buf, buf);
2745 msg_print(_("マクロを削除しました。", "Removed a macro."));
2752 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
2755 prt(_("ファイル: ", "File: "), 18, 0);
2757 /* Default filename */
2758 sprintf(tmp, "%s.prf", player_base);
2760 /* Ask for a file */
2761 if (!askfor(tmp, 80)) continue;
2763 /* Dump the macros */
2764 (void)keymap_dump(tmp);
2767 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
2770 /* Query a keymap */
2776 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
2779 prt(_("押すキー: ", "Keypress: "), 18, 0);
2781 /* Get a keymap trigger */
2782 do_cmd_macro_aux_keymap(buf);
2784 /* Look up the keymap */
2785 act = keymap_act[mode][(byte)(buf[0])];
2791 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
2797 /* Obtain the action */
2798 strcpy(macro__buf, act);
2800 /* Analyze the current action */
2801 ascii_to_text(buf, macro__buf);
2803 /* Display the current action */
2807 msg_print(_("キー配置を確認しました。", "Found a keymap."));
2811 /* Create a keymap */
2815 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
2818 prt(_("押すキー: ", "Keypress: "), 18, 0);
2820 /* Get a keymap trigger */
2821 do_cmd_macro_aux_keymap(buf);
2827 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2828 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2831 prt(_("行動: ", "Action: "), 20, 0);
2833 /* Convert to text */
2834 ascii_to_text(tmp, macro__buf);
2836 /* Get an encoded action */
2837 if (askfor(tmp, 80))
2839 /* Convert to ascii */
2840 text_to_ascii(macro__buf, tmp);
2842 /* Free old keymap */
2843 string_free(keymap_act[mode][(byte)(buf[0])]);
2845 /* Make new keymap */
2846 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
2849 msg_print(_("キー配置を追加しました。", "Added a keymap."));
2853 /* Remove a keymap */
2857 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
2860 prt(_("押すキー: ", "Keypress: "), 18, 0);
2862 /* Get a keymap trigger */
2863 do_cmd_macro_aux_keymap(buf);
2865 /* Free old keymap */
2866 string_free(keymap_act[mode][(byte)(buf[0])]);
2868 /* Make new keymap */
2869 keymap_act[mode][(byte)(buf[0])] = NULL;
2872 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
2875 /* Enter a new action */
2879 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
2885 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2886 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2889 prt(_("マクロ行動: ", "Action: "), 20, 0);
2891 /* Hack -- limit the value */
2894 /* Get an encoded action */
2895 if (!askfor(buf, 80)) continue;
2897 /* Extract an action */
2898 text_to_ascii(macro__buf, buf);
2901 #endif /* ALLOW_MACROS */
2914 * @brief キャラクタ色の明暗表現
2916 static cptr lighting_level_str[F_LIT_MAX] =
2931 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
2932 * @param i 指定対象となるキャラクタコード
2933 * @param num 指定されたビジュアルIDを返す参照ポインタ
2934 * @param max ビジュアルIDの最大数
2935 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
2937 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2944 sprintf(str, "%d", *num);
2946 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
2949 tmp = (IDX)strtol(str, NULL, 0);
2950 if (tmp >= 0 && tmp < max)
2953 else if (isupper(i))
2954 *num = (*num + max - 1) % max;
2956 *num = (*num + 1) % max;
2962 * @brief キャラクタの変更メニュー表示
2963 * @param choice_msg 選択メッセージ
2966 static void print_visuals_menu(cptr choice_msg)
2968 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2970 /* Give some choices */
2971 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2973 #ifdef ALLOW_VISUALS
2974 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2975 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2976 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2977 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2978 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2979 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2980 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2981 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2982 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2983 #endif /* ALLOW_VISUALS */
2985 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2988 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2991 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx);
2992 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx);
2993 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
2996 * Interact with "visuals"
2998 void do_cmd_visuals(void)
3003 bool need_redraw = FALSE;
3004 cptr empty_symbol = "<< ? >>";
3006 if (use_bigtile) empty_symbol = "<< ?? >>";
3008 /* File type is "TEXT" */
3009 FILE_TYPE(FILE_TYPE_TEXT);
3012 /* Interact until done */
3017 /* Ask for a choice */
3018 print_visuals_menu(NULL);
3023 if (i == ESCAPE) break;
3027 /* Load a 'pref' file */
3030 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
3033 prt(_("ファイル: ", "File: "), 17, 0);
3035 /* Default filename */
3036 sprintf(tmp, "%s.prf", player_base);
3039 if (!askfor(tmp, 70)) continue;
3041 /* Process the given filename */
3042 (void)process_pref_file(tmp);
3047 #ifdef ALLOW_VISUALS
3049 /* Dump monster attr/chars */
3052 static cptr mark = "Monster attr/chars";
3055 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
3058 prt(_("ファイル: ", "File: "), 17, 0);
3060 /* Default filename */
3061 sprintf(tmp, "%s.prf", player_base);
3063 /* Get a filename */
3064 if (!askfor(tmp, 70)) continue;
3066 /* Build the filename */
3067 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3069 /* Append to the file */
3070 if (!open_auto_dump(buf, mark)) continue;
3073 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
3076 for (i = 0; i < max_r_idx; i++)
3078 monster_race *r_ptr = &r_info[i];
3080 /* Skip non-entries */
3081 if (!r_ptr->name) continue;
3083 /* Dump a comment */
3084 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
3086 /* Dump the monster attr/char info */
3087 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
3088 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
3094 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
3099 /* Dump object attr/chars */
3102 static cptr mark = "Object attr/chars";
3103 KIND_OBJECT_IDX k_idx;
3106 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
3109 prt(_("ファイル: ", "File: "), 17, 0);
3111 /* Default filename */
3112 sprintf(tmp, "%s.prf", player_base);
3114 /* Get a filename */
3115 if (!askfor(tmp, 70)) continue;
3117 /* Build the filename */
3118 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3120 /* Append to the file */
3121 if (!open_auto_dump(buf, mark)) continue;
3124 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
3127 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
3129 GAME_TEXT o_name[MAX_NLEN];
3130 object_kind *k_ptr = &k_info[k_idx];
3132 /* Skip non-entries */
3133 if (!k_ptr->name) continue;
3138 strip_name(o_name, k_idx);
3144 /* Prepare dummy object */
3145 object_prep(&forge, k_idx);
3147 /* Get un-shuffled flavor name */
3148 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3151 /* Dump a comment */
3152 auto_dump_printf("# %s\n", o_name);
3154 /* Dump the object attr/char info */
3155 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
3156 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3162 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
3167 /* Dump feature attr/chars */
3170 static cptr mark = "Feature attr/chars";
3173 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
3176 prt(_("ファイル: ", "File: "), 17, 0);
3178 /* Default filename */
3179 sprintf(tmp, "%s.prf", player_base);
3181 /* Get a filename */
3182 if (!askfor(tmp, 70)) continue;
3184 /* Build the filename */
3185 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3187 /* Append to the file */
3188 if (!open_auto_dump(buf, mark)) continue;
3191 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
3194 for (i = 0; i < max_f_idx; i++)
3196 feature_type *f_ptr = &f_info[i];
3198 /* Skip non-entries */
3199 if (!f_ptr->name) continue;
3201 /* Skip mimiccing features */
3202 if (f_ptr->mimic != i) continue;
3204 /* Dump a comment */
3205 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
3207 /* Dump the feature attr/char info */
3208 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
3209 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
3210 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
3211 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
3217 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
3222 /* Modify monster attr/chars (numeric operation) */
3225 static cptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
3228 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3230 /* Hack -- query until done */
3233 monster_race *r_ptr = &r_info[r];
3237 TERM_COLOR da = r_ptr->d_attr;
3238 byte dc = r_ptr->d_char;
3239 TERM_COLOR ca = r_ptr->x_attr;
3240 byte cc = r_ptr->x_char;
3242 /* Label the object */
3243 Term_putstr(5, 17, -1, TERM_WHITE,
3244 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
3246 /* Label the Default values */
3247 Term_putstr(10, 19, -1, TERM_WHITE,
3248 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
3250 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3251 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3253 /* Label the Current values */
3254 Term_putstr(10, 20, -1, TERM_WHITE,
3255 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
3257 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3258 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3261 Term_putstr(0, 22, -1, TERM_WHITE,
3262 _("コマンド (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): "));
3267 if (i == ESCAPE) break;
3269 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3270 else if (isupper(i)) c = 'a' + i - 'A';
3280 if (!cmd_visuals_aux(i, &r, max_r_idx))
3286 while (!r_info[r].name);
3290 t = (int)r_ptr->x_attr;
3291 (void)cmd_visuals_aux(i, &t, 256);
3292 r_ptr->x_attr = (byte)t;
3296 t = (int)r_ptr->x_char;
3297 (void)cmd_visuals_aux(i, &t, 256);
3298 r_ptr->x_char = (byte)t;
3302 do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
3304 print_visuals_menu(choice_msg);
3312 /* Modify object attr/chars (numeric operation) */
3315 static cptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
3317 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3319 /* Hack -- query until done */
3322 object_kind *k_ptr = &k_info[k];
3326 TERM_COLOR da = k_ptr->d_attr;
3327 SYMBOL_CODE dc = k_ptr->d_char;
3328 TERM_COLOR ca = k_ptr->x_attr;
3329 SYMBOL_CODE cc = k_ptr->x_char;
3331 /* Label the object */
3332 Term_putstr(5, 17, -1, TERM_WHITE,
3333 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
3334 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
3336 /* Label the Default values */
3337 Term_putstr(10, 19, -1, TERM_WHITE,
3338 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3340 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3341 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3343 /* Label the Current values */
3344 Term_putstr(10, 20, -1, TERM_WHITE,
3345 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
3347 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3348 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3351 Term_putstr(0, 22, -1, TERM_WHITE,
3352 _("コマンド (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): "));
3357 if (i == ESCAPE) break;
3359 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3360 else if (isupper(i)) c = 'a' + i - 'A';
3370 if (!cmd_visuals_aux(i, &k, max_k_idx))
3376 while (!k_info[k].name);
3380 t = (int)k_ptr->x_attr;
3381 (void)cmd_visuals_aux(i, &t, 256);
3382 k_ptr->x_attr = (byte)t;
3386 t = (int)k_ptr->x_char;
3387 (void)cmd_visuals_aux(i, &t, 256);
3388 k_ptr->x_char = (byte)t;
3392 do_cmd_knowledge_objects(&need_redraw, TRUE, k);
3394 print_visuals_menu(choice_msg);
3402 /* Modify feature attr/chars (numeric operation) */
3405 static cptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
3407 static IDX lighting_level = F_LIT_STANDARD;
3408 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3410 /* Hack -- query until done */
3413 feature_type *f_ptr = &f_info[f];
3417 TERM_COLOR da = f_ptr->d_attr[lighting_level];
3418 byte dc = f_ptr->d_char[lighting_level];
3419 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
3420 byte cc = f_ptr->x_char[lighting_level];
3422 /* Label the object */
3424 Term_putstr(5, 17, -1, TERM_WHITE,
3425 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
3426 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
3428 /* Label the Default values */
3429 Term_putstr(10, 19, -1, TERM_WHITE,
3430 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3432 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3433 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3435 /* Label the Current values */
3437 Term_putstr(10, 20, -1, TERM_WHITE,
3438 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
3440 Term_putstr(10, 20, -1, TERM_WHITE,
3441 format("Current attr/char = %3d / %3d", ca, cc));
3444 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3445 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3449 Term_putstr(0, 22, -1, TERM_WHITE,
3450 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3452 Term_putstr(0, 22, -1, TERM_WHITE,
3453 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3459 if (i == ESCAPE) break;
3461 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3462 else if (isupper(i)) c = 'a' + i - 'A';
3472 if (!cmd_visuals_aux(i, &f, max_f_idx))
3478 while (!f_info[f].name || (f_info[f].mimic != f));
3482 t = (int)f_ptr->x_attr[lighting_level];
3483 (void)cmd_visuals_aux(i, &t, 256);
3484 f_ptr->x_attr[lighting_level] = (byte)t;
3488 t = (int)f_ptr->x_char[lighting_level];
3489 (void)cmd_visuals_aux(i, &t, 256);
3490 f_ptr->x_char[lighting_level] = (byte)t;
3494 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
3497 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
3501 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
3503 print_visuals_menu(choice_msg);
3511 /* Modify monster attr/chars (visual mode) */
3513 do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
3516 /* Modify object attr/chars (visual mode) */
3518 do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
3521 /* Modify feature attr/chars (visual mode) */
3524 IDX lighting_level = F_LIT_STANDARD;
3525 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
3529 #endif /* ALLOW_VISUALS */
3537 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
3541 /* Unknown option */
3551 if (need_redraw) do_cmd_redraw();
3556 * Interact with "colors"
3558 void do_cmd_colors(void)
3567 /* File type is "TEXT" */
3568 FILE_TYPE(FILE_TYPE_TEXT);
3573 /* Interact until done */
3578 /* Ask for a choice */
3579 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
3581 /* Give some choices */
3582 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
3585 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
3586 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
3590 prt(_("コマンド: ", "Command: "), 8, 0);
3594 if (i == ESCAPE) break;
3596 /* Load a 'pref' file */
3600 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
3603 prt(_("ファイル: ", "File: "), 10, 0);
3606 sprintf(tmp, "%s.prf", player_base);
3609 if (!askfor(tmp, 70)) continue;
3611 /* Process the given filename */
3612 (void)process_pref_file(tmp);
3614 /* Mega-Hack -- react to changes */
3615 Term_xtra(TERM_XTRA_REACT, 0);
3617 /* Mega-Hack -- redraw */
3626 static cptr mark = "Colors";
3629 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
3632 prt(_("ファイル: ", "File: "), 10, 0);
3634 /* Default filename */
3635 sprintf(tmp, "%s.prf", player_base);
3637 /* Get a filename */
3638 if (!askfor(tmp, 70)) continue;
3640 /* Build the filename */
3641 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3643 /* Append to the file */
3644 if (!open_auto_dump(buf, mark)) continue;
3647 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
3650 for (i = 0; i < 256; i++)
3652 int kv = angband_color_table[i][0];
3653 int rv = angband_color_table[i][1];
3654 int gv = angband_color_table[i][2];
3655 int bv = angband_color_table[i][3];
3657 cptr name = _("未知", "unknown");
3659 /* Skip non-entries */
3660 if (!kv && !rv && !gv && !bv) continue;
3662 /* Extract the color name */
3663 if (i < 16) name = color_names[i];
3665 /* Dump a comment */
3666 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
3668 /* Dump the monster attr/char info */
3669 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
3676 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
3685 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
3687 /* Hack -- query until done */
3696 /* Exhibit the normal colors */
3697 for (j = 0; j < 16; j++)
3699 /* Exhibit this color */
3700 Term_putstr(j*4, 20, -1, a, "###");
3702 /* Exhibit all colors */
3703 Term_putstr(j*4, 22, -1, j, format("%3d", j));
3706 /* Describe the color */
3707 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
3709 /* Describe the color */
3710 Term_putstr(5, 10, -1, TERM_WHITE,
3711 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
3713 /* Label the Current values */
3714 Term_putstr(5, 12, -1, TERM_WHITE,
3715 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
3716 angband_color_table[a][0],
3717 angband_color_table[a][1],
3718 angband_color_table[a][2],
3719 angband_color_table[a][3]));
3722 Term_putstr(0, 14, -1, TERM_WHITE,
3723 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
3728 if (i == ESCAPE) break;
3731 if (i == 'n') a = (byte)(a + 1);
3732 if (i == 'N') a = (byte)(a - 1);
3733 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
3734 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
3735 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
3736 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
3737 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
3738 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
3739 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
3740 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
3742 /* Hack -- react to changes */
3743 Term_xtra(TERM_XTRA_REACT, 0);
3745 /* Hack -- redraw */
3752 /* Unknown option */
3766 * Note something in the message recall
3768 void do_cmd_note(void)
3776 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
3778 /* Ignore empty notes */
3779 if (!buf[0] || (buf[0] == ' ')) return;
3781 /* Add the note to the message recall */
3782 msg_format(_("メモ: %s", "Note: %s"), buf);
3787 * Mention the current version
3789 void do_cmd_version(void)
3793 #if FAKE_VER_EXTRA > 0
3794 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
3795 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
3797 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
3798 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
3805 * Array of feeling strings
3807 static cptr do_cmd_feeling_text[11] =
3809 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3810 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3811 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
3812 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3813 _("とても悪い予感がする...", "You have a very bad feeling..."),
3814 _("悪い予感がする...", "You have a bad feeling..."),
3815 _("何か緊張する。", "You feel nervous."),
3816 _("少し不運な気がする...", "You feel your luck is turning..."),
3817 _("この場所は好きになれない。", "You don't like the look of this place."),
3818 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3819 _("なんて退屈なところだ...", "What a boring place...")
3822 static cptr do_cmd_feeling_text_combat[11] =
3824 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3825 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3826 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
3827 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3828 _("とても悪い予感がする...", "You have a very bad feeling..."),
3829 _("悪い予感がする...", "You have a bad feeling..."),
3830 _("何か緊張する。", "You feel nervous."),
3831 _("少し不運な気がする...", "You feel your luck is turning..."),
3832 _("この場所は好きになれない。", "You don't like the look of this place."),
3833 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3834 _("なんて退屈なところだ...", "What a boring place...")
3837 static cptr do_cmd_feeling_text_lucky[11] =
3839 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3840 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3841 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
3842 _("素晴らしい感じがする...", "You have an excellent feeling..."),
3843 _("とても良い感じがする...", "You have a very good feeling..."),
3844 _("良い感じがする...", "You have a good feeling..."),
3845 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
3846 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
3847 _("見た感じ悪くはない...", "You like the look of this place..."),
3848 _("全然駄目ということはないが...", "This level can't be all bad..."),
3849 _("なんて退屈なところだ...", "What a boring place...")
3854 * Note that "feeling" is set to zero unless some time has passed.
3855 * Note that this is done when the level is GENERATED, not entered.
3857 void do_cmd_feeling(void)
3859 /* No useful feeling in quests */
3860 if (p_ptr->inside_quest && !random_quest_number(dun_level))
3862 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
3866 /* No useful feeling in town */
3867 else if (p_ptr->town_num && !dun_level)
3869 if (!strcmp(town[p_ptr->town_num].name, _("荒野", "wilderness")))
3871 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
3876 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
3881 /* No useful feeling in the wilderness */
3882 else if (!dun_level)
3884 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
3888 /* Display the feeling */
3889 if (p_ptr->muta3 & MUT3_GOOD_LUCK)
3890 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
3891 else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
3892 inventory[INVEN_BOW].name1 == ART_CRIMSON)
3893 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
3895 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
3901 * Description of each monster group.
3903 static cptr monster_group_text[] =
3906 "ユニーク", /* "Uniques" */
3907 "乗馬可能なモンスター", /* "Riding" */
3908 "賞金首", /* "Wanted */
3909 "アンバーの王族", /* "Ambertite" */
3938 /* "古代ドラゴン/ワイアーム", */
3999 /* "Ancient Dragon/Wyrm", */
4008 "Multi-Headed Reptile",
4013 "Reptile/Amphibian",
4014 "Spider/Scorpion/Tick",
4016 /* "Major Demon", */
4033 * Symbols of monsters in each group. Note the "Uniques" group
4034 * is handled differently.
4036 static cptr monster_group_char[] =
4093 "!$&()+./=>?[\\]`{|~",
4103 * hook function to sort monsters by level
4105 static bool ang_sort_comp_monster_level(vptr u, vptr v, int a, int b)
4107 u16b *who = (u16b*)(u);
4112 monster_race *r_ptr1 = &r_info[w1];
4113 monster_race *r_ptr2 = &r_info[w2];
4118 if (r_ptr2->level > r_ptr1->level) return TRUE;
4119 if (r_ptr1->level > r_ptr2->level) return FALSE;
4121 if ((r_ptr2->flags1 & RF1_UNIQUE) && !(r_ptr1->flags1 & RF1_UNIQUE)) return TRUE;
4122 if ((r_ptr1->flags1 & RF1_UNIQUE) && !(r_ptr2->flags1 & RF1_UNIQUE)) return FALSE;
4127 * Build a list of monster indexes in the given group. Return the number
4128 * of monsters in the group.
4130 * mode & 0x01 : check for non-empty group
4131 * mode & 0x02 : visual operation only
4133 static IDX collect_monsters(IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
4139 /* Get a list of x_char in this group */
4140 cptr group_char = monster_group_char[grp_cur];
4142 /* XXX Hack -- Check if this is the "Uniques" group */
4143 bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
4145 /* XXX Hack -- Check if this is the "Riding" group */
4146 bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
4148 /* XXX Hack -- Check if this is the "Wanted" group */
4149 bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
4151 /* XXX Hack -- Check if this is the "Amberite" group */
4152 bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
4155 /* Check every race */
4156 for (i = 0; i < max_r_idx; i++)
4158 /* Access the race */
4159 monster_race *r_ptr = &r_info[i];
4161 /* Skip empty race */
4162 if (!r_ptr->name) continue ;
4164 /* Require known monsters */
4165 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
4169 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4172 else if (grp_riding)
4174 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
4177 else if (grp_wanted)
4179 bool wanted = FALSE;
4181 for (j = 0; j < MAX_KUBI; j++)
4183 if (kubi_r_idx[j] == i || kubi_r_idx[j] - 10000 == i ||
4184 (p_ptr->today_mon && p_ptr->today_mon == i))
4190 if (!wanted) continue;
4193 else if (grp_amberite)
4195 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
4200 /* Check for race in the group */
4201 if (!my_strchr(group_char, r_ptr->d_char)) continue;
4205 mon_idx[mon_cnt++] = i;
4207 /* XXX Hack -- Just checking for non-empty group */
4208 if (mode & 0x01) break;
4211 /* Terminate the list */
4212 mon_idx[mon_cnt] = -1;
4214 /* Select the sort method */
4215 ang_sort_comp = ang_sort_comp_monster_level;
4216 ang_sort_swap = ang_sort_swap_hook;
4218 /* Sort by monster level */
4219 ang_sort(mon_idx, &dummy_why, mon_cnt);
4221 /* Return the number of races */
4227 * Description of each monster group.
4229 static cptr object_group_text[] =
4232 "キノコ", /* "Mushrooms" */
4233 "薬", /* "Potions" */
4234 "油つぼ", /* "Flasks" */
4235 "巻物", /* "Scrolls" */
4237 "アミュレット", /* "Amulets" */
4238 "笛", /* "Whistle" */
4239 "光源", /* "Lanterns" */
4240 "魔法棒", /* "Wands" */
4243 "カード", /* "Cards" */
4254 "刀剣類", /* "Swords" */
4255 "鈍器", /* "Blunt Weapons" */
4256 "長柄武器", /* "Polearms" */
4257 "採掘道具", /* "Diggers" */
4258 "飛び道具", /* "Bows" */
4262 "軽装鎧", /* "Soft Armor" */
4263 "重装鎧", /* "Hard Armor" */
4264 "ドラゴン鎧", /* "Dragon Armor" */
4265 "盾", /* "Shields" */
4266 "クローク", /* "Cloaks" */
4267 "籠手", /* "Gloves" */
4268 "ヘルメット", /* "Helms" */
4270 "ブーツ", /* "Boots" */
4323 * TVALs of items in each group
4325 static byte object_group_tval[] =
4366 TV_LIFE_BOOK, /* Hack -- all spellbooks */
4374 * Build a list of object indexes in the given group. Return the number
4375 * of objects in the group.
4377 * mode & 0x01 : check for non-empty group
4378 * mode & 0x02 : visual operation only
4380 static int collect_objects(int grp_cur, IDX object_idx[], BIT_FLAGS8 mode)
4383 int j, k, object_cnt = 0;
4385 /* Get a list of x_char in this group */
4386 byte group_tval = object_group_tval[grp_cur];
4388 /* Check every object */
4389 for (i = 0; i < max_k_idx; i++)
4391 /* Access the object */
4392 object_kind *k_ptr = &k_info[i];
4394 /* Skip empty objects */
4395 if (!k_ptr->name) continue;
4399 /* Any objects will be displayed */
4405 /* Skip non-flavoured objects */
4406 if (!k_ptr->flavor) continue;
4408 /* Require objects ever seen */
4409 if (!k_ptr->aware) continue;
4412 /* Skip items with no distribution (special artifacts) */
4413 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
4417 /* Check for objects in the group */
4418 if (TV_LIFE_BOOK == group_tval)
4420 /* Hack -- All spell books */
4421 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
4423 /* Add the object */
4424 object_idx[object_cnt++] = i;
4428 else if (k_ptr->tval == group_tval)
4430 /* Add the object */
4431 object_idx[object_cnt++] = i;
4435 /* XXX Hack -- Just checking for non-empty group */
4436 if (mode & 0x01) break;
4439 /* Terminate the list */
4440 object_idx[object_cnt] = -1;
4442 /* Return the number of objects */
4448 * Description of each feature group.
4450 static cptr feature_group_text[] =
4458 * Build a list of feature indexes in the given group. Return the number
4459 * of features in the group.
4461 * mode & 0x01 : check for non-empty group
4463 static int collect_features(int grp_cur, IDX *feat_idx, BIT_FLAGS8 mode)
4468 /* Unused; There is a single group. */
4471 /* Check every feature */
4472 for (i = 0; i < max_f_idx; i++)
4474 /* Access the index */
4475 feature_type *f_ptr = &f_info[i];
4477 /* Skip empty index */
4478 if (!f_ptr->name) continue;
4480 /* Skip mimiccing features */
4481 if (f_ptr->mimic != i) continue;
4484 feat_idx[feat_cnt++] = i;
4486 /* XXX Hack -- Just checking for non-empty group */
4487 if (mode & 0x01) break;
4490 /* Terminate the list */
4491 feat_idx[feat_cnt] = -1;
4493 /* Return the number of races */
4500 * Build a list of monster indexes in the given group. Return the number
4501 * of monsters in the group.
4503 static int collect_artifacts(int grp_cur, int object_idx[])
4505 int i, object_cnt = 0;
4507 /* Get a list of x_char in this group */
4508 byte group_tval = object_group_tval[grp_cur];
4510 /* Check every object */
4511 for (i = 0; i < max_a_idx; i++)
4513 /* Access the artifact */
4514 artifact_type *a_ptr = &a_info[i];
4516 /* Skip empty artifacts */
4517 if (!a_ptr->name) continue;
4519 /* Skip "uncreated" artifacts */
4520 if (!a_ptr->cur_num) continue;
4522 /* Check for race in the group */
4523 if (a_ptr->tval == group_tval)
4526 object_idx[object_cnt++] = i;
4530 /* Terminate the list */
4531 object_idx[object_cnt] = 0;
4533 /* Return the number of races */
4540 * Encode the screen colors
4542 static char hack[17] = "dwsorgbuDWvyRGBU";
4546 * Hack -- load a screen dump from a file
4548 void do_cmd_load_screen(void)
4563 Term_get_size(&wid, &hgt);
4565 /* Build the filename */
4566 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4568 /* Append to the file */
4569 fff = my_fopen(buf, "r");
4572 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4580 /* Load the screen */
4581 for (y = 0; okay; y++)
4583 /* Get a line of data including control code */
4584 if (!fgets(buf, 1024, fff)) okay = FALSE;
4586 /* Get the blank line */
4587 if (buf[0] == '\n' || buf[0] == '\0') break;
4589 /* Ignore too large screen image */
4590 if (y >= hgt) continue;
4593 for (x = 0; x < wid - 1; x++)
4596 if (buf[x] == '\n' || buf[x] == '\0') break;
4598 /* Put the attr/char */
4599 Term_draw(x, y, TERM_WHITE, buf[x]);
4603 /* Dump the screen */
4604 for (y = 0; okay; y++)
4606 /* Get a line of data including control code */
4607 if (!fgets(buf, 1024, fff)) okay = FALSE;
4609 /* Get the blank line */
4610 if (buf[0] == '\n' || buf[0] == '\0') break;
4612 /* Ignore too large screen image */
4613 if (y >= hgt) continue;
4616 for (x = 0; x < wid - 1; x++)
4619 if (buf[x] == '\n' || buf[x] == '\0') break;
4621 /* Get the attr/char */
4622 (void)(Term_what(x, y, &a, &c));
4624 /* Look up the attr */
4625 for (i = 0; i < 16; i++)
4627 /* Use attr matches */
4628 if (hack[i] == buf[x]) a = (byte_hack)i;
4631 /* Put the attr/char */
4632 Term_draw(x, y, a, c);
4641 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4652 cptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4653 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4656 #define IM_FLAG_STR _("*", "* ")
4657 #define HAS_FLAG_STR _("+", "+ ")
4658 #define NO_FLAG_STR _("・", ". ")
4660 #define print_im_or_res_flag(IM, RES) \
4662 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4663 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4666 #define print_flag(TR) \
4668 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4672 /* XTRA HACK RESLIST */
4673 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
4675 GAME_TEXT o_name[MAX_NLEN];
4676 BIT_FLAGS flgs[TR_FLAG_SIZE];
4678 if (!o_ptr->k_idx) return;
4679 if (o_ptr->tval != tval) return;
4681 /* Identified items only */
4682 if (!object_is_known(o_ptr)) return;
4685 * HACK:Ring of Lordly protection and Dragon equipment
4686 * have random resistances.
4688 if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4689 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4690 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4691 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4692 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4693 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4694 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4695 || object_is_artifact(o_ptr))
4698 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4700 while (o_name[i] && (i < 26))
4703 if (iskanji(o_name[i])) i++;
4712 o_name[i] = ' '; i++;
4717 fprintf(fff, "%s %s", where, o_name);
4719 if (!(o_ptr->ident & (IDENT_MENTAL)))
4721 fputs(_("-------不明--------------- -------不明---------\n",
4722 "-------unknown------------ -------unknown------\n"), fff);
4726 object_flags_known(o_ptr, flgs);
4728 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4729 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4730 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4731 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4732 print_flag(TR_RES_POIS);
4733 print_flag(TR_RES_LITE);
4734 print_flag(TR_RES_DARK);
4735 print_flag(TR_RES_SHARDS);
4736 print_flag(TR_RES_SOUND);
4737 print_flag(TR_RES_NETHER);
4738 print_flag(TR_RES_NEXUS);
4739 print_flag(TR_RES_CHAOS);
4740 print_flag(TR_RES_DISEN);
4744 print_flag(TR_RES_BLIND);
4745 print_flag(TR_RES_FEAR);
4746 print_flag(TR_RES_CONF);
4747 print_flag(TR_FREE_ACT);
4748 print_flag(TR_SEE_INVIS);
4749 print_flag(TR_HOLD_EXP);
4750 print_flag(TR_TELEPATHY);
4751 print_flag(TR_SLOW_DIGEST);
4752 print_flag(TR_REGEN);
4753 print_flag(TR_LEVITATION);
4761 fprintf(fff, "%s\n", inven_res_label);
4767 * Display *ID* ed weapons/armors's resistances
4769 static void do_cmd_knowledge_inven(void)
4773 GAME_TEXT file_name[1024];
4777 OBJECT_TYPE_VALUE tval;
4783 /* Open a new file */
4784 fff = my_fopen_temp(file_name, 1024);
4787 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4791 fprintf(fff, "%s\n", inven_res_label);
4793 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4797 for (; j < 9; j++) fputc('\n', fff);
4799 fprintf(fff, "%s\n", inven_res_label);
4801 strcpy(where, _("装", "E "));
4802 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4804 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4806 strcpy(where, _("持", "I "));
4807 for (i = 0; i < INVEN_PACK; i++)
4809 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4812 st_ptr = &town[1].store[STORE_HOME];
4813 strcpy(where, _("家", "H "));
4814 for (i = 0; i < st_ptr->stock_num; i++)
4816 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
4821 /* Display the file contents */
4822 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
4824 /* Remove the file */
4829 void do_cmd_save_screen_html_aux(char *filename, int message)
4833 TERM_COLOR a = 0, old_a = 0;
4847 cptr html_head[] = {
4848 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
4852 cptr html_foot[] = {
4854 "</body>\n</html>\n",
4860 Term_get_size(&wid, &hgt);
4862 /* File type is "TEXT" */
4863 FILE_TYPE(FILE_TYPE_TEXT);
4865 /* Append to the file */
4866 fff = my_fopen(filename, "w");
4870 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
4876 if (message) screen_save();
4878 /* Build the filename */
4879 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
4880 tmpfff = my_fopen(buf, "r");
4882 for (i = 0; html_head[i]; i++)
4883 fputs(html_head[i], fff);
4887 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4889 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
4893 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
4895 fprintf(fff, "%s\n", buf);
4900 /* Dump the screen */
4901 for (y = 0; y < hgt; y++)
4908 for (x = 0; x < wid - 1; x++)
4912 /* Get the attr/char */
4913 (void)(Term_what(x, y, &a, &c));
4917 case '&': cc = "&"; break;
4918 case '<': cc = "<"; break;
4919 case '>': cc = ">"; break;
4921 case 0x1f: c = '.'; break;
4922 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
4927 if ((y == 0 && x == 0) || a != old_a) {
4928 rv = angband_color_table[a][1];
4929 gv = angband_color_table[a][2];
4930 bv = angband_color_table[a][3];
4931 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
4932 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
4936 fprintf(fff, "%s", cc);
4938 fprintf(fff, "%c", c);
4941 fprintf(fff, "</font>");
4944 for (i = 0; html_foot[i]; i++)
4945 fputs(html_foot[i], fff);
4950 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4952 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
4956 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
4958 fprintf(fff, "%s\n", buf);
4971 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4979 * Hack -- save a screen dump to a file
4981 static void do_cmd_save_screen_html(void)
4983 char buf[1024], tmp[256] = "screen.html";
4985 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
4988 /* Build the filename */
4989 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4993 do_cmd_save_screen_html_aux(buf, 1);
4998 * Redefinable "save_screen" action
5000 void (*screendump_aux)(void) = NULL;
5004 * Hack -- save a screen dump to a file
5006 void do_cmd_save_screen(void)
5008 bool old_use_graphics = use_graphics;
5009 bool html_dump = FALSE;
5013 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
5017 if (c == 'Y' || c == 'y')
5019 else if (c == 'H' || c == 'h')
5031 Term_get_size(&wid, &hgt);
5033 if (old_use_graphics)
5035 use_graphics = FALSE;
5037 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5043 do_cmd_save_screen_html();
5047 /* Do we use a special screendump function ? */
5048 else if (screendump_aux)
5050 /* Dump the screen to a graphics file */
5051 (*screendump_aux)();
5053 else /* Dump the screen as text */
5064 /* Build the filename */
5065 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5067 /* File type is "TEXT" */
5068 FILE_TYPE(FILE_TYPE_TEXT);
5070 /* Append to the file */
5071 fff = my_fopen(buf, "w");
5075 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5083 /* Dump the screen */
5084 for (y = 0; y < hgt; y++)
5087 for (x = 0; x < wid - 1; x++)
5089 /* Get the attr/char */
5090 (void)(Term_what(x, y, &a, &c));
5100 fprintf(fff, "%s\n", buf);
5107 /* Dump the screen */
5108 for (y = 0; y < hgt; y++)
5111 for (x = 0; x < wid - 1; x++)
5113 /* Get the attr/char */
5114 (void)(Term_what(x, y, &a, &c));
5117 buf[x] = hack[a&0x0F];
5124 fprintf(fff, "%s\n", buf);
5133 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5138 if (old_use_graphics)
5140 use_graphics = TRUE;
5142 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5149 * Sorting hook -- Comp function -- see below
5151 * We use "u" to point to array of monster indexes,
5152 * and "v" to select the type of sorting to perform on "u".
5154 static bool ang_sort_art_comp(vptr u, vptr v, int a, int b)
5156 u16b *who = (u16b*)(u);
5158 u16b *why = (u16b*)(v);
5165 /* Sort by total kills */
5168 /* Extract total kills */
5169 z1 = a_info[w1].tval;
5170 z2 = a_info[w2].tval;
5172 /* Compare total kills */
5173 if (z1 < z2) return (TRUE);
5174 if (z1 > z2) return (FALSE);
5178 /* Sort by monster level */
5181 /* Extract levels */
5182 z1 = a_info[w1].sval;
5183 z2 = a_info[w2].sval;
5185 /* Compare levels */
5186 if (z1 < z2) return (TRUE);
5187 if (z1 > z2) return (FALSE);
5191 /* Sort by monster experience */
5194 /* Extract experience */
5195 z1 = a_info[w1].level;
5196 z2 = a_info[w2].level;
5198 /* Compare experience */
5199 if (z1 < z2) return (TRUE);
5200 if (z1 > z2) return (FALSE);
5204 /* Compare indexes */
5210 * Sorting hook -- Swap function -- see below
5212 * We use "u" to point to array of monster indexes,
5213 * and "v" to select the type of sorting to perform.
5215 static void ang_sort_art_swap(vptr u, vptr v, int a, int b)
5217 u16b *who = (u16b*)(u);
5232 * Check the status of "artifacts"
5234 static void do_cmd_knowledge_artifacts(void)
5246 GAME_TEXT file_name[1024];
5248 GAME_TEXT base_name[MAX_NLEN];
5252 /* Open a new file */
5253 fff = my_fopen_temp(file_name, 1024);
5256 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5261 /* Allocate the "who" array */
5262 C_MAKE(who, max_a_idx, s16b);
5264 /* Allocate the "okay" array */
5265 C_MAKE(okay, max_a_idx, bool);
5267 /* Scan the artifacts */
5268 for (k = 0; k < max_a_idx; k++)
5270 artifact_type *a_ptr = &a_info[k];
5275 /* Skip "empty" artifacts */
5276 if (!a_ptr->name) continue;
5278 /* Skip "uncreated" artifacts */
5279 if (!a_ptr->cur_num) continue;
5285 /* Check the dungeon */
5286 for (y = 0; y < cur_hgt; y++)
5288 for (x = 0; x < cur_wid; x++)
5290 cave_type *c_ptr = &cave[y][x];
5292 OBJECT_IDX this_o_idx, next_o_idx = 0;
5294 /* Scan all objects in the grid */
5295 for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5298 o_ptr = &o_list[this_o_idx];
5300 /* Acquire next object */
5301 next_o_idx = o_ptr->next_o_idx;
5303 /* Ignore non-artifacts */
5304 if (!object_is_fixed_artifact(o_ptr)) continue;
5306 /* Ignore known items */
5307 if (object_is_known(o_ptr)) continue;
5309 /* Note the artifact */
5310 okay[o_ptr->name1] = FALSE;
5315 /* Check the inventory and equipment */
5316 for (i = 0; i < INVEN_TOTAL; i++)
5318 object_type *o_ptr = &inventory[i];
5320 /* Ignore non-objects */
5321 if (!o_ptr->k_idx) continue;
5323 /* Ignore non-artifacts */
5324 if (!object_is_fixed_artifact(o_ptr)) continue;
5326 /* Ignore known items */
5327 if (object_is_known(o_ptr)) continue;
5329 /* Note the artifact */
5330 okay[o_ptr->name1] = FALSE;
5333 for (k = 0; k < max_a_idx; k++)
5335 if (okay[k]) who[n++] = k;
5338 /* Select the sort method */
5339 ang_sort_comp = ang_sort_art_comp;
5340 ang_sort_swap = ang_sort_art_swap;
5342 /* Sort the array by dungeon depth of monsters */
5343 ang_sort(who, &why, n);
5345 /* Scan the artifacts */
5346 for (k = 0; k < n; k++)
5348 artifact_type *a_ptr = &a_info[who[k]];
5351 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5353 /* Obtain the base object type */
5354 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5363 /* Create fake object */
5364 object_prep(q_ptr, z);
5366 /* Make it an artifact */
5367 q_ptr->name1 = (byte)who[k];
5369 /* Display as if known */
5370 q_ptr->ident |= IDENT_STORE;
5372 /* Describe the artifact */
5373 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5376 /* Hack -- Build the artifact name */
5377 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
5380 /* Free the "who" array */
5381 C_KILL(who, max_a_idx, s16b);
5383 /* Free the "okay" array */
5384 C_KILL(okay, max_a_idx, bool);
5387 /* Display the file contents */
5388 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5390 /* Remove the file */
5396 * Display known uniques
5397 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5399 static void do_cmd_knowledge_uniques(void)
5408 GAME_TEXT file_name[1024];
5411 int n_alive_surface = 0;
5412 int n_alive_over100 = 0;
5413 int n_alive_total = 0;
5416 for (i = 0; i < 10; i++) n_alive[i] = 0;
5418 /* Open a new file */
5419 fff = my_fopen_temp(file_name, 1024);
5423 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5428 /* Allocate the "who" array */
5429 C_MAKE(who, max_r_idx, s16b);
5431 /* Scan the monsters */
5432 for (i = 1; i < max_r_idx; i++)
5434 monster_race *r_ptr = &r_info[i];
5437 if (!r_ptr->name) continue;
5439 /* Require unique monsters */
5440 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5442 /* Only display "known" uniques */
5443 if (!cheat_know && !r_ptr->r_sights) continue;
5445 /* Only print rarity <= 100 uniques */
5446 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5448 /* Only "alive" uniques */
5449 if (r_ptr->max_num == 0) continue;
5453 lev = (r_ptr->level - 1) / 10;
5457 if (max_lev < lev) max_lev = lev;
5459 else n_alive_over100++;
5461 else n_alive_surface++;
5463 /* Collect "appropriate" monsters */
5467 /* Select the sort method */
5468 ang_sort_comp = ang_sort_comp_hook;
5469 ang_sort_swap = ang_sort_swap_hook;
5471 /* Sort the array by dungeon depth of monsters */
5472 ang_sort(who, &why, n);
5474 if (n_alive_surface)
5476 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
5477 n_alive_total += n_alive_surface;
5479 for (i = 0; i <= max_lev; i++)
5481 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5482 n_alive_total += n_alive[i];
5484 if (n_alive_over100)
5486 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
5487 n_alive_total += n_alive_over100;
5492 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
5493 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
5497 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5500 /* Scan the monster races */
5501 for (k = 0; k < n; k++)
5503 monster_race *r_ptr = &r_info[who[k]];
5505 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
5508 /* Free the "who" array */
5509 C_KILL(who, max_r_idx, s16b);
5512 /* Display the file contents */
5513 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5515 /* Remove the file */
5521 * Display weapon-exp
5523 static void do_cmd_knowledge_weapon_exp(void)
5525 int i, num, weapon_exp;
5530 GAME_TEXT file_name[1024];
5533 /* Open a new file */
5534 fff = my_fopen_temp(file_name, 1024);
5536 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5541 for (i = 0; i < 5; i++)
5543 for (num = 0; num < 64; num++)
5545 for (j = 0; j < max_k_idx; j++)
5547 object_kind *k_ptr = &k_info[j];
5549 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5551 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5553 weapon_exp = p_ptr->weapon_exp[4 - i][num];
5555 fprintf(fff, "%-25s ", tmp);
5556 if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5557 else fprintf(fff, " ");
5558 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5559 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5568 /* Display the file contents */
5569 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5571 /* Remove the file */
5577 * @brief 魔法の経験値を表示するコマンドのメインルーチン
5581 static void do_cmd_knowledge_spell_exp(void)
5584 int spell_exp, exp_level;
5587 const magic_type *s_ptr;
5589 GAME_TEXT file_name[1024];
5591 /* Open a new file */
5592 fff = my_fopen_temp(file_name, 1024);
5594 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5599 if (p_ptr->realm1 != REALM_NONE)
5601 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5602 for (i = 0; i < 32; i++)
5604 if (!is_magic(p_ptr->realm1))
5606 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5610 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5612 if (s_ptr->slevel >= 99) continue;
5613 spell_exp = p_ptr->spell_exp[i];
5614 exp_level = spell_exp_level(spell_exp);
5615 fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5616 if (p_ptr->realm1 == REALM_HISSATSU)
5617 fprintf(fff, "[--]");
5620 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5621 else fprintf(fff, " ");
5622 fprintf(fff, "%s", exp_level_str[exp_level]);
5624 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5629 if (p_ptr->realm2 != REALM_NONE)
5631 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5632 for (i = 0; i < 32; i++)
5634 if (!is_magic(p_ptr->realm1))
5636 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5640 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5642 if (s_ptr->slevel >= 99) continue;
5644 spell_exp = p_ptr->spell_exp[i + 32];
5645 exp_level = spell_exp_level(spell_exp);
5646 fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5647 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5648 else fprintf(fff, " ");
5649 fprintf(fff, "%s", exp_level_str[exp_level]);
5650 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5656 /* Display the file contents */
5657 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5659 /* Remove the file */
5665 * @brief スキル情報を表示するコマンドのメインルーチン /
5669 static void do_cmd_knowledge_skill_exp(void)
5671 int i = 0, skill_exp;
5675 GAME_TEXT file_name[1024];
5676 GAME_TEXT skill_name[3][20]={_("マーシャルアーツ", "Martial Arts "),
5677 _("二刀流 ", "Dual Wielding "),
5678 _("乗馬 ", "Riding ")};
5680 /* Open a new file */
5681 fff = my_fopen_temp(file_name, 1024);
5683 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5688 for (i = 0; i < 3; i++)
5690 skill_exp = p_ptr->skill_exp[i];
5691 fprintf(fff, "%-20s ", skill_name[i]);
5692 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5693 else fprintf(fff, " ");
5694 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5695 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5700 /* Display the file contents */
5701 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5703 /* Remove the file */
5709 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5710 * @param Name 変換したい文字列の参照ポインタ
5713 void plural_aux(char *Name)
5715 int NameLen = strlen(Name);
5717 if (my_strstr(Name, "Disembodied hand"))
5719 strcpy(Name, "Disembodied hands that strangled people");
5721 else if (my_strstr(Name, "Colour out of space"))
5723 strcpy(Name, "Colours out of space");
5725 else if (my_strstr(Name, "stairway to hell"))
5727 strcpy(Name, "stairways to hell");
5729 else if (my_strstr(Name, "Dweller on the threshold"))
5731 strcpy(Name, "Dwellers on the threshold");
5733 else if (my_strstr(Name, " of "))
5735 cptr aider = my_strstr(Name, " of ");
5746 if (dummy[i-1] == 's')
5748 strcpy(&(dummy[i]), "es");
5753 strcpy(&(dummy[i]), "s");
5756 strcpy(&(dummy[i+1]), aider);
5757 strcpy(Name, dummy);
5759 else if (my_strstr(Name, "coins"))
5762 strcpy(dummy, "piles of ");
5763 strcat(dummy, Name);
5764 strcpy(Name, dummy);
5767 else if (my_strstr(Name, "Manes"))
5771 else if (streq(&(Name[NameLen - 2]), "ey"))
5773 strcpy(&(Name[NameLen - 2]), "eys");
5775 else if (Name[NameLen - 1] == 'y')
5777 strcpy(&(Name[NameLen - 1]), "ies");
5779 else if (streq(&(Name[NameLen - 4]), "ouse"))
5781 strcpy(&(Name[NameLen - 4]), "ice");
5783 else if (streq(&(Name[NameLen - 2]), "us"))
5785 strcpy(&(Name[NameLen - 2]), "i");
5787 else if (streq(&(Name[NameLen - 6]), "kelman"))
5789 strcpy(&(Name[NameLen - 6]), "kelmen");
5791 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5793 strcpy(&(Name[NameLen - 8]), "wordsmen");
5795 else if (streq(&(Name[NameLen - 7]), "oodsman"))
5797 strcpy(&(Name[NameLen - 7]), "oodsmen");
5799 else if (streq(&(Name[NameLen - 7]), "eastman"))
5801 strcpy(&(Name[NameLen - 7]), "eastmen");
5803 else if (streq(&(Name[NameLen - 8]), "izardman"))
5805 strcpy(&(Name[NameLen - 8]), "izardmen");
5807 else if (streq(&(Name[NameLen - 5]), "geist"))
5809 strcpy(&(Name[NameLen - 5]), "geister");
5811 else if (streq(&(Name[NameLen - 2]), "ex"))
5813 strcpy(&(Name[NameLen - 2]), "ices");
5815 else if (streq(&(Name[NameLen - 2]), "lf"))
5817 strcpy(&(Name[NameLen - 2]), "lves");
5819 else if (suffix(Name, "ch") ||
5820 suffix(Name, "sh") ||
5821 suffix(Name, "nx") ||
5822 suffix(Name, "s") ||
5825 strcpy(&(Name[NameLen]), "es");
5829 strcpy(&(Name[NameLen]), "s");
5834 * @brief 現在のペットを表示するコマンドのメインルーチン /
5835 * Display current pets
5838 static void do_cmd_knowledge_pets(void)
5842 monster_type *m_ptr;
5843 GAME_TEXT pet_name[MAX_NLEN];
5845 int show_upkeep = 0;
5846 GAME_TEXT file_name[1024];
5849 /* Open a new file */
5850 fff = my_fopen_temp(file_name, 1024);
5852 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5857 /* Process the monsters (backwards) */
5858 for (i = m_max - 1; i >= 1; i--)
5860 /* Access the monster */
5863 /* Ignore "dead" monsters */
5864 if (!m_ptr->r_idx) continue;
5866 /* Calculate "upkeep" for pets */
5870 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
5871 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
5875 show_upkeep = calculate_upkeep();
5877 fprintf(fff, "----------------------------------------------\n");
5879 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
5880 fprintf(fff, " 維持コスト: %d%% MP\n", show_upkeep);
5882 fprintf(fff, " Total: %d pet%s.\n",
5883 t_friends, (t_friends == 1 ? "" : "s"));
5884 fprintf(fff, " Upkeep: %d%% mana.\n", show_upkeep);
5890 /* Display the file contents */
5891 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
5893 /* Remove the file */
5899 * @brief 現在のペットを表示するコマンドのメインルーチン /
5902 * @note the player ghosts are ignored.
5904 static void do_cmd_knowledge_kill_count(void)
5913 GAME_TEXT file_name[1024];
5918 /* Open a new file */
5919 fff = my_fopen_temp(file_name, 1024);
5922 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5927 /* Allocate the "who" array */
5928 C_MAKE(who, max_r_idx, s16b);
5931 /* Monsters slain */
5934 for (kk = 1; kk < max_r_idx; kk++)
5936 monster_race *r_ptr = &r_info[kk];
5938 if (r_ptr->flags1 & (RF1_UNIQUE))
5940 bool dead = (r_ptr->max_num == 0);
5949 MONSTER_NUMBER This = r_ptr->r_pkills;
5959 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
5962 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
5964 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
5970 /* Scan the monsters */
5971 for (i = 1; i < max_r_idx; i++)
5973 monster_race *r_ptr = &r_info[i];
5975 /* Use that monster */
5976 if (r_ptr->name) who[n++] = i;
5979 /* Select the sort method */
5980 ang_sort_comp = ang_sort_comp_hook;
5981 ang_sort_swap = ang_sort_swap_hook;
5983 /* Sort the array by dungeon depth of monsters */
5984 ang_sort(who, &why, n);
5986 /* Scan the monster races */
5987 for (k = 0; k < n; k++)
5989 monster_race *r_ptr = &r_info[who[k]];
5991 if (r_ptr->flags1 & (RF1_UNIQUE))
5993 bool dead = (r_ptr->max_num == 0);
5997 fprintf(fff, " %s\n", (r_name + r_ptr->name));
6003 MONSTER_NUMBER This = r_ptr->r_pkills;
6008 /* p,tは人と数える by ita */
6009 if (my_strchr("pt", r_ptr->d_char))
6010 fprintf(fff, " %3d 人の %s\n", (int)This, r_name + r_ptr->name);
6012 fprintf(fff, " %3d 体の %s\n", (int)This, r_name + r_ptr->name);
6016 if (my_strstr(r_name + r_ptr->name, "coins"))
6018 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
6022 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
6028 strcpy(ToPlural, (r_name + r_ptr->name));
6029 plural_aux(ToPlural);
6030 fprintf(fff, " %d %s\n", This, ToPlural);
6040 fprintf(fff,"----------------------------------------------\n");
6042 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
6044 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)Total, (Total == 1 ? "" : "s"));
6048 /* Free the "who" array */
6049 C_KILL(who, max_r_idx, s16b);
6052 /* Display the file contents */
6053 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
6055 /* Remove the file */
6061 * @brief モンスター情報リスト中のグループを表示する /
6062 * Display the object groups.
6066 * @param per_page リストの表示行
6067 * @param grp_idx グループのID配列
6068 * @param group_text グループ名の文字列配列
6069 * @param grp_cur 現在の選択ID
6070 * @param grp_top 現在の選択リスト最上部ID
6073 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)
6077 /* Display lines until done */
6078 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
6080 /* Get the group index */
6081 int grp = grp_idx[grp_top + i];
6083 /* Choose a color */
6084 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
6086 /* Erase the entire line */
6087 Term_erase(col, row + i, wid);
6089 /* Display the group label */
6090 c_put_str(attr, group_text[grp], row + i, col);
6096 * Move the cursor in a browser window
6098 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
6099 IDX *list_cur, int list_cnt)
6104 IDX list = *list_cur;
6106 /* Extract direction */
6109 /* Hack -- scroll up full screen */
6114 /* Hack -- scroll down full screen */
6119 d = get_keymap_dir(ch);
6124 /* Diagonals - hack */
6125 if ((ddx[d] > 0) && ddy[d])
6130 Term_get_size(&wid, &hgt);
6132 browser_rows = hgt - 8;
6134 /* Browse group list */
6139 /* Move up or down */
6140 grp += ddy[d] * (browser_rows - 1);
6143 if (grp >= grp_cnt) grp = grp_cnt - 1;
6144 if (grp < 0) grp = 0;
6145 if (grp != old_grp) list = 0;
6148 /* Browse sub-list list */
6151 /* Move up or down */
6152 list += ddy[d] * browser_rows;
6155 if (list >= list_cnt) list = list_cnt - 1;
6156 if (list < 0) list = 0;
6168 if (col < 0) col = 0;
6169 if (col > 1) col = 1;
6176 /* Browse group list */
6181 /* Move up or down */
6185 if (grp >= grp_cnt) grp = grp_cnt - 1;
6186 if (grp < 0) grp = 0;
6187 if (grp != old_grp) list = 0;
6190 /* Browse sub-list list */
6193 /* Move up or down */
6197 if (list >= list_cnt) list = list_cnt - 1;
6198 if (list < 0) list = 0;
6209 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
6213 /* Clear the display lines */
6214 for (i = 0; i < height; i++)
6216 Term_erase(col, row + i, width);
6219 /* Bigtile mode uses double width */
6220 if (use_bigtile) width /= 2;
6222 /* Display lines until done */
6223 for (i = 0; i < height; i++)
6225 /* Display columns until done */
6226 for (j = 0; j < width; j++)
6230 TERM_LEN x = col + j;
6231 TERM_LEN y = row + i;
6234 /* Bigtile mode uses double width */
6235 if (use_bigtile) x += j;
6240 /* Ignore illegal characters */
6241 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6242 (!use_graphics && ic > 0x7f))
6248 /* Force correct code for both ASCII character and tile */
6249 if (c & 0x80) a |= 0x80;
6251 /* Display symbol */
6252 Term_queue_bigchar(x, y, a, c, 0, 0);
6259 * Place the cursor at the collect position for visual mode
6261 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
6263 int i = (a & 0x7f) - attr_top;
6264 int j = c - char_left;
6266 TERM_LEN x = col + j;
6267 TERM_LEN y = row + i;
6269 /* Bigtile mode uses double width */
6270 if (use_bigtile) x += j;
6272 /* Place the cursor */
6278 * Clipboard variables for copy&paste in visual mode
6280 static TERM_COLOR attr_idx = 0;
6281 static byte char_idx = 0;
6283 /* Hack -- for feature lighting */
6284 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
6285 static byte char_idx_feat[F_LIT_MAX];
6288 * Do visual mode command -- Change symbols
6290 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6291 int height, int width,
6292 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
6293 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
6295 static TERM_COLOR attr_old = 0;
6296 static SYMBOL_CODE char_old = 0;
6301 if (*visual_list_ptr)
6304 *cur_attr_ptr = attr_old;
6305 *cur_char_ptr = char_old;
6306 *visual_list_ptr = FALSE;
6314 if (*visual_list_ptr)
6317 *visual_list_ptr = FALSE;
6318 *need_redraw = TRUE;
6326 if (!*visual_list_ptr)
6328 *visual_list_ptr = TRUE;
6330 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6331 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6333 attr_old = *cur_attr_ptr;
6334 char_old = *cur_char_ptr;
6345 /* Set the visual */
6346 attr_idx = *cur_attr_ptr;
6347 char_idx = *cur_char_ptr;
6349 /* Hack -- for feature lighting */
6350 for (i = 0; i < F_LIT_MAX; i++)
6352 attr_idx_feat[i] = 0;
6353 char_idx_feat[i] = 0;
6360 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6363 *cur_attr_ptr = attr_idx;
6364 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6365 if (!*visual_list_ptr) *need_redraw = TRUE;
6371 *cur_char_ptr = char_idx;
6372 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6373 if (!*visual_list_ptr) *need_redraw = TRUE;
6379 if (*visual_list_ptr)
6382 int d = get_keymap_dir(ch);
6383 byte a = (*cur_attr_ptr & 0x7f);
6384 byte c = *cur_char_ptr;
6386 if (use_bigtile) eff_width = width / 2;
6387 else eff_width = width;
6389 /* Restrict direction */
6390 if ((a == 0) && (ddy[d] < 0)) d = 0;
6391 if ((c == 0) && (ddx[d] < 0)) d = 0;
6392 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6393 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6398 /* Force correct code for both ASCII character and tile */
6399 if (c & 0x80) a |= 0x80;
6401 /* Set the visual */
6406 /* Move the frame */
6407 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6408 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6409 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6410 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6416 /* Visual mode command is not used */
6422 * Display the monsters in a group.
6424 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6425 int mon_cur, int mon_top, bool visual_only)
6429 /* Display lines until done */
6430 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6434 /* Get the race index */
6435 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6437 /* Access the race */
6438 monster_race *r_ptr = &r_info[r_idx];
6440 /* Choose a color */
6441 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6443 /* Display the name */
6444 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6446 /* Hack -- visual_list mode */
6449 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6451 if (p_ptr->wizard || visual_only)
6453 c_prt(attr, format("%d", r_idx), row + i, 62);
6456 /* Erase chars before overwritten by the race letter */
6457 Term_erase(69, row + i, 255);
6459 /* Display symbol */
6460 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6465 if (!(r_ptr->flags1 & RF1_UNIQUE))
6466 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6468 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6469 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6473 /* Clear remaining lines */
6474 for (; i < per_page; i++)
6476 Term_erase(col, row + i, 255);
6482 * Display known monsters.
6484 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6488 IDX grp_cur, grp_top, old_grp_cur;
6489 IDX mon_cur, mon_top;
6490 IDX grp_cnt, grp_idx[100];
6498 bool visual_list = FALSE;
6499 TERM_COLOR attr_top = 0;
6507 Term_get_size(&wid, &hgt);
6509 browser_rows = hgt - 8;
6511 /* Allocate the "mon_idx" array */
6512 C_MAKE(mon_idx, max_r_idx, s16b);
6517 if (direct_r_idx < 0)
6519 mode = visual_only ? 0x03 : 0x01;
6521 /* Check every group */
6522 for (i = 0; monster_group_text[i] != NULL; i++)
6524 /* Measure the label */
6525 len = strlen(monster_group_text[i]);
6527 /* Save the maximum length */
6528 if (len > max) max = len;
6530 /* See if any monsters are known */
6531 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6533 /* Build a list of groups with known monsters */
6534 grp_idx[grp_cnt++] = i;
6542 mon_idx[0] = direct_r_idx;
6545 /* Terminate the list */
6548 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6549 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6552 /* Terminate the list */
6553 grp_idx[grp_cnt] = -1;
6556 grp_cur = grp_top = 0;
6557 mon_cur = mon_top = 0;
6562 mode = visual_only ? 0x02 : 0x00;
6567 monster_race *r_ptr;
6574 prt(format("%s - モンスター", !visual_only ? "知識" : "表示"), 2, 0);
6575 if (direct_r_idx < 0) prt("グループ", 4, 0);
6576 prt("名前", 4, max + 3);
6577 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6579 if (!visual_only) prt("殺害数", 4, 72);
6581 prt(format("%s - monsters", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6582 if (direct_r_idx < 0) prt("Group", 4, 0);
6583 prt("Name", 4, max + 3);
6584 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6586 if (!visual_only) prt("Kills", 4, 73);
6589 for (i = 0; i < 78; i++)
6591 Term_putch(i, 5, TERM_WHITE, '=');
6594 if (direct_r_idx < 0)
6596 for (i = 0; i < browser_rows; i++)
6598 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6605 if (direct_r_idx < 0)
6607 /* Scroll group list */
6608 if (grp_cur < grp_top) grp_top = grp_cur;
6609 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6611 /* Display a list of monster groups */
6612 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6614 if (old_grp_cur != grp_cur)
6616 old_grp_cur = grp_cur;
6618 /* Get a list of monsters in the current group */
6619 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6622 /* Scroll monster list */
6623 while (mon_cur < mon_top)
6624 mon_top = MAX(0, mon_top - browser_rows/2);
6625 while (mon_cur >= mon_top + browser_rows)
6626 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6631 /* Display a list of monsters in the current group */
6632 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6638 /* Display a monster name */
6639 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6641 /* Display visual list below first monster */
6642 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6647 prt(format("<方向>%s%s%s, ESC",
6648 (!visual_list && !visual_only) ? ", 'r'で思い出を見る" : "",
6649 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
6650 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
6653 prt(format("<dir>%s%s%s, ESC",
6654 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
6655 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
6656 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
6660 /* Get the current monster */
6661 r_ptr = &r_info[mon_idx[mon_cur]];
6665 /* Mega Hack -- track this monster race */
6666 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6672 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6676 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6680 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6685 /* Do visual mode command if needed */
6686 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))
6688 if (direct_r_idx >= 0)
6713 /* Recall on screen */
6714 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6716 screen_roff(mon_idx[mon_cur], 0);
6727 /* Move the cursor */
6728 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6735 /* Free the "mon_idx" array */
6736 C_KILL(mon_idx, max_r_idx, s16b);
6741 * Display the objects in a group.
6743 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6744 int object_cur, int object_top, bool visual_only)
6748 /* Display lines until done */
6749 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6751 GAME_TEXT o_name[MAX_NLEN];
6754 object_kind *flavor_k_ptr;
6756 /* Get the object index */
6757 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6759 /* Access the object */
6760 object_kind *k_ptr = &k_info[k_idx];
6762 /* Choose a color */
6763 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6764 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6767 if (!visual_only && k_ptr->flavor)
6769 /* Appearance of this object is shuffled */
6770 flavor_k_ptr = &k_info[k_ptr->flavor];
6774 /* Appearance of this object is very normal */
6775 flavor_k_ptr = k_ptr;
6780 attr = ((i + object_top == object_cur) ? cursor : attr);
6782 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6785 strip_name(o_name, k_idx);
6790 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
6793 /* Display the name */
6794 c_prt(attr, o_name, row + i, col);
6796 /* Hack -- visual_list mode */
6799 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);
6801 if (p_ptr->wizard || visual_only)
6803 c_prt(attr, format("%d", k_idx), row + i, 70);
6806 a = flavor_k_ptr->x_attr;
6807 c = flavor_k_ptr->x_char;
6809 /* Display symbol */
6810 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
6813 /* Clear remaining lines */
6814 for (; i < per_page; i++)
6816 Term_erase(col, row + i, 255);
6821 * Describe fake object
6823 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
6826 object_type object_type_body;
6827 o_ptr = &object_type_body;
6830 /* Create the artifact */
6831 object_prep(o_ptr, k_idx);
6833 /* It's fully know */
6834 o_ptr->ident |= IDENT_KNOWN;
6836 /* Track the object */
6837 /* object_actual_track(o_ptr); */
6839 /* Hack - mark as fake */
6840 /* term_obj_real = FALSE; */
6843 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
6845 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
6853 * Display known objects
6855 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
6859 IDX grp_cur, grp_top, old_grp_cur;
6860 IDX object_old, object_cur, object_top;
6870 bool visual_list = FALSE;
6871 TERM_COLOR attr_top = 0;
6879 Term_get_size(&wid, &hgt);
6881 browser_rows = hgt - 8;
6883 /* Allocate the "object_idx" array */
6884 C_MAKE(object_idx, max_k_idx, IDX);
6889 if (direct_k_idx < 0)
6891 mode = visual_only ? 0x03 : 0x01;
6893 /* Check every group */
6894 for (i = 0; object_group_text[i] != NULL; i++)
6896 /* Measure the label */
6897 len = strlen(object_group_text[i]);
6899 /* Save the maximum length */
6900 if (len > max) max = len;
6902 /* See if any monsters are known */
6903 if (collect_objects(i, object_idx, mode))
6905 /* Build a list of groups with known monsters */
6906 grp_idx[grp_cnt++] = i;
6915 object_kind *k_ptr = &k_info[direct_k_idx];
6916 object_kind *flavor_k_ptr;
6918 if (!visual_only && k_ptr->flavor)
6920 /* Appearance of this object is shuffled */
6921 flavor_k_ptr = &k_info[k_ptr->flavor];
6925 /* Appearance of this object is very normal */
6926 flavor_k_ptr = k_ptr;
6929 object_idx[0] = direct_k_idx;
6930 object_old = direct_k_idx;
6933 /* Terminate the list */
6936 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6937 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
6940 /* Terminate the list */
6941 grp_idx[grp_cnt] = -1;
6944 grp_cur = grp_top = 0;
6945 object_cur = object_top = 0;
6950 mode = visual_only ? 0x02 : 0x00;
6955 object_kind *k_ptr, *flavor_k_ptr;
6962 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
6963 if (direct_k_idx < 0) prt("グループ", 4, 0);
6964 prt("名前", 4, max + 3);
6965 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6968 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6969 if (direct_k_idx < 0) prt("Group", 4, 0);
6970 prt("Name", 4, max + 3);
6971 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6975 for (i = 0; i < 78; i++)
6977 Term_putch(i, 5, TERM_WHITE, '=');
6980 if (direct_k_idx < 0)
6982 for (i = 0; i < browser_rows; i++)
6984 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6991 if (direct_k_idx < 0)
6993 /* Scroll group list */
6994 if (grp_cur < grp_top) grp_top = grp_cur;
6995 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6997 /* Display a list of object groups */
6998 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
7000 if (old_grp_cur != grp_cur)
7002 old_grp_cur = grp_cur;
7004 /* Get a list of objects in the current group */
7005 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
7008 /* Scroll object list */
7009 while (object_cur < object_top)
7010 object_top = MAX(0, object_top - browser_rows/2);
7011 while (object_cur >= object_top + browser_rows)
7012 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
7017 /* Display a list of objects in the current group */
7018 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
7022 object_top = object_cur;
7024 /* Display a list of objects in the current group */
7025 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
7027 /* Display visual list below first object */
7028 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7031 /* Get the current object */
7032 k_ptr = &k_info[object_idx[object_cur]];
7034 if (!visual_only && k_ptr->flavor)
7036 /* Appearance of this object is shuffled */
7037 flavor_k_ptr = &k_info[k_ptr->flavor];
7041 /* Appearance of this object is very normal */
7042 flavor_k_ptr = k_ptr;
7047 prt(format("<方向>%s%s%s, ESC",
7048 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
7049 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
7050 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
7053 prt(format("<dir>%s%s%s, ESC",
7054 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
7055 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
7056 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
7062 /* Mega Hack -- track this object */
7063 if (object_cnt) object_kind_track(object_idx[object_cur]);
7065 /* The "current" object changed */
7066 if (object_old != object_idx[object_cur])
7070 /* Remember the "current" object */
7071 object_old = object_idx[object_cur];
7077 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
7081 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7085 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
7090 /* Do visual mode command if needed */
7091 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))
7093 if (direct_k_idx >= 0)
7118 /* Recall on screen */
7119 if (!visual_list && !visual_only && (grp_cnt > 0))
7121 desc_obj_fake(object_idx[object_cur]);
7129 /* Move the cursor */
7130 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
7136 /* Free the "object_idx" array */
7137 C_KILL(object_idx, max_k_idx, IDX);
7142 * Display the features in a group.
7144 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
7145 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
7147 int lit_col[F_LIT_MAX], i, j;
7148 int f_idx_col = use_bigtile ? 62 : 64;
7150 /* Correct columns 1 and 4 */
7151 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
7152 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7153 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
7155 /* Display lines until done */
7156 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
7161 FEAT_IDX f_idx = feat_idx[feat_top + i];
7163 /* Access the index */
7164 feature_type *f_ptr = &f_info[f_idx];
7166 int row_i = row + i;
7168 /* Choose a color */
7169 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
7171 /* Display the name */
7172 c_prt(attr, f_name + f_ptr->name, row_i, col);
7174 /* Hack -- visual_list mode */
7177 /* Display lighting level */
7178 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
7180 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));
7182 if (p_ptr->wizard || visual_only)
7184 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7187 /* Display symbol */
7188 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);
7190 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7191 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7193 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7195 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7197 /* Mega-hack -- Use non-standard colour */
7198 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7200 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7204 /* Clear remaining lines */
7205 for (; i < per_page; i++)
7207 Term_erase(col, row + i, 255);
7213 * Interact with feature visuals.
7215 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7219 IDX grp_cur, grp_top, old_grp_cur;
7220 IDX feat_cur, feat_top;
7230 bool visual_list = FALSE;
7231 TERM_COLOR attr_top = 0;
7237 TERM_COLOR attr_old[F_LIT_MAX];
7238 SYMBOL_CODE char_old[F_LIT_MAX];
7239 TERM_COLOR *cur_attr_ptr;
7240 SYMBOL_CODE *cur_char_ptr;
7242 (void)C_WIPE(attr_old, F_LIT_MAX, byte);
7243 (void)C_WIPE(char_old, F_LIT_MAX, byte);
7245 Term_get_size(&wid, &hgt);
7247 browser_rows = hgt - 8;
7249 /* Allocate the "feat_idx" array */
7250 C_MAKE(feat_idx, max_f_idx, IDX);
7255 if (direct_f_idx < 0)
7257 /* Check every group */
7258 for (i = 0; feature_group_text[i] != NULL; i++)
7260 /* Measure the label */
7261 len = strlen(feature_group_text[i]);
7263 /* Save the maximum length */
7264 if (len > max) max = len;
7266 /* See if any features are known */
7267 if (collect_features(i, feat_idx, 0x01))
7269 /* Build a list of groups with known features */
7270 grp_idx[grp_cnt++] = i;
7278 feature_type *f_ptr = &f_info[direct_f_idx];
7280 feat_idx[0] = direct_f_idx;
7283 /* Terminate the list */
7286 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7287 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7289 for (i = 0; i < F_LIT_MAX; i++)
7291 attr_old[i] = f_ptr->x_attr[i];
7292 char_old[i] = f_ptr->x_char[i];
7296 /* Terminate the list */
7297 grp_idx[grp_cnt] = -1;
7300 grp_cur = grp_top = 0;
7301 feat_cur = feat_top = 0;
7309 feature_type *f_ptr;
7316 prt("表示 - 地形", 2, 0);
7317 if (direct_f_idx < 0) prt("グループ", 4, 0);
7318 prt("名前", 4, max + 3);
7321 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7322 prt("文字 ( l/ d)", 4, 66);
7326 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7327 prt("文字 (l/d)", 4, 68);
7330 prt("Visuals - features", 2, 0);
7331 if (direct_f_idx < 0) prt("Group", 4, 0);
7332 prt("Name", 4, max + 3);
7335 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7336 prt("Sym ( l/ d)", 4, 67);
7340 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7341 prt("Sym (l/d)", 4, 69);
7345 for (i = 0; i < 78; i++)
7347 Term_putch(i, 5, TERM_WHITE, '=');
7350 if (direct_f_idx < 0)
7352 for (i = 0; i < browser_rows; i++)
7354 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7361 if (direct_f_idx < 0)
7363 /* Scroll group list */
7364 if (grp_cur < grp_top) grp_top = grp_cur;
7365 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7367 /* Display a list of feature groups */
7368 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7370 if (old_grp_cur != grp_cur)
7372 old_grp_cur = grp_cur;
7374 /* Get a list of features in the current group */
7375 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7378 /* Scroll feature list */
7379 while (feat_cur < feat_top)
7380 feat_top = MAX(0, feat_top - browser_rows/2);
7381 while (feat_cur >= feat_top + browser_rows)
7382 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7387 /* Display a list of features in the current group */
7388 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7392 feat_top = feat_cur;
7394 /* Display a list of features in the current group */
7395 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7397 /* Display visual list below first object */
7398 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7403 prt(format("<方向>%s, 'd'で標準光源効果%s, ESC",
7404 visual_list ? ", ENTERで決定, 'a'で対象明度変更" : ", 'v'でシンボル変更",
7405 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
7408 prt(format("<dir>%s, 'd' for default lighting%s, ESC",
7409 visual_list ? ", ENTER to accept, 'a' for lighting level" : ", 'v' for visuals",
7410 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
7414 /* Get the current feature */
7415 f_ptr = &f_info[feat_idx[feat_cur]];
7416 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7417 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7421 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7425 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7429 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7434 if (visual_list && ((ch == 'A') || (ch == 'a')))
7436 int prev_lighting_level = *lighting_level;
7440 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7441 else (*lighting_level)--;
7445 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7446 else (*lighting_level)++;
7449 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7450 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7452 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7453 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7458 else if ((ch == 'D') || (ch == 'd'))
7460 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
7461 byte prev_x_char = f_ptr->x_char[*lighting_level];
7463 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7467 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7468 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7470 if (prev_x_char != f_ptr->x_char[*lighting_level])
7471 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7473 else *need_redraw = TRUE;
7478 /* Do visual mode command if needed */
7479 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))
7483 /* Restore previous visual settings */
7485 for (i = 0; i < F_LIT_MAX; i++)
7487 f_ptr->x_attr[i] = attr_old[i];
7488 f_ptr->x_char[i] = char_old[i];
7495 if (direct_f_idx >= 0) flag = TRUE;
7496 else *lighting_level = F_LIT_STANDARD;
7499 /* Preserve current visual settings */
7502 for (i = 0; i < F_LIT_MAX; i++)
7504 attr_old[i] = f_ptr->x_attr[i];
7505 char_old[i] = f_ptr->x_char[i];
7507 *lighting_level = F_LIT_STANDARD;
7514 for (i = 0; i < F_LIT_MAX; i++)
7516 attr_idx_feat[i] = f_ptr->x_attr[i];
7517 char_idx_feat[i] = f_ptr->x_char[i];
7526 /* Allow TERM_DARK text */
7527 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7529 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7530 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7548 /* Move the cursor */
7549 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7555 /* Free the "feat_idx" array */
7556 C_KILL(feat_idx, max_f_idx, IDX);
7561 * List wanted monsters
7563 static void do_cmd_knowledge_kubi(void)
7568 GAME_TEXT file_name[1024];
7571 /* Open a new file */
7572 fff = my_fopen_temp(file_name, 1024);
7574 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7581 bool listed = FALSE;
7584 fprintf(fff, "今日のターゲット : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "不明"));
7586 fprintf(fff, "賞金首リスト\n");
7588 fprintf(fff, "Today target : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "unknown"));
7590 fprintf(fff, "List of wanted monsters\n");
7592 fprintf(fff, "----------------------------------------------\n");
7594 for (i = 0; i < MAX_KUBI; i++)
7596 if (kubi_r_idx[i] <= 10000)
7598 fprintf(fff,"%s\n", r_name + r_info[kubi_r_idx[i]].name);
7606 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7611 /* Display the file contents */
7612 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7614 /* Remove the file */
7619 * List virtues & status
7621 static void do_cmd_knowledge_virtues(void)
7624 GAME_TEXT file_name[1024];
7626 /* Open a new file */
7627 fff = my_fopen_temp(file_name, 1024);
7629 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7636 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7641 /* Display the file contents */
7642 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7644 /* Remove the file */
7652 static void do_cmd_knowledge_dungeon(void)
7656 GAME_TEXT file_name[1024];
7659 /* Open a new file */
7660 fff = my_fopen_temp(file_name, 1024);
7662 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7669 for (i = 1; i < max_d_idx; i++)
7673 if (!d_info[i].maxdepth) continue;
7674 if (!max_dlv[i]) continue;
7675 if (d_info[i].final_guardian)
7677 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7679 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7681 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7686 /* Display the file contents */
7687 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7689 /* Remove the file */
7694 * List virtues & status
7697 static void do_cmd_knowledge_stat(void)
7701 GAME_TEXT file_name[1024];
7704 /* Open a new file */
7705 fff = my_fopen_temp(file_name, 1024);
7707 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7714 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7715 (2 * p_ptr->hitdie +
7716 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7719 if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "現在の体力ランク : %d/100\n\n", percent);
7720 else fprintf(fff, "現在の体力ランク : ???\n\n");
7721 fprintf(fff, "能力の最大値\n\n");
7723 if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "Your current Life Rating is %d/100.\n\n", percent);
7724 else fprintf(fff, "Your current Life Rating is ???.\n\n");
7725 fprintf(fff, "Limits of maximum stats\n\n");
7727 for (v_nr = 0; v_nr < 6; v_nr++)
7729 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);
7730 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7737 /* Display the file contents */
7738 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7740 /* Remove the file */
7746 * Print all active quests
7748 static void do_cmd_knowledge_quests_current(FILE *fff)
7751 char rand_tmp_str[120] = "\0";
7752 GAME_TEXT name[MAX_NLEN];
7753 monster_race *r_ptr;
7755 int rand_level = 100;
7758 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7760 for (i = 1; i < max_q_idx; i++)
7762 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7763 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7764 (quest[i].status == QUEST_STATUS_COMPLETED))
7766 /* Set the quest number temporary */
7767 IDX old_quest = p_ptr->inside_quest;
7770 /* Clear the text */
7771 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7772 quest_text_line = 0;
7774 p_ptr->inside_quest = i;
7776 /* Get the quest text */
7777 init_flags = INIT_SHOW_TEXT;
7779 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7781 /* Reset the old quest number */
7782 p_ptr->inside_quest = old_quest;
7784 /* No info from "silent" quests */
7785 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7789 if (quest[i].type != QUEST_TYPE_RANDOM)
7791 char note[80] = "\0";
7793 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
7795 switch (quest[i].type)
7797 case QUEST_TYPE_KILL_LEVEL:
7798 case QUEST_TYPE_KILL_ANY_LEVEL:
7799 r_ptr = &r_info[quest[i].r_idx];
7800 strcpy(name, r_name + r_ptr->name);
7801 if (quest[i].max_num > 1)
7804 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
7805 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7808 sprintf(note," - kill %d %s, have killed %d.",
7809 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7813 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
7816 case QUEST_TYPE_FIND_ARTIFACT:
7819 artifact_type *a_ptr = &a_info[quest[i].k_idx];
7821 object_type *q_ptr = &forge;
7822 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
7823 object_prep(q_ptr, k_idx);
7824 q_ptr->name1 = quest[i].k_idx;
7825 q_ptr->ident = IDENT_STORE;
7826 object_desc(name, q_ptr, OD_NAME_ONLY);
7828 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find out %s."), name);
7830 case QUEST_TYPE_FIND_EXIT:
7831 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
7834 case QUEST_TYPE_KILL_NUMBER:
7836 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
7837 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
7839 sprintf(note," - Kill %d monsters, have killed %d.",
7840 (int)quest[i].max_num, (int)quest[i].cur_num);
7844 case QUEST_TYPE_KILL_ALL:
7845 case QUEST_TYPE_TOWER:
7846 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
7851 /* Print the quest info */
7852 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
7853 quest[i].name, (int)quest[i].level, note);
7855 fputs(tmp_str, fff);
7857 if (quest[i].status == QUEST_STATUS_COMPLETED)
7859 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
7860 fputs(tmp_str, fff);
7866 while (quest_text[j][0] && j < 10)
7868 fprintf(fff, " %s\n", quest_text[j]);
7873 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
7876 rand_level = quest[i].level;
7878 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
7880 /* Print the quest info */
7881 r_ptr = &r_info[quest[i].r_idx];
7882 strcpy(name, r_name + r_ptr->name);
7884 if (quest[i].max_num > 1)
7887 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
7888 quest[i].name, (int)quest[i].level,
7889 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7893 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
7894 quest[i].name, (int)quest[i].level,
7895 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7900 sprintf(rand_tmp_str,_(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
7901 quest[i].name, (int)quest[i].level, name);
7908 /* Print the current random quest */
7909 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
7911 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7915 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
7918 char playtime_str[16];
7919 quest_type* const q_ptr = &quest[q_idx];
7921 if (is_fixed_quest_idx(q_idx))
7923 /* Set the quest number temporary */
7924 IDX old_quest = p_ptr->inside_quest;
7926 p_ptr->inside_quest = q_idx;
7929 init_flags = INIT_NAME_ONLY;
7931 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7933 /* Reset the old quest number */
7934 p_ptr->inside_quest = old_quest;
7936 /* No info from "silent" quests */
7937 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
7940 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
7941 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
7943 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
7945 /* Print the quest info */
7946 if (q_ptr->complev == 0)
7949 _(" %-35s (%3d階) - 不戦勝 - %s\n",
7950 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
7951 r_name+r_info[q_ptr->r_idx].name,
7952 (int)q_ptr->level, playtime_str);
7957 _(" %-35s (%3d階) - レベル%2d - %s\n",
7958 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
7959 r_name+r_info[q_ptr->r_idx].name,
7967 /* Print the quest info */
7969 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
7970 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
7971 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
7974 fputs(tmp_str, fff);
7980 * Print all finished quests
7982 void do_cmd_knowledge_quests_completed(FILE *fff, IDX quest_num[])
7987 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
7988 for (i = 1; i < max_q_idx; i++)
7990 IDX q_idx = quest_num[i];
7991 quest_type* const q_ptr = &quest[q_idx];
7993 if (q_ptr->status == QUEST_STATUS_FINISHED &&
7994 do_cmd_knowledge_quests_aux(fff, q_idx))
7999 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
8004 * Print all failed quests
8006 void do_cmd_knowledge_quests_failed(FILE *fff, IDX quest_num[])
8011 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
8012 for (i = 1; i < max_q_idx; i++)
8014 IDX q_idx = quest_num[i];
8015 quest_type* const q_ptr = &quest[q_idx];
8017 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
8018 do_cmd_knowledge_quests_aux(fff, q_idx))
8023 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
8028 * Print all random quests
8030 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
8036 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
8037 for (i = 1; i < max_q_idx; i++)
8039 /* No info from "silent" quests */
8040 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
8042 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
8046 /* Print the quest info */
8047 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
8048 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
8049 fputs(tmp_str, fff);
8052 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
8056 bool ang_sort_comp_quest_num(vptr u, vptr v, int a, int b)
8058 QUEST_IDX *q_num = (QUEST_IDX *)u;
8059 quest_type *qa = &quest[q_num[a]];
8060 quest_type *qb = &quest[q_num[b]];
8065 return (qa->comptime != qb->comptime) ?
8066 (qa->comptime < qb->comptime) :
8067 (qa->level <= qb->level);
8070 void ang_sort_swap_quest_num(vptr u, vptr v, int a, int b)
8072 QUEST_IDX *q_num = (QUEST_IDX *)u;
8079 q_num[a] = q_num[b];
8085 * Print quest status of all active quests
8087 static void do_cmd_knowledge_quests(void)
8090 GAME_TEXT file_name[1024];
8095 /* Open a new file */
8096 fff = my_fopen_temp(file_name, 1024);
8099 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8104 /* Allocate Memory */
8105 C_MAKE(quest_num, max_q_idx, IDX);
8107 /* Sort by compete level */
8108 for (i = 1; i < max_q_idx; i++) quest_num[i] = i;
8109 ang_sort_comp = ang_sort_comp_quest_num;
8110 ang_sort_swap = ang_sort_swap_quest_num;
8111 ang_sort(quest_num, &dummy, max_q_idx);
8113 /* Dump Quest Information */
8114 do_cmd_knowledge_quests_current(fff);
8116 do_cmd_knowledge_quests_completed(fff, quest_num);
8118 do_cmd_knowledge_quests_failed(fff, quest_num);
8122 do_cmd_knowledge_quests_wiz_random(fff);
8126 /* Display the file contents */
8127 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
8129 /* Remove the file */
8133 C_KILL(quest_num, max_q_idx, IDX);
8140 static void do_cmd_knowledge_home(void)
8145 GAME_TEXT file_name[1024];
8147 GAME_TEXT o_name[MAX_NLEN];
8150 process_dungeon_file("w_info.txt", 0, 0, max_wild_y, max_wild_x);
8152 /* Open a new file */
8153 fff = my_fopen_temp(file_name, 1024);
8155 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8162 /* Print all homes in the different towns */
8163 st_ptr = &town[1].store[STORE_HOME];
8165 /* Home -- if anything there */
8166 if (st_ptr->stock_num)
8171 /* Header with name of the town */
8172 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
8174 /* Dump all available items */
8175 for (i = 0; i < st_ptr->stock_num; i++)
8178 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
8179 object_desc(o_name, &st_ptr->stock[i], 0);
8180 if (strlen(o_name) <= 80-3)
8182 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8188 for (n = 0, t = o_name; n < 80-3; n++, t++)
8189 if(iskanji(*t)) {t++; n++;}
8190 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
8192 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
8193 fprintf(fff, " %.77s\n", o_name+n);
8196 object_desc(o_name, &st_ptr->stock[i], 0);
8197 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8202 /* Add an empty line */
8203 fprintf(fff, "\n\n");
8208 /* Display the file contents */
8209 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
8211 /* Remove the file */
8217 * Check the status of "autopick"
8219 static void do_cmd_knowledge_autopick(void)
8223 GAME_TEXT file_name[1024];
8225 /* Open a new file */
8226 fff = my_fopen_temp(file_name, 1024);
8230 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8237 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
8241 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
8242 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
8245 for (k = 0; k < max_autopick; k++)
8248 byte act = autopick_list[k].action;
8249 if (act & DONT_AUTOPICK)
8251 tmp = _("放置", "Leave");
8253 else if (act & DO_AUTODESTROY)
8255 tmp = _("破壊", "Destroy");
8257 else if (act & DO_AUTOPICK)
8259 tmp = _("拾う", "Pickup");
8263 tmp = _("確認", "Query");
8266 if (act & DO_DISPLAY)
8267 fprintf(fff, "%11s", format("[%s]", tmp));
8269 fprintf(fff, "%11s", format("(%s)", tmp));
8271 tmp = autopick_line_from_entry(&autopick_list[k]);
8272 fprintf(fff, " %s", tmp);
8277 /* Display the file contents */
8278 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8280 /* Remove the file */
8286 * Interact with "knowledge"
8288 void do_cmd_knowledge(void)
8291 bool need_redraw = FALSE;
8293 /* File type is "TEXT" */
8294 FILE_TYPE(FILE_TYPE_TEXT);
8297 /* Interact until done */
8302 /* Ask for a choice */
8303 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
8304 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
8306 /* Give some choices */
8310 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8311 prt("(2) 既知のアイテム の一覧", 7, 5);
8312 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8313 prt("(4) 既知のモンスター の一覧", 9, 5);
8314 prt("(5) 倒した敵の数 の一覧", 10, 5);
8315 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8316 prt("(7) 現在のペット の一覧", 12, 5);
8317 prt("(8) 我が家のアイテム の一覧", 13, 5);
8318 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8319 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8323 prt("(a) 自分に関する情報 の一覧", 6, 5);
8324 prt("(b) 突然変異 の一覧", 7, 5);
8325 prt("(c) 武器の経験値 の一覧", 8, 5);
8326 prt("(d) 魔法の経験値 の一覧", 9, 5);
8327 prt("(e) 技能の経験値 の一覧", 10, 5);
8328 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8329 prt("(g) 入ったダンジョン の一覧", 12, 5);
8330 prt("(h) 実行中のクエスト の一覧", 13, 5);
8331 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8336 prt("(1) Display known artifacts", 6, 5);
8337 prt("(2) Display known objects", 7, 5);
8338 prt("(3) Display remaining uniques", 8, 5);
8339 prt("(4) Display known monster", 9, 5);
8340 prt("(5) Display kill count", 10, 5);
8341 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8342 prt("(7) Display current pets", 12, 5);
8343 prt("(8) Display home inventory", 13, 5);
8344 prt("(9) Display *identified* equip.", 14, 5);
8345 prt("(0) Display terrain symbols.", 15, 5);
8349 prt("(a) Display about yourself", 6, 5);
8350 prt("(b) Display mutations", 7, 5);
8351 prt("(c) Display weapon proficiency", 8, 5);
8352 prt("(d) Display spell proficiency", 9, 5);
8353 prt("(e) Display misc. proficiency", 10, 5);
8354 prt("(f) Display virtues", 11, 5);
8355 prt("(g) Display dungeons", 12, 5);
8356 prt("(h) Display current quests", 13, 5);
8357 prt("(i) Display auto pick/destroy", 14, 5);
8361 prt(_("-続く-", "-more-"), 17, 8);
8362 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
8363 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
8364 /*prt("-) 前ページ", 21, 60);*/
8365 prt(_("コマンド:", "Command: "), 20, 0);
8368 if (i == ESCAPE) break;
8371 case ' ': /* Page change */
8375 case '1': /* Artifacts */
8376 do_cmd_knowledge_artifacts();
8378 case '2': /* Objects */
8379 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8381 case '3': /* Uniques */
8382 do_cmd_knowledge_uniques();
8384 case '4': /* Monsters */
8385 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8387 case '5': /* Kill count */
8388 do_cmd_knowledge_kill_count();
8390 case '6': /* wanted */
8391 if (!vanilla_town) do_cmd_knowledge_kubi();
8393 case '7': /* Pets */
8394 do_cmd_knowledge_pets();
8396 case '8': /* Home */
8397 do_cmd_knowledge_home();
8399 case '9': /* Resist list */
8400 do_cmd_knowledge_inven();
8402 case '0': /* Feature list */
8404 IDX lighting_level = F_LIT_STANDARD;
8405 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8409 case 'a': /* Max stat */
8410 do_cmd_knowledge_stat();
8412 case 'b': /* Mutations */
8413 do_cmd_knowledge_mutations();
8415 case 'c': /* weapon-exp */
8416 do_cmd_knowledge_weapon_exp();
8418 case 'd': /* spell-exp */
8419 do_cmd_knowledge_spell_exp();
8421 case 'e': /* skill-exp */
8422 do_cmd_knowledge_skill_exp();
8424 case 'f': /* Virtues */
8425 do_cmd_knowledge_virtues();
8427 case 'g': /* Dungeon */
8428 do_cmd_knowledge_dungeon();
8430 case 'h': /* Quests */
8431 do_cmd_knowledge_quests();
8433 case 'i': /* Autopick */
8434 do_cmd_knowledge_autopick();
8436 default: /* Unknown option */
8444 if (need_redraw) do_cmd_redraw();
8449 * Check on the status of an active quest
8451 void do_cmd_checkquest(void)
8453 /* File type is "TEXT" */
8454 FILE_TYPE(FILE_TYPE_TEXT);
8458 do_cmd_knowledge_quests();
8464 * Display the time and date
8466 void do_cmd_time(void)
8468 int day, hour, min, full, start, end, num;
8476 extract_day_hour_min(&day, &hour, &min);
8478 full = hour * 100 + min;
8485 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8487 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8488 else strcpy(day_buf, "*****");
8491 msg_format("%s日目, 時刻は%d:%02d %sです。",
8492 day_buf, (hour % 12 == 0) ? 12 : (hour % 12),
8493 min, (hour < 12) ? "AM" : "PM");
8495 msg_format("This is day %s. The time is %d:%02d %s.",
8496 day_buf, (hour % 12 == 0) ? 12 : (hour % 12),
8497 min, (hour < 12) ? "AM" : "PM");
8502 if (!randint0(10) || p_ptr->image)
8504 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8508 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8511 /* Open this file */
8512 fff = my_fopen(buf, "rt");
8516 /* Find this time */
8517 while (!my_fgets(fff, buf, sizeof(buf)))
8519 /* Ignore comments */
8520 if (!buf[0] || (buf[0] == '#')) continue;
8522 /* Ignore invalid lines */
8523 if (buf[1] != ':') continue;
8525 /* Process 'Start' */
8528 /* Extract the starting time */
8529 start = atoi(buf + 2);
8531 /* Assume valid for an hour */
8541 /* Extract the ending time */
8542 end = atoi(buf + 2);
8548 /* Ignore incorrect range */
8549 if ((start > full) || (full > end)) continue;
8551 /* Process 'Description' */
8556 /* Apply the randomizer */
8557 if (!randint0(num)) strcpy(desc, buf + 2);