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"
53 * Mark strings for auto dump
55 static char auto_dump_header[] = "# vvvvvvv== %s ==vvvvvvv";
56 static char auto_dump_footer[] = "# ^^^^^^^== %s ==^^^^^^^";
59 * Variables for auto dump
61 static FILE *auto_dump_stream;
62 static cptr auto_dump_mark;
63 static int auto_dump_line_num;
67 * @brief prf出力内容を消去する /
68 * Remove old lines automatically generated before.
69 * @param orig_file 消去を行うファイル名
71 static void remove_auto_dump(cptr orig_file)
73 FILE *tmp_fff, *orig_fff;
77 bool between_mark = FALSE;
80 long header_location = 0;
81 char header_mark_str[80];
82 char footer_mark_str[80];
85 /* Prepare a header/footer mark string */
86 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
87 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
89 mark_len = strlen(footer_mark_str);
91 /* Open an old dump file in read-only mode */
92 orig_fff = my_fopen(orig_file, "r");
94 /* If original file does not exist, nothing to do */
95 if (!orig_fff) return;
97 /* Open a new (temporary) file */
98 tmp_fff = my_fopen_temp(tmp_file, 1024);
102 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), tmp_file);
107 /* Loop for every line */
111 if (my_fgets(orig_fff, buf, sizeof(buf)))
113 /* Read error: Assume End of File */
116 * Was looking for the footer, but not found.
118 * Since automatic dump might be edited by hand,
119 * it's dangerous to kill these lines.
120 * Seek back to the next line of the (pseudo) header,
125 fseek(orig_fff, header_location, SEEK_SET);
126 between_mark = FALSE;
130 /* Success -- End the loop */
137 /* We are looking for the header mark of automatic dump */
140 /* Is this line a header? */
141 if (!strcmp(buf, header_mark_str))
143 /* Memorise seek point of this line */
144 header_location = ftell(orig_fff);
146 /* Initialize counter for number of lines */
149 /* Look for the footer from now */
152 /* There are some changes */
159 /* Copy orginally lines */
160 fprintf(tmp_fff, "%s\n", buf);
164 /* We are looking for the footer mark of automatic dump */
167 /* Is this line a footer? */
168 if (!strncmp(buf, footer_mark_str, mark_len))
173 * Compare the number of lines
175 * If there is an inconsistency between
176 * actual number of lines and the
177 * number here, the automatic dump
178 * might be edited by hand. So it's
179 * dangerous to kill these lines.
180 * Seek back to the next line of the
181 * (pseudo) header, and read again.
183 if (!sscanf(buf + mark_len, " (%d)", &tmp)
186 fseek(orig_fff, header_location, SEEK_SET);
189 /* Look for another header */
190 between_mark = FALSE;
196 /* Ignore old line, and count number of lines */
206 /* If there are some changes, overwrite the original file with new one */
209 /* Copy contents of temporary file */
211 tmp_fff = my_fopen(tmp_file, "r");
212 orig_fff = my_fopen(orig_file, "w");
214 while (!my_fgets(tmp_fff, buf, sizeof(buf)))
215 fprintf(orig_fff, "%s\n", buf);
221 /* Kill the temporary file */
229 * @brief prfファイルのフォーマットに従った内容を出力する /
230 * Dump a formatted line, using "vstrnfmt()".
233 static void auto_dump_printf(cptr fmt, ...)
240 /* Begin the Varargs Stuff */
243 /* Format the args, save the length */
244 (void)vstrnfmt(buf, sizeof(buf), fmt, vp);
246 /* End the Varargs Stuff */
249 /* Count number of lines */
250 for (p = buf; *p; p++)
252 if (*p == '\n') auto_dump_line_num++;
256 fprintf(auto_dump_stream, "%s", buf);
261 * @brief prfファイルをファイルオープンする /
262 * Open file to append auto dump.
264 * @param mark 出力するヘッダマーク
265 * @return ファイルポインタを取得できたらTRUEを返す
267 static bool open_auto_dump(cptr buf, cptr mark)
270 char header_mark_str[80];
272 /* Save the mark string */
273 auto_dump_mark = mark;
275 /* Prepare a header mark string */
276 sprintf(header_mark_str, auto_dump_header, auto_dump_mark);
278 /* Remove old macro dumps */
279 remove_auto_dump(buf);
281 /* Append to the file */
282 auto_dump_stream = my_fopen(buf, "a");
285 if (!auto_dump_stream) {
286 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
294 fprintf(auto_dump_stream, "%s\n", header_mark_str);
296 /* Initialize counter */
297 auto_dump_line_num = 0;
299 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
300 "# *Warning!* The lines below are an automatic dump.\n"));
301 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
302 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
308 * @brief prfファイルをファイルクローズする /
309 * Append foot part and close auto dump.
312 static void close_auto_dump(void)
314 char footer_mark_str[80];
316 /* Prepare a footer mark string */
317 sprintf(footer_mark_str, auto_dump_footer, auto_dump_mark);
319 auto_dump_printf(_("# *警告!!* 以降の行は自動生成されたものです。\n",
320 "# *Warning!* The lines below are an automatic dump.\n"));
321 auto_dump_printf(_("# *警告!!* 後で自動的に削除されるので編集しないでください。\n",
322 "# Don't edit them; changes will be deleted and replaced automatically.\n"));
324 fprintf(auto_dump_stream, "%s (%d)\n", footer_mark_str, auto_dump_line_num);
327 my_fclose(auto_dump_stream);
336 * @brief Return suffix of ordinal number
338 * @return pointer of suffix string.
340 cptr get_ordinal_number_suffix(int num)
342 num = ABS(num) % 100;
346 return (num == 11) ? "th" : "st";
348 return (num == 12) ? "th" : "nd";
350 return (num == 13) ? "th" : "rd";
359 * @brief 日記にメッセージを追加する /
360 * Take note to the diary.
361 * @param type 日記内容のID
362 * @param num 日記内容のIDに応じた数値
363 * @param note 日記内容のIDに応じた文字列参照ポインタ
366 errr do_cmd_write_nikki(int type, int num, cptr note)
370 GAME_TEXT file_name[MAX_NLEN];
372 cptr note_level = "";
373 bool do_level = TRUE;
374 char note_level_buf[40];
377 static bool disable_nikki = FALSE;
379 extract_day_hour_min(&day, &hour, &min);
381 if (disable_nikki) return(-1);
383 if (type == NIKKI_FIX_QUEST_C ||
384 type == NIKKI_FIX_QUEST_F ||
385 type == NIKKI_RAND_QUEST_C ||
386 type == NIKKI_RAND_QUEST_F ||
387 type == NIKKI_TO_QUEST)
391 old_quest = p_ptr->inside_quest;
392 p_ptr->inside_quest = (quest[num].type == QUEST_TYPE_RANDOM) ? 0 : num;
394 /* Get the quest text */
395 init_flags = INIT_NAME_ONLY;
397 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
399 /* Reset the old quest number */
400 p_ptr->inside_quest = old_quest;
403 /* different filne name to avoid mixing */
404 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
406 /* Build the filename */
407 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
409 /* File type is "TEXT" */
410 FILE_TYPE(FILE_TYPE_TEXT);
412 fff = my_fopen(buf, "a");
417 msg_format(_("%s を開くことができませんでした。プレイ記録を一時停止します。", "Failed to open %s. Play-Record is disabled temporally."), buf);
423 q_idx = quest_number(dun_level);
427 if (p_ptr->inside_arena)
428 note_level = _("アリーナ:", "Arane:");
430 note_level = _("地上:", "Surface:");
431 else if (q_idx && (is_fixed_quest_idx(q_idx)
432 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
433 note_level = _("クエスト:", "Quest:");
437 sprintf(note_level_buf, "%d階(%s):", (int)dun_level, d_name+d_info[dungeon_type].name);
439 sprintf(note_level_buf, "%s L%d:", d_name+d_info[dungeon_type].name, (int)dun_level);
441 note_level = note_level_buf;
449 if (day < MAX_DAYS) fprintf(fff, _("%d日目\n", "Day %d\n"), day);
450 else fputs(_("*****日目\n", "Day *****\n"), fff);
458 fprintf(fff, "%s\n",note);
462 fprintf(fff, " %2d:%02d %20s %s\n",hour, min, note_level, note);
467 fprintf(fff, _(" %2d:%02d %20s %sを発見した。\n", " %2d:%02d %20s discovered %s.\n"), hour, min, note_level, note);
470 case NIKKI_ART_SCROLL:
472 fprintf(fff, _(" %2d:%02d %20s 巻物によって%sを生成した。\n", " %2d:%02d %20s created %s by scroll.\n"), hour, min, note_level, note);
477 fprintf(fff, _(" %2d:%02d %20s %sを倒した。\n", " %2d:%02d %20s defeated %s.\n"), hour, min, note_level, note);
480 case NIKKI_FIX_QUEST_C:
482 if (quest[num].flags & QUEST_FLAG_SILENT) break;
483 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」を達成した。\n",
484 " %2d:%02d %20s completed quest '%s'.\n"), hour, min, note_level, quest[num].name);
487 case NIKKI_FIX_QUEST_F:
489 if (quest[num].flags & QUEST_FLAG_SILENT) break;
490 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」から命からがら逃げ帰った。\n",
491 " %2d:%02d %20s run away from quest '%s'.\n"), hour, min, note_level, quest[num].name);
494 case NIKKI_RAND_QUEST_C:
496 GAME_TEXT name[MAX_NLEN];
497 strcpy(name, r_name+r_info[quest[num].r_idx].name);
498 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)を達成した。\n",
499 " %2d:%02d %20s completed random quest '%s'\n"), hour, min, note_level, name);
502 case NIKKI_RAND_QUEST_F:
504 GAME_TEXT name[MAX_NLEN];
505 strcpy(name, r_name+r_info[quest[num].r_idx].name);
506 fprintf(fff, _(" %2d:%02d %20s ランダムクエスト(%s)から逃げ出した。\n",
507 " %2d:%02d %20s ran away from quest '%s'.\n"), hour, min, note_level, name);
510 case NIKKI_MAXDEAPTH:
512 fprintf(fff, _(" %2d:%02d %20s %sの最深階%d階に到達した。\n",
513 " %2d:%02d %20s reached level %d of %s for the first time.\n"), hour, min, note_level,
514 _(d_name+d_info[dungeon_type].name, num),
515 _(num, d_name+d_info[dungeon_type].name));
520 fprintf(fff, _(" %2d:%02d %20s %s%sの最深階を%d階にセットした。\n",
521 " %2d:%02d %20s reset recall level of %s to %d %s.\n"), hour, min, note_level, note,
522 _(d_name + d_info[num].name, (int)max_dlv[num]),
523 _((int)max_dlv[num], d_name + d_info[num].name));
529 if (q_idx && (is_fixed_quest_idx(q_idx)
530 && !((q_idx == QUEST_OBERON) || (q_idx == QUEST_SERPENT))))
532 to = _("地上", "the surface");
536 if (!(dun_level+num)) to = _("地上", "the surface");
537 else to = format(_("%d階", "level %d"), dun_level+num);
539 fprintf(fff, _(" %2d:%02d %20s %sへ%s。\n", " %2d:%02d %20s %s %s.\n"), hour, min, note_level, _(to, note), _(note, to));
545 fprintf(fff, _(" %2d:%02d %20s 帰還を使って%sの%d階へ下りた。\n", " %2d:%02d %20s recalled to dungeon level %d of %s.\n"),
546 hour, min, note_level, _(d_name+d_info[dungeon_type].name, (int)max_dlv[dungeon_type]),
547 _((int)max_dlv[dungeon_type], d_name+d_info[dungeon_type].name));
549 fprintf(fff, _(" %2d:%02d %20s 帰還を使って地上へと戻った。\n", " %2d:%02d %20s recalled from dungeon to surface.\n"), hour, min, note_level);
554 if (quest[num].flags & QUEST_FLAG_SILENT) break;
555 fprintf(fff, _(" %2d:%02d %20s クエスト「%s」へと突入した。\n", " %2d:%02d %20s entered the quest '%s'.\n"),
556 hour, min, note_level, quest[num].name);
561 fprintf(fff, _(" %2d:%02d %20s レベル・テレポートで脱出した。\n", " %2d:%02d %20s Got out using teleport level.\n"),
562 hour, min, note_level);
567 fprintf(fff, _(" %2d:%02d %20s %sを購入した。\n", " %2d:%02d %20s bought %s.\n"), hour, min, note_level, note);
572 fprintf(fff, _(" %2d:%02d %20s %sを売却した。\n", " %2d:%02d %20s sold %s.\n"), hour, min, note_level, note);
580 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦で、%sの前に敗れ去った。\n", " %2d:%02d %20s beaten by %s in the %d%s fight.\n"),
581 hour, min, note_level, _(n, note), _("", n), _(note, get_ordinal_number_suffix(n)));
584 fprintf(fff, _(" %2d:%02d %20s 闘技場の%d%s回戦(%s)に勝利した。\n", " %2d:%02d %20s won the %d%s fight (%s).\n"),
585 hour, min, note_level, num, _("", get_ordinal_number_suffix(num)), note);
587 if (num == MAX_ARENA_MONS)
589 fprintf(fff, _(" 闘技場のすべての敵に勝利し、チャンピオンとなった。\n",
590 " won all fight to become a Chanpion.\n"));
597 fprintf(fff, _(" %2d:%02d %20s %sを識別した。\n", " %2d:%02d %20s identified %s.\n"), hour, min, note_level, note);
604 to = _("地上", "the surface");
606 to = format(_("%d階(%s)", "level %d of %s"), dun_level, d_name+d_info[dungeon_type].name);
608 fprintf(fff, _(" %2d:%02d %20s %sへとウィザード・テレポートで移動した。\n",
609 " %2d:%02d %20s wizard-teleport to %s.\n"), hour, min, note_level, to);
616 to = _("地上", "the surface");
618 to = format(_("%d階(%s)", "level %d of %s"), dun_level, d_name+d_info[dungeon_type].name);
620 fprintf(fff, _(" %2d:%02d %20s %sへとパターンの力で移動した。\n",
621 " %2d:%02d %20s used Pattern to teleport to %s.\n"), hour, min, note_level, to);
626 fprintf(fff, _(" %2d:%02d %20s レベルが%dに上がった。\n", " %2d:%02d %20s reached player level %d.\n"), hour, min, note_level, num);
629 case NIKKI_GAMESTART:
631 time_t ct = time((time_t*)0);
635 fprintf(fff, "%s %s",note, ctime(&ct));
638 fprintf(fff, " %2d:%02d %20s %s %s",hour, min, note_level, note, ctime(&ct));
641 case NIKKI_NAMED_PET:
643 fprintf(fff, " %2d:%02d %20s ", hour, min, note_level);
646 case RECORD_NAMED_PET_NAME:
647 fprintf(fff, _("%sを旅の友にすることに決めた。\n", "decided to travel together with %s.\n"), note);
649 case RECORD_NAMED_PET_UNNAME:
650 fprintf(fff, _("%sの名前を消した。\n", "unnamed %s.\n"), note);
652 case RECORD_NAMED_PET_DISMISS:
653 fprintf(fff, _("%sを解放した。\n", "dismissed %s.\n"), note);
655 case RECORD_NAMED_PET_DEATH:
656 fprintf(fff, _("%sが死んでしまった。\n", "%s died.\n"), note);
658 case RECORD_NAMED_PET_MOVED:
659 fprintf(fff, _("%sをおいて別のマップへ移動した。\n", "moved to another map leaving %s behind.\n"), note);
661 case RECORD_NAMED_PET_LOST_SIGHT:
662 fprintf(fff, _("%sとはぐれてしまった。\n", "lost sight of %s.\n"), note);
664 case RECORD_NAMED_PET_DESTROY:
665 fprintf(fff, _("%sが*破壊*によって消え去った。\n", "%s was made disappeared by *destruction*.\n"), note);
667 case RECORD_NAMED_PET_EARTHQUAKE:
668 fprintf(fff, _("%sが岩石に押し潰された。\n", "%s was crushed by falling rocks.\n"), note);
670 case RECORD_NAMED_PET_GENOCIDE:
671 fprintf(fff, _("%sが抹殺によって消え去った。\n", "%s was made disappeared by genocide.\n"), note);
673 case RECORD_NAMED_PET_WIZ_ZAP:
674 fprintf(fff, _("%sがデバッグコマンドによって消え去った。\n", "%s was removed by debug command.\n"), note);
676 case RECORD_NAMED_PET_TELE_LEVEL:
677 fprintf(fff, _("%sがテレポート・レベルによって消え去った。\n", "%s was made disappeared by teleport level.\n"), note);
679 case RECORD_NAMED_PET_BLAST:
680 fprintf(fff, _("%sを爆破した。\n", "blasted %s.\n"), note);
682 case RECORD_NAMED_PET_HEAL_LEPER:
683 fprintf(fff, _("%sの病気が治り旅から外れた。\n", "%s was healed and left.\n"), note);
685 case RECORD_NAMED_PET_COMPACT:
686 fprintf(fff, _("%sがモンスター情報圧縮によって消え去った。\n", "%s was made disappeared by compacting monsters.\n"), note);
688 case RECORD_NAMED_PET_LOSE_PARENT:
689 fprintf(fff, _("%sの召喚者が既にいないため消え去った。\n", "%s disappeared because there does not exist summoner.\n"), note);
700 case NIKKI_WIZARD_LOG:
701 fprintf(fff, "%s\n", note);
710 if (do_level) write_level = FALSE;
716 #define MAX_SUBTITLE (sizeof(subtitle)/sizeof(subtitle[0]))
719 * @brief 日記のタイトル表記と内容出力 /
722 * 日記のタイトルは本関数の subtitle ローカル変数で定義されている。
724 static void do_cmd_disp_nikki(void)
726 char nikki_title[256];
727 GAME_TEXT file_name[MAX_NLEN];
732 static const char subtitle[][30] = {"最強の肉体を求めて",
763 static const char subtitle[][51] ={"Quest of The World's Toughest Body",
764 "Attack is the best form of defence.",
766 "An unexpected windfall",
767 "A drowning man will catch at a straw",
768 "Don't count your chickens before they are hatched.",
769 "It is no use crying over spilt milk.",
770 "Seeing is believing.",
771 "Strike the iron while it is hot.",
772 "I don't care what follows.",
773 "To dig a well to put out a house on fire.",
774 "Tomorrow is another day.",
775 "Easy come, easy go.",
776 "The more haste, the less speed.",
777 "Where there is life, there is hope.",
778 "There is no royal road to *WINNER*.",
779 "Danger past, God forgotten.",
780 "The best thing to do now is to run away.",
781 "Life is but an empty dream.",
782 "Dead men tell no tales.",
783 "A book that remains shut is but a block.",
784 "Misfortunes never come singly.",
785 "A little knowledge is a dangerous thing.",
786 "History repeats itself.",
787 "*WINNER* was not built in a day.",
788 "Ignorance is bliss.",
789 "To lose is to win?",
790 "No medicine can cure folly.",
791 "All good things come to an end.",
792 "M$ Empire strikes back.",
793 "To see is to believe",
795 "Quest of The World's Greatest Brain"};
797 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
799 /* Build the filename */
800 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
802 if (p_ptr->pclass == CLASS_WARRIOR || p_ptr->pclass == CLASS_MONK || p_ptr->pclass == CLASS_SAMURAI || p_ptr->pclass == CLASS_BERSERKER)
803 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)]);
804 else if (IS_WIZARD_CLASS())
805 strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-1)+1]);
806 else strcpy(tmp,subtitle[randint0(MAX_SUBTITLE-2)+1]);
809 sprintf(nikki_title, "「%s%s%sの伝説 -%s-」",
810 ap_ptr->title, ap_ptr->no ? "の" : "", p_ptr->name, tmp);
812 sprintf(nikki_title, "Legend of %s %s '%s'",
813 ap_ptr->title, p_ptr->name, tmp);
816 /* Display the file contents */
817 show_file(FALSE, buf, nikki_title, -1, 0);
821 * @brief 日記に任意の内容を表記するコマンドのメインルーチン /
824 static void do_cmd_bunshou(void)
827 char bunshou[80] = "\0";
829 if (get_string(_("内容: ", "diary note: "), tmp, 79))
831 strcpy(bunshou, tmp);
833 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, bunshou);
838 * @brief 最後に取得したアイテムの情報を日記に追加するメインルーチン /
841 static void do_cmd_last_get(void)
846 if (record_o_name[0] == '\0') return;
848 sprintf(buf,_("%sの入手を記録します。", "Do you really want to record getting %s? "),record_o_name);
849 if (!get_check(buf)) return;
853 sprintf(buf,_("%sを手に入れた。", "descover %s."), record_o_name);
854 do_cmd_write_nikki(NIKKI_BUNSHOU, 0, buf);
859 * @brief ファイル中の全日記記録を消去する /
862 static void do_cmd_erase_nikki(void)
864 GAME_TEXT file_name[MAX_NLEN];
868 if (!get_check(_("本当に記録を消去しますか?", "Do you really want to delete all your record? "))) return;
869 sprintf(file_name,_("playrecord-%s.txt", "playrec-%s.txt"),savefile_base);
871 /* Build the filename */
872 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, file_name);
874 /* Remove the file */
877 fff = my_fopen(buf, "w");
880 msg_format(_("記録を消去しました。", "deleted record."));
882 msg_format(_("%s の消去に失敗しました。", "failed to delete %s."), buf);
891 void do_cmd_nikki(void)
895 /* File type is "TEXT" */
896 FILE_TYPE(FILE_TYPE_TEXT);
899 /* Interact until done */
904 /* Ask for a choice */
905 prt(_("[ 記録の設定 ]", "[ Play Record ]"), 2, 0);
907 /* Give some choices */
908 prt(_("(1) 記録を見る", "(1) Display your record"), 4, 5);
909 prt(_("(2) 文章を記録する", "(2) Add record"), 5, 5);
910 prt(_("(3) 直前に入手又は鑑定したものを記録する", "(3) Record item you last get/identify"), 6, 5);
911 prt(_("(4) 記録を消去する", "(4) Delete your record"), 7, 5);
913 prt(_("(R) プレイ動画を記録する/中止する", "(R) Record playing movie / or stop it"), 9, 5);
916 prt(_("コマンド:", "Command: "), 18, 0);
921 if (i == ESCAPE) break;
935 do_cmd_erase_nikki();
939 prepare_movie_hooks();
941 default: /* Unknown option */
951 * @brief 画面を再描画するコマンドのメインルーチン
952 * Hack -- redraw the screen
956 * This command performs various low level updates, clears all the "extra"
957 * windows, does a total redraw of the main window, and requests all of the
958 * interesting updates and redraws that I can think of.
960 * This command is also used to "instantiate" the results of the user
961 * selecting various things, such as graphics mode, so it must call
962 * the "TERM_XTRA_REACT" hook before redrawing the windows.
965 void do_cmd_redraw(void)
971 /* Hack -- react to changes */
972 Term_xtra(TERM_XTRA_REACT, 0);
974 /* Combine and Reorder the pack (later) */
975 p_ptr->update |= (PU_COMBINE | PU_REORDER);
976 p_ptr->update |= (PU_TORCH);
977 p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
978 p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE);
979 p_ptr->update |= (PU_VIEW | PU_LITE | PU_MON_LITE);
980 p_ptr->update |= (PU_MONSTERS);
982 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
984 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL | PW_PLAYER);
985 p_ptr->window |= (PW_MESSAGE | PW_OVERHEAD | PW_DUNGEON | PW_MONSTER | PW_OBJECT);
991 if (p_ptr->prace == RACE_ANDROID) calc_android_exp();
994 /* Redraw every window */
995 for (j = 0; j < 8; j++)
998 if (!angband_term[j]) continue;
1001 Term_activate(angband_term[j]);
1010 * @brief 名前を変更するコマンドのメインルーチン
1011 * Hack -- change name
1014 void do_cmd_change_name(void)
1029 /* Display the player */
1030 display_player(mode);
1035 display_player(mode);
1040 Term_putstr(2, 23, -1, TERM_WHITE,
1041 "['c'で名前変更, 'f'でファイルへ書出, 'h'でモード変更, ESCで終了]");
1043 Term_putstr(2, 23, -1, TERM_WHITE,
1044 "['c' to change name, 'f' to file, 'h' to change mode, or ESC]");
1052 if (c == ESCAPE) break;
1059 /* Process the player name */
1060 process_player_name(FALSE);
1066 sprintf(tmp, "%s.txt", player_base);
1067 if (get_string(_("ファイル名: ", "File name: "), tmp, 80))
1069 if (tmp[0] && (tmp[0] != ' '))
1071 file_character(tmp);
1089 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
1096 * @brief 最近表示されたメッセージを再表示するコマンドのメインルーチン
1097 * Recall the most recent message
1100 void do_cmd_message_one(void)
1102 /* Recall one message */
1103 prt(format("> %s", message_str(0)), 0, 0);
1108 * @brief メッセージのログを表示するコマンドのメインルーチン
1109 * Recall the most recent message
1113 * Show previous messages to the user -BEN-
1115 * The screen format uses line 0 and 23 for headers and prompts,
1116 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
1118 * This command shows you which commands you are viewing, and allows
1119 * you to "search" for strings in the recall.
1121 * Note that messages may be longer than 80 characters, but they are
1122 * displayed using "infinite" length, with a special sub-command to
1123 * "slide" the virtual display to the left or right.
1125 * Attempt to only hilite the matching portions of the string.
1128 void do_cmd_messages(int num_now)
1132 char shower_str[81];
1133 char finder_str[81];
1139 Term_get_size(&wid, &hgt);
1141 /* Number of message lines in a screen */
1142 num_lines = hgt - 4;
1145 strcpy(finder_str, "");
1148 strcpy(shower_str, "");
1150 /* Total messages */
1153 /* Start on first message */
1158 /* Process requests until done */
1164 /* Dump up to 20 lines of messages */
1165 for (j = 0; (j < num_lines) && (i + j < n); j++)
1167 cptr msg = message_str(i+j);
1169 /* Dump the messages, bottom to top */
1170 c_prt((i + j < num_now ? TERM_WHITE : TERM_SLATE), msg, num_lines + 1 - j, 0);
1172 /* Hilite "shower" */
1173 if (shower && shower[0])
1177 /* Display matches */
1178 while ((str = my_strstr(str, shower)) != NULL)
1180 int len = strlen(shower);
1182 /* Display the match */
1183 Term_putstr(str-msg, num_lines + 1 - j, len, TERM_YELLOW, shower);
1191 /* Erase remaining lines */
1192 for (; j < num_lines; j++)
1194 Term_erase(0, num_lines + 1 - j, 255);
1197 /* Display header */
1199 prt(format(_("以前のメッセージ %d-%d 全部で(%d)", "Message Recall (%d-%d of %d)"),
1200 i, i + j - 1, n), 0, 0);
1202 /* Display prompt (not very informative) */
1203 prt(_("[ 'p' で更に古いもの, 'n' で更に新しいもの, '/' で検索, ESC で中断 ]",
1204 "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]"), hgt - 1, 0);
1206 skey = inkey_special(TRUE);
1208 /* Exit on Escape */
1209 if (skey == ESCAPE) break;
1211 /* Hack -- Save the old index */
1216 /* Hack -- handle show */
1219 prt(_("強調: ", "Show: "), hgt - 1, 0);
1221 /* Get a "shower" string, or continue */
1222 strcpy(back_str, shower_str);
1223 if (askfor(shower_str, 80))
1226 shower = shower_str[0] ? shower_str : NULL;
1228 else strcpy(shower_str, back_str);
1232 /* Hack -- handle find */
1239 prt(_("検索: ", "Find: "), hgt - 1, 0);
1241 /* Get a "finder" string, or continue */
1242 strcpy(back_str, finder_str);
1243 if (!askfor(finder_str, 80))
1245 strcpy(finder_str, back_str);
1248 else if (!finder_str[0])
1250 shower = NULL; /* Stop showing */
1255 shower = finder_str;
1258 for (z = i + 1; z < n; z++)
1260 cptr msg = message_str(z);
1263 if (my_strstr(msg, finder_str))
1274 /* Recall 1 older message */
1276 /* Go to the oldest line */
1280 /* Recall 1 newer message */
1282 /* Go to the newest line */
1286 /* Recall 1 older message */
1291 /* Go older if legal */
1292 i = MIN(i + 1, n - num_lines);
1295 /* Recall 10 older messages */
1297 /* Go older if legal */
1298 i = MIN(i + 10, n - num_lines);
1301 /* Recall 20 older messages */
1306 /* Go older if legal */
1307 i = MIN(i + num_lines, n - num_lines);
1310 /* Recall 20 newer messages */
1314 /* Go newer (if able) */
1315 i = MAX(0, i - num_lines);
1318 /* Recall 10 newer messages */
1320 /* Go newer (if able) */
1324 /* Recall 1 newer messages */
1327 /* Go newer (if able) */
1332 /* Hack -- Error of some kind */
1340 * @brief チートオプションを変更するコマンドのメインルーチン
1341 * Interact with some options for cheating
1342 * @param info 表示メッセージ
1345 static void do_cmd_options_cheat(cptr info)
1348 int i, k = 0, n = CHEAT_MAX;
1352 /* Interact with the player */
1358 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, ESC で決定 )", "%s (RET to advance, y/n to set, ESC to accept) "), info);
1363 /* 詐欺オプションをうっかりいじってしまう人がいるようなので注意 */
1364 prt(" << 注意 >>", 11, 0);
1365 prt(" 詐欺オプションを一度でも設定すると、スコア記録が残らなくなります!", 12, 0);
1366 prt(" 後に解除してもダメですので、勝利者を目指す方はここのオプションはい", 13, 0);
1367 prt(" じらないようにして下さい。", 14, 0);
1369 /* Display the options */
1370 for (i = 0; i < n; i++)
1372 byte a = TERM_WHITE;
1374 /* Color current option */
1375 if (i == k) a = TERM_L_BLUE;
1377 /* Display the option text */
1378 sprintf(buf, "%-48s: %s (%s)",
1379 cheat_info[i].o_desc,
1380 (*cheat_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1381 cheat_info[i].o_text);
1382 c_prt(a, buf, i + 2, 0);
1385 /* Hilite current option */
1386 move_cursor(k + 2, 50);
1392 * HACK - Try to translate the key into a direction
1393 * to allow using the roguelike keys for navigation.
1395 dir = get_keymap_dir(ch);
1396 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1410 k = (n + k - 1) % n;
1428 do_cmd_write_nikki(NIKKI_BUNSHOU, 0,
1429 _("詐欺オプションをONにして、スコアを残せなくなった。", "give up sending score to use cheating options."));
1430 p_ptr->noscore |= (cheat_info[k].o_set * 256 + cheat_info[k].o_bit);
1431 (*cheat_info[k].o_var) = TRUE;
1440 (*cheat_info[k].o_var) = FALSE;
1447 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), cheat_info[k].o_text);
1448 /* Peruse the help file */
1449 (void)show_file(TRUE, buf, NULL, 0, 0);
1466 * @brief セーブ頻度ターンの次の値を返す
1467 * @param current 現在のセーブ頻度ターン値
1468 * @return 次のセーブ頻度ターン値
1470 static s16b toggle_frequency(s16b current)
1475 case 50: return 100;
1476 case 100: return 250;
1477 case 250: return 500;
1478 case 500: return 1000;
1479 case 1000: return 2500;
1480 case 2500: return 5000;
1481 case 5000: return 10000;
1482 case 10000: return 25000;
1489 * @brief 自動セーブオプションを変更するコマンドのメインルーチン
1490 * @param info 表示メッセージ
1493 static void do_cmd_options_autosave(cptr info)
1496 int i, k = 0, n = 2;
1501 /* Interact with the player */
1505 sprintf(buf, _("%s ( リターンで次へ, y/n でセット, F で頻度を入力, ESC で決定 ) ",
1506 "%s (RET to advance, y/n to set, 'F' for frequency, ESC to accept) "), info);
1510 /* Display the options */
1511 for (i = 0; i < n; i++)
1513 byte a = TERM_WHITE;
1515 /* Color current option */
1516 if (i == k) a = TERM_L_BLUE;
1518 /* Display the option text */
1519 sprintf(buf, "%-48s: %s (%s)",
1520 autosave_info[i].o_desc,
1521 (*autosave_info[i].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1522 autosave_info[i].o_text);
1523 c_prt(a, buf, i + 2, 0);
1525 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1527 /* Hilite current option */
1528 move_cursor(k + 2, 50);
1544 k = (n + k - 1) % n;
1562 (*autosave_info[k].o_var) = TRUE;
1571 (*autosave_info[k].o_var) = FALSE;
1579 autosave_freq = toggle_frequency(autosave_freq);
1580 prt(format(_("自動セーブの頻度: %d ターン毎", "Timed autosave frequency: every %d turns"), autosave_freq), 5, 0);
1586 (void)show_file(TRUE, _("joption.txt#Autosave", "option.txt#Autosave"), NULL, 0, 0);
1602 * @brief 標準オプションを変更するコマンドのサブルーチン /
1603 * Interact with some options
1604 * @param page オプションページ番号
1605 * @param info 表示メッセージ
1608 void do_cmd_options_aux(int page, cptr info)
1611 int i, k = 0, n = 0, l;
1614 bool browse_only = (page == OPT_PAGE_BIRTH) && character_generated &&
1615 (!p_ptr->wizard || !allow_debug_opts);
1618 /* Lookup the options */
1619 for (i = 0; i < 24; i++) opt[i] = 0;
1621 /* Scan the options */
1622 for (i = 0; option_info[i].o_desc; i++)
1624 /* Notice options on this "page" */
1625 if (option_info[i].o_page == page) opt[n++] = i;
1629 /* Interact with the player */
1635 sprintf(buf, _("%s (リターン:次, %sESC:終了, ?:ヘルプ) ", "%s (RET:next, %s, ?:help) "),
1636 info, browse_only ? _("", "ESC:exit") : _("y/n:変更, ", "y/n:change, ESC:accept"));
1639 /* HACK -- description for easy-auto-destroy options */
1640 if (page == OPT_PAGE_AUTODESTROY)
1641 c_prt(TERM_YELLOW, _("以下のオプションは、簡易自動破壊を使用するときのみ有効",
1642 "Following options will protect items from easy auto-destroyer."), 6, _(6, 3));
1644 /* Display the options */
1645 for (i = 0; i < n; i++)
1647 byte a = TERM_WHITE;
1649 /* Color current option */
1650 if (i == k) a = TERM_L_BLUE;
1652 /* Display the option text */
1653 sprintf(buf, "%-48s: %s (%.19s)",
1654 option_info[opt[i]].o_desc,
1655 (*option_info[opt[i]].o_var ? _("はい ", "yes") : _("いいえ", "no ")),
1656 option_info[opt[i]].o_text);
1657 if ((page == OPT_PAGE_AUTODESTROY) && i > 2) c_prt(a, buf, i + 5, 0);
1658 else c_prt(a, buf, i + 2, 0);
1661 if ((page == OPT_PAGE_AUTODESTROY) && (k > 2)) l = 3;
1664 /* Hilite current option */
1665 move_cursor(k + 2 + l, 50);
1671 * HACK - Try to translate the key into a direction
1672 * to allow using the roguelike keys for navigation.
1674 dir = get_keymap_dir(ch);
1675 if ((dir == 2) || (dir == 4) || (dir == 6) || (dir == 8))
1689 k = (n + k - 1) % n;
1706 if (browse_only) break;
1707 (*option_info[opt[k]].o_var) = TRUE;
1716 if (browse_only) break;
1717 (*option_info[opt[k]].o_var) = FALSE;
1725 if (!browse_only) (*option_info[opt[k]].o_var) = !(*option_info[opt[k]].o_var);
1731 strnfmt(buf, sizeof(buf), _("joption.txt#%s", "option.txt#%s"), option_info[opt[k]].o_text);
1732 /* Peruse the help file */
1733 (void)show_file(TRUE, buf, NULL, 0, 0);
1750 * @brief ウィンドウオプションを変更するコマンドのメインルーチン /
1751 * Modify the "window" options
1754 static void do_cmd_options_win(void)
1764 /* Memorize old flags */
1765 for (j = 0; j < 8; j++)
1767 /* Acquire current flags */
1768 old_flag[j] = window_flag[j];
1777 prt(_("ウィンドウ・フラグ (<方向>で移動, tでチェンジ, y/n でセット, ESC)", "Window Flags (<dir>, t, y, n, ESC) "), 0, 0);
1779 /* Display the windows */
1780 for (j = 0; j < 8; j++)
1782 byte a = TERM_WHITE;
1784 cptr s = angband_term_name[j];
1787 if (j == x) a = TERM_L_BLUE;
1789 /* Window name, staggered, centered */
1790 Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
1793 /* Display the options */
1794 for (i = 0; i < 16; i++)
1796 byte a = TERM_WHITE;
1798 cptr str = window_flag_desc[i];
1801 if (i == y) a = TERM_L_BLUE;
1804 if (!str) str = _("(未使用)", "(Unused option)");
1807 Term_putstr(0, i + 5, -1, a, str);
1809 /* Display the windows */
1810 for (j = 0; j < 8; j++)
1816 if ((i == y) && (j == x)) a = TERM_L_BLUE;
1819 if (window_flag[j] & (1L << i)) c = 'X';
1822 Term_putch(35 + j * 5, i + 5, a, c);
1827 Term_gotoxy(35 + x * 5, y + 5);
1845 for (j = 0; j < 8; j++)
1847 window_flag[j] &= ~(1L << y);
1851 for (i = 0; i < 16; i++)
1853 window_flag[x] &= ~(1L << i);
1866 window_flag[x] |= (1L << y);
1874 window_flag[x] &= ~(1L << y);
1880 (void)show_file(TRUE, _("joption.txt#Window", "option.txt#Window"), NULL, 0, 0);
1888 d = get_keymap_dir(ch);
1890 x = (x + ddx[d] + 8) % 8;
1891 y = (y + ddy[d] + 16) % 16;
1898 /* Notice changes */
1899 for (j = 0; j < 8; j++)
1904 if (!angband_term[j]) continue;
1906 /* Ignore non-changes */
1907 if (window_flag[j] == old_flag[j]) continue;
1910 Term_activate(angband_term[j]);
1927 option_fields[OPT_NUM] =
1930 { '1', " キー入力 オプション", 3 },
1931 { '2', " マップ画面 オプション", 4 },
1932 { '3', " テキスト表示 オプション", 5 },
1933 { '4', " ゲームプレイ オプション", 6 },
1934 { '5', " 行動中止関係 オプション", 7 },
1935 { '6', " 簡易自動破壊 オプション", 8 },
1936 { 'r', " プレイ記録 オプション", 9 },
1938 { 'p', "自動拾いエディタ", 11 },
1939 { 'd', " 基本ウェイト量 ", 12 },
1940 { 'h', "低ヒットポイント", 13 },
1941 { 'm', " 低魔力色閾値 ", 14 },
1942 { 'a', " 自動セーブ オプション", 15 },
1943 { 'w', "ウインドウフラグ", 16 },
1945 { 'b', " 初期 オプション (参照のみ)", 18 },
1946 { 'c', " 詐欺 オプション", 19 },
1948 { '1', "Input Options", 3 },
1949 { '2', "Map Screen Options", 4 },
1950 { '3', "Text Display Options", 5 },
1951 { '4', "Game-Play Options", 6 },
1952 { '5', "Disturbance Options", 7 },
1953 { '6', "Easy Auto-Destroyer Options", 8 },
1954 { 'r', "Play record Options", 9 },
1956 { 'p', "Auto-picker/destroyer editor", 11 },
1957 { 'd', "Base Delay Factor", 12 },
1958 { 'h', "Hitpoint Warning", 13 },
1959 { 'm', "Mana Color Threshold", 14 },
1960 { 'a', "Autosave Options", 15 },
1961 { 'w', "Window Flags", 16 },
1963 { 'b', "Birth Options (Browse Only)", 18 },
1964 { 'c', "Cheat Options", 19 },
1970 * @brief 標準オプションを変更するコマンドのメインルーチン /
1971 * Set or unset various options.
1975 * The user must use the "Ctrl-R" command to "adapt" to changes
1976 * in any options which control "visual" aspects of the game.
1979 void do_cmd_options(void)
1991 /* Does not list cheat option when cheat option is off */
1992 if (!p_ptr->noscore && !allow_debug_opts) n--;
1995 /* Why are we here */
1996 prt(_("[ オプションの設定 ]", "TinyAngband options"), 1, 0);
2000 /* Give some choices */
2001 for (i = 0; i < n; i++)
2003 byte a = TERM_WHITE;
2004 if (i == y) a = TERM_L_BLUE;
2005 Term_putstr(5, option_fields[i].row, -1, a,
2006 format("(%c) %s", toupper(option_fields[i].key), option_fields[i].name));
2009 prt(_("<方向>で移動, Enterで決定, ESCでキャンセル, ?でヘルプ: ", "Move to <dir>, Select to Enter, Cancel to ESC, ? to help: "), 21, 0);
2012 skey = inkey_special(TRUE);
2013 if (!(skey & SKEY_MASK)) k = (char)skey;
2017 if (k == ESCAPE) break;
2019 if (my_strchr("\n\r ", k))
2021 k = option_fields[y].key;
2025 for (i = 0; i < n; i++)
2027 if (tolower(k) == option_fields[i].key) break;
2030 /* Command is found */
2033 /* Hack -- browse help */
2034 if (k == '?') break;
2038 if (skey == SKEY_UP) d = 8;
2039 if (skey == SKEY_DOWN) d = 2;
2040 y = (y + ddy[d] + n) % n;
2045 if (k == ESCAPE) break;
2052 /* Process the general options */
2053 do_cmd_options_aux(OPT_PAGE_INPUT, _("キー入力オプション", "Input Options"));
2059 /* Process the general options */
2060 do_cmd_options_aux(OPT_PAGE_MAPSCREEN, _("マップ画面オプション", "Map Screen Options"));
2067 do_cmd_options_aux(OPT_PAGE_TEXT, _("テキスト表示オプション", "Text Display Options"));
2074 do_cmd_options_aux(OPT_PAGE_GAMEPLAY, _("ゲームプレイ・オプション", "Game-Play Options"));
2081 do_cmd_options_aux(OPT_PAGE_DISTURBANCE, _("行動中止関係のオプション", "Disturbance Options"));
2088 do_cmd_options_aux(OPT_PAGE_AUTODESTROY, _("簡易自動破壊オプション", "Easy Auto-Destroyer Options"));
2092 /* Play-record Options */
2097 do_cmd_options_aux(OPT_PAGE_PLAYRECORD, _("プレイ記録オプション", "Play-record Options"));
2106 do_cmd_options_aux(OPT_PAGE_BIRTH, (!p_ptr->wizard || !allow_debug_opts) ?
2107 _("初期オプション(参照のみ)", "Birth Options(browse only)") :
2108 _("初期オプション((*)はスコアに影響)", "Birth Options((*)s effect score)"));
2112 /* Cheating Options */
2115 if (!p_ptr->noscore && !allow_debug_opts)
2117 /* Cheat options are not permitted */
2123 do_cmd_options_cheat(_("詐欺師は決して勝利できない!", "Cheaters never win"));
2130 do_cmd_options_autosave(_("自動セーブ", "Autosave"));
2139 do_cmd_options_win();
2140 p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_SPELL |
2141 PW_PLAYER | PW_MESSAGE | PW_OVERHEAD |
2142 PW_MONSTER | PW_OBJECT | PW_SNAPSHOT |
2143 PW_BORG_1 | PW_BORG_2 | PW_DUNGEON |
2148 /* Auto-picker/destroyer editor */
2152 do_cmd_edit_autopick();
2156 /* Hack -- Delay Speed */
2162 prt(_("コマンド: 基本ウェイト量", "Command: Base Delay Factor"), 19, 0);
2164 /* Get a new value */
2167 int msec = delay_factor * delay_factor * delay_factor;
2168 prt(format(_("現在のウェイト: %d (%dミリ秒)", "Current base delay factor: %d (%d msec)"), delay_factor, msec), 22, 0);
2169 prt(_("ウェイト (0-9) ESCで決定: ", "Delay Factor (0-9 or ESC to accept): "), 20, 0);
2171 if (k == ESCAPE) break;
2174 (void)show_file(TRUE, _("joption.txt#BaseDelay", "option.txt#BaseDelay"), NULL, 0, 0);
2177 else if (isdigit(k)) delay_factor = D2I(k);
2184 /* Hack -- hitpoint warning factor */
2190 prt(_("コマンド: 低ヒットポイント警告", "Command: Hitpoint Warning"), 19, 0);
2192 /* Get a new value */
2195 prt(format(_("現在の低ヒットポイント警告: %d0%%", "Current hitpoint warning: %d0%%"), hitpoint_warn), 22, 0);
2196 prt(_("低ヒットポイント警告 (0-9) ESCで決定: ", "Hitpoint Warning (0-9 or ESC to accept): "), 20, 0);
2198 if (k == ESCAPE) break;
2201 (void)show_file(TRUE, _("joption.txt#Hitpoint", "option.txt#Hitpoint"), NULL, 0, 0);
2204 else if (isdigit(k)) hitpoint_warn = D2I(k);
2211 /* Hack -- mana color factor */
2217 prt(_("コマンド: 低魔力色閾値", "Command: Mana Color Threshold"), 19, 0);
2219 /* Get a new value */
2222 prt(format(_("現在の低魔力色閾値: %d0%%", "Current mana color threshold: %d0%%"), mana_warn), 22, 0);
2223 prt(_("低魔力閾値 (0-9) ESCで決定: ", "Mana color Threshold (0-9 or ESC to accept): "), 20, 0);
2225 if (k == ESCAPE) break;
2228 (void)show_file(TRUE, _("joption.txt#Manapoint", "option.txt#Manapoint"), NULL, 0, 0);
2231 else if (isdigit(k)) mana_warn = D2I(k);
2239 (void)show_file(TRUE, _("joption.txt", "option.txt"), NULL, 0, 0);
2243 /* Unknown option */
2256 /* Hack - Redraw equippy chars */
2257 p_ptr->redraw |= (PR_EQUIPPY);
2263 * @brief prefファイルを選択して処理する /
2264 * Ask for a "user pref line" and process it
2267 * Allow absolute file names?
2269 void do_cmd_pref(void)
2276 /* Ask for a "user pref command" */
2277 if (!get_string(_("設定変更コマンド: ", "Pref: "), buf, 80)) return;
2279 /* Process that pref command */
2280 (void)process_pref_file_command(buf);
2284 * @brief 自動拾い設定ファイルをロードするコマンドのメインルーチン /
2287 void do_cmd_reload_autopick(void)
2289 if (!get_check(_("自動拾い設定ファイルをロードしますか? ", "Reload auto-pick preference file? "))) return;
2290 /* Load the file with messages */
2291 autopick_load_pref(TRUE);
2297 * @brief マクロ情報をprefファイルに保存する /
2298 * @param fname ファイル名
2301 static errr macro_dump(cptr fname)
2303 static cptr mark = "Macro Dump";
2309 /* Build the filename */
2310 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2312 /* File type is "TEXT" */
2313 FILE_TYPE(FILE_TYPE_TEXT);
2315 /* Append to the file */
2316 if (!open_auto_dump(buf, mark)) return (-1);
2319 auto_dump_printf(_("\n# 自動マクロセーブ\n\n", "\n# Automatic macro dump\n\n"));
2322 for (i = 0; i < macro__num; i++)
2324 /* Extract the action */
2325 ascii_to_text(buf, macro__act[i]);
2327 /* Dump the macro */
2328 auto_dump_printf("A:%s\n", buf);
2330 /* Extract the action */
2331 ascii_to_text(buf, macro__pat[i]);
2333 /* Dump normal macros */
2334 auto_dump_printf("P:%s\n", buf);
2337 auto_dump_printf("\n");
2349 * @brief マクロのトリガーキーを取得する /
2350 * Hack -- ask for a "trigger" (see below)
2351 * @param buf キー表記を保管するバッファ
2355 * Note the complex use of the "inkey()" function from "util.c".
2357 * Note that both "flush()" calls are extremely important.
2360 static void do_cmd_macro_aux(char *buf)
2368 /* Do not process macros */
2374 /* Read the pattern */
2380 /* Do not process macros */
2383 /* Do not wait for keys */
2386 /* Attempt to read a key */
2395 /* Convert the trigger */
2396 ascii_to_text(tmp, buf);
2398 /* Hack -- display the trigger */
2399 Term_addstr(-1, TERM_WHITE, tmp);
2405 * @brief マクロのキー表記からアスキーコードを得てターミナルに表示する /
2406 * Hack -- ask for a keymap "trigger" (see below)
2407 * @param buf キー表記を取得するバッファ
2411 * Note that both "flush()" calls are extremely important. This may
2412 * no longer be true, since "util.c" is much simpler now.
2415 static void do_cmd_macro_aux_keymap(char *buf)
2425 /* Convert to ascii */
2426 ascii_to_text(tmp, buf);
2428 /* Hack -- display the trigger */
2429 Term_addstr(-1, TERM_WHITE, tmp);
2436 * @brief キーマップをprefファイルにダンプする /
2437 * Hack -- append all keymaps to the given file
2438 * @param fname ファイルネーム
2442 static errr keymap_dump(cptr fname)
2444 static cptr mark = "Keymap Dump";
2453 if (rogue_like_commands)
2455 mode = KEYMAP_MODE_ROGUE;
2461 mode = KEYMAP_MODE_ORIG;
2465 /* Build the filename */
2466 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, fname);
2468 /* File type is "TEXT" */
2469 FILE_TYPE(FILE_TYPE_TEXT);
2471 /* Append to the file */
2472 if (!open_auto_dump(buf, mark)) return -1;
2475 auto_dump_printf(_("\n# 自動キー配置セーブ\n\n", "\n# Automatic keymap dump\n\n"));
2478 for (i = 0; i < 256; i++)
2482 /* Loop up the keymap */
2483 act = keymap_act[mode][i];
2485 /* Skip empty keymaps */
2488 /* Encode the key */
2491 ascii_to_text(key, buf);
2493 /* Encode the action */
2494 ascii_to_text(buf, act);
2496 /* Dump the macro */
2497 auto_dump_printf("A:%s\n", buf);
2498 auto_dump_printf("C:%d:%s\n", mode, key);
2510 * @brief マクロを設定するコマンドのメインルーチン /
2511 * Interact with "macros"
2515 * Note that the macro "action" must be defined before the trigger.
2517 * Could use some helpful instructions on this page.
2520 void do_cmd_macros(void)
2532 if (rogue_like_commands)
2534 mode = KEYMAP_MODE_ROGUE;
2540 mode = KEYMAP_MODE_ORIG;
2543 /* File type is "TEXT" */
2544 FILE_TYPE(FILE_TYPE_TEXT);
2549 /* Process requests until done */
2553 prt(_("[ マクロの設定 ]", "Interact with Macros"), 2, 0);
2555 /* Describe that action */
2556 prt(_("マクロ行動が(もしあれば)下に表示されます:", "Current action (if any) shown below:"), 20, 0);
2558 /* Analyze the current action */
2559 ascii_to_text(buf, macro__buf);
2561 /* Display the current action */
2566 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
2568 prt(_("(2) ファイルにマクロを追加", "(2) Append macros to a file"), 5, 5);
2569 prt(_("(3) マクロの確認", "(3) Query a macro"), 6, 5);
2570 prt(_("(4) マクロの作成", "(4) Create a macro"), 7, 5);
2571 prt(_("(5) マクロの削除", "(5) Remove a macro"), 8, 5);
2572 prt(_("(6) ファイルにキー配置を追加", "(6) Append keymaps to a file"), 9, 5);
2573 prt(_("(7) キー配置の確認", "(7) Query a keymap"), 10, 5);
2574 prt(_("(8) キー配置の作成", "(8) Create a keymap"), 11, 5);
2575 prt(_("(9) キー配置の削除", "(9) Remove a keymap"), 12, 5);
2576 prt(_("(0) マクロ行動の入力", "(0) Enter a new action"), 13, 5);
2577 #endif /* ALLOW_MACROS */
2580 prt(_("コマンド: ", "Command: "), 16, 0);
2585 if (i == ESCAPE) break;
2587 /* Load a 'macro' file */
2593 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 16, 0);
2596 prt(_("ファイル: ", "File: "), 18, 0);
2598 /* Default filename */
2599 sprintf(tmp, "%s.prf", player_base);
2601 /* Ask for a file */
2602 if (!askfor(tmp, 80)) continue;
2604 /* Process the given filename */
2605 err = process_pref_file(tmp);
2608 msg_format(_("標準の設定ファイル'%s'を読み込みました。", "Loaded default '%s'."), tmp);
2613 msg_format(_("'%s'の読み込みに失敗しました!", "Failed to load '%s'!"), tmp);
2617 msg_format(_("'%s'を読み込みました。", "Loaded '%s'."), tmp);
2627 prt(_("コマンド: マクロをファイルに追加する", "Command: Append macros to a file"), 16, 0);
2630 prt(_("ファイル: ", "File: "), 18, 0);
2632 /* Default filename */
2633 sprintf(tmp, "%s.prf", player_base);
2635 /* Ask for a file */
2636 if (!askfor(tmp, 80)) continue;
2638 /* Dump the macros */
2639 (void)macro_dump(tmp);
2642 msg_print(_("マクロを追加しました。", "Appended macros."));
2651 prt(_("コマンド: マクロの確認", "Command: Query a macro"), 16, 0);
2655 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2657 /* Get a macro trigger */
2658 do_cmd_macro_aux(buf);
2660 /* Acquire action */
2661 k = macro_find_exact(buf);
2667 msg_print(_("そのキーにはマクロは定義されていません。", "Found no macro."));
2673 /* Obtain the action */
2674 strcpy(macro__buf, macro__act[k]);
2676 /* Analyze the current action */
2677 ascii_to_text(buf, macro__buf);
2679 /* Display the current action */
2683 msg_print(_("マクロを確認しました。", "Found a macro."));
2687 /* Create a macro */
2691 prt(_("コマンド: マクロの作成", "Command: Create a macro"), 16, 0);
2694 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2696 /* Get a macro trigger */
2697 do_cmd_macro_aux(buf);
2703 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2704 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2707 prt(_("マクロ行動: ", "Action: "), 20, 0);
2709 /* Convert to text */
2710 ascii_to_text(tmp, macro__buf);
2712 /* Get an encoded action */
2713 if (askfor(tmp, 80))
2715 /* Convert to ascii */
2716 text_to_ascii(macro__buf, tmp);
2718 /* Link the macro */
2719 macro_add(buf, macro__buf);
2722 msg_print(_("マクロを追加しました。", "Added a macro."));
2726 /* Remove a macro */
2730 prt(_("コマンド: マクロの削除", "Command: Remove a macro"), 16, 0);
2733 prt(_("トリガーキー: ", "Trigger: "), 18, 0);
2735 /* Get a macro trigger */
2736 do_cmd_macro_aux(buf);
2738 /* Link the macro */
2739 macro_add(buf, buf);
2742 msg_print(_("マクロを削除しました。", "Removed a macro."));
2749 prt(_("コマンド: キー配置をファイルに追加する", "Command: Append keymaps to a file"), 16, 0);
2752 prt(_("ファイル: ", "File: "), 18, 0);
2754 /* Default filename */
2755 sprintf(tmp, "%s.prf", player_base);
2757 /* Ask for a file */
2758 if (!askfor(tmp, 80)) continue;
2760 /* Dump the macros */
2761 (void)keymap_dump(tmp);
2764 msg_print(_("キー配置を追加しました。", "Appended keymaps."));
2767 /* Query a keymap */
2773 prt(_("コマンド: キー配置の確認", "Command: Query a keymap"), 16, 0);
2776 prt(_("押すキー: ", "Keypress: "), 18, 0);
2778 /* Get a keymap trigger */
2779 do_cmd_macro_aux_keymap(buf);
2781 /* Look up the keymap */
2782 act = keymap_act[mode][(byte)(buf[0])];
2788 msg_print(_("キー配置は定義されていません。", "Found no keymap."));
2794 /* Obtain the action */
2795 strcpy(macro__buf, act);
2797 /* Analyze the current action */
2798 ascii_to_text(buf, macro__buf);
2800 /* Display the current action */
2804 msg_print(_("キー配置を確認しました。", "Found a keymap."));
2808 /* Create a keymap */
2812 prt(_("コマンド: キー配置の作成", "Command: Create a keymap"), 16, 0);
2815 prt(_("押すキー: ", "Keypress: "), 18, 0);
2817 /* Get a keymap trigger */
2818 do_cmd_macro_aux_keymap(buf);
2824 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2825 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2828 prt(_("行動: ", "Action: "), 20, 0);
2830 /* Convert to text */
2831 ascii_to_text(tmp, macro__buf);
2833 /* Get an encoded action */
2834 if (askfor(tmp, 80))
2836 /* Convert to ascii */
2837 text_to_ascii(macro__buf, tmp);
2839 /* Free old keymap */
2840 string_free(keymap_act[mode][(byte)(buf[0])]);
2842 /* Make new keymap */
2843 keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf);
2846 msg_print(_("キー配置を追加しました。", "Added a keymap."));
2850 /* Remove a keymap */
2854 prt(_("コマンド: キー配置の削除", "Command: Remove a keymap"), 16, 0);
2857 prt(_("押すキー: ", "Keypress: "), 18, 0);
2859 /* Get a keymap trigger */
2860 do_cmd_macro_aux_keymap(buf);
2862 /* Free old keymap */
2863 string_free(keymap_act[mode][(byte)(buf[0])]);
2865 /* Make new keymap */
2866 keymap_act[mode][(byte)(buf[0])] = NULL;
2869 msg_print(_("キー配置を削除しました。", "Removed a keymap."));
2872 /* Enter a new action */
2876 prt(_("コマンド: マクロ行動の入力", "Command: Enter a new action"), 16, 0);
2882 c_prt(TERM_L_RED, _("カーソルキーの左右でカーソル位置を移動。BackspaceかDeleteで一文字削除。",
2883 "Press Left/Right arrow keys to move cursor. Backspace/Delete to delete a char."), 22, 0);
2886 prt(_("マクロ行動: ", "Action: "), 20, 0);
2888 /* Hack -- limit the value */
2891 /* Get an encoded action */
2892 if (!askfor(buf, 80)) continue;
2894 /* Extract an action */
2895 text_to_ascii(macro__buf, buf);
2898 #endif /* ALLOW_MACROS */
2911 * @brief キャラクタ色の明暗表現
2913 static cptr lighting_level_str[F_LIT_MAX] =
2928 * @brief キャラクタのビジュアルIDを変更する際の対象指定関数
2929 * @param i 指定対象となるキャラクタコード
2930 * @param num 指定されたビジュアルIDを返す参照ポインタ
2931 * @param max ビジュアルIDの最大数
2932 * @return 指定が実際に行われた場合TRUE、キャンセルされた場合FALSE
2934 static bool cmd_visuals_aux(int i, IDX *num, IDX max)
2941 sprintf(str, "%d", *num);
2943 if (!get_string(format("Input new number(0-%d): ", max-1), str, 4))
2946 tmp = (IDX)strtol(str, NULL, 0);
2947 if (tmp >= 0 && tmp < max)
2950 else if (isupper(i))
2951 *num = (*num + max - 1) % max;
2953 *num = (*num + 1) % max;
2959 * @brief キャラクタの変更メニュー表示
2960 * @param choice_msg 選択メッセージ
2963 static void print_visuals_menu(cptr choice_msg)
2965 prt(_("[ 画面表示の設定 ]", "Interact with Visuals"), 1, 0);
2967 /* Give some choices */
2968 prt(_("(0) ユーザー設定ファイルのロード", "(0) Load a user pref file"), 3, 5);
2970 #ifdef ALLOW_VISUALS
2971 prt(_("(1) モンスターの 色/文字 をファイルに書き出す", "(1) Dump monster attr/chars"), 4, 5);
2972 prt(_("(2) アイテムの 色/文字 をファイルに書き出す", "(2) Dump object attr/chars"), 5, 5);
2973 prt(_("(3) 地形の 色/文字 をファイルに書き出す", "(3) Dump feature attr/chars"), 6, 5);
2974 prt(_("(4) モンスターの 色/文字 を変更する (数値操作)", "(4) Change monster attr/chars (numeric operation)"), 7, 5);
2975 prt(_("(5) アイテムの 色/文字 を変更する (数値操作)", "(5) Change object attr/chars (numeric operation)"), 8, 5);
2976 prt(_("(6) 地形の 色/文字 を変更する (数値操作)", "(6) Change feature attr/chars (numeric operation)"), 9, 5);
2977 prt(_("(7) モンスターの 色/文字 を変更する (シンボルエディタ)", "(7) Change monster attr/chars (visual mode)"), 10, 5);
2978 prt(_("(8) アイテムの 色/文字 を変更する (シンボルエディタ)", "(8) Change object attr/chars (visual mode)"), 11, 5);
2979 prt(_("(9) 地形の 色/文字 を変更する (シンボルエディタ)", "(9) Change feature attr/chars (visual mode)"), 12, 5);
2980 #endif /* ALLOW_VISUALS */
2982 prt(_("(R) 画面表示方法の初期化", "(R) Reset visuals"), 13, 5);
2985 prt(format("コマンド: %s", choice_msg ? choice_msg : _("", "")), 15, 0);
2988 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx);
2989 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx);
2990 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level);
2993 * Interact with "visuals"
2995 void do_cmd_visuals(void)
3000 bool need_redraw = FALSE;
3001 cptr empty_symbol = "<< ? >>";
3003 if (use_bigtile) empty_symbol = "<< ?? >>";
3005 /* File type is "TEXT" */
3006 FILE_TYPE(FILE_TYPE_TEXT);
3009 /* Interact until done */
3014 /* Ask for a choice */
3015 print_visuals_menu(NULL);
3020 if (i == ESCAPE) break;
3024 /* Load a 'pref' file */
3027 prt(_("コマンド: ユーザー設定ファイルのロード", "Command: Load a user pref file"), 15, 0);
3030 prt(_("ファイル: ", "File: "), 17, 0);
3032 /* Default filename */
3033 sprintf(tmp, "%s.prf", player_base);
3036 if (!askfor(tmp, 70)) continue;
3038 /* Process the given filename */
3039 (void)process_pref_file(tmp);
3044 #ifdef ALLOW_VISUALS
3046 /* Dump monster attr/chars */
3049 static cptr mark = "Monster attr/chars";
3052 prt(_("コマンド: モンスターの[色/文字]をファイルに書き出します", "Command: Dump monster attr/chars"), 15, 0);
3055 prt(_("ファイル: ", "File: "), 17, 0);
3057 /* Default filename */
3058 sprintf(tmp, "%s.prf", player_base);
3060 /* Get a filename */
3061 if (!askfor(tmp, 70)) continue;
3063 /* Build the filename */
3064 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3066 /* Append to the file */
3067 if (!open_auto_dump(buf, mark)) continue;
3070 auto_dump_printf(_("\n# モンスターの[色/文字]の設定\n\n", "\n# Monster attr/char definitions\n\n"));
3073 for (i = 0; i < max_r_idx; i++)
3075 monster_race *r_ptr = &r_info[i];
3077 /* Skip non-entries */
3078 if (!r_ptr->name) continue;
3080 /* Dump a comment */
3081 auto_dump_printf("# %s\n", (r_name + r_ptr->name));
3083 /* Dump the monster attr/char info */
3084 auto_dump_printf("R:%d:0x%02X/0x%02X\n\n", i,
3085 (byte)(r_ptr->x_attr), (byte)(r_ptr->x_char));
3091 msg_print(_("モンスターの[色/文字]をファイルに書き出しました。", "Dumped monster attr/chars."));
3096 /* Dump object attr/chars */
3099 static cptr mark = "Object attr/chars";
3100 KIND_OBJECT_IDX k_idx;
3103 prt(_("コマンド: アイテムの[色/文字]をファイルに書き出します", "Command: Dump object attr/chars"), 15, 0);
3106 prt(_("ファイル: ", "File: "), 17, 0);
3108 /* Default filename */
3109 sprintf(tmp, "%s.prf", player_base);
3111 /* Get a filename */
3112 if (!askfor(tmp, 70)) continue;
3114 /* Build the filename */
3115 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3117 /* Append to the file */
3118 if (!open_auto_dump(buf, mark)) continue;
3121 auto_dump_printf(_("\n# アイテムの[色/文字]の設定\n\n", "\n# Object attr/char definitions\n\n"));
3124 for (k_idx = 0; k_idx < max_k_idx; k_idx++)
3126 GAME_TEXT o_name[MAX_NLEN];
3127 object_kind *k_ptr = &k_info[k_idx];
3129 /* Skip non-entries */
3130 if (!k_ptr->name) continue;
3135 strip_name(o_name, k_idx);
3141 /* Prepare dummy object */
3142 object_prep(&forge, k_idx);
3144 /* Get un-shuffled flavor name */
3145 object_desc(o_name, &forge, OD_FORCE_FLAVOR);
3148 /* Dump a comment */
3149 auto_dump_printf("# %s\n", o_name);
3151 /* Dump the object attr/char info */
3152 auto_dump_printf("K:%d:0x%02X/0x%02X\n\n", (int)k_idx,
3153 (byte)(k_ptr->x_attr), (byte)(k_ptr->x_char));
3159 msg_print(_("アイテムの[色/文字]をファイルに書き出しました。", "Dumped object attr/chars."));
3164 /* Dump feature attr/chars */
3167 static cptr mark = "Feature attr/chars";
3170 prt(_("コマンド: 地形の[色/文字]をファイルに書き出します", "Command: Dump feature attr/chars"), 15, 0);
3173 prt(_("ファイル: ", "File: "), 17, 0);
3175 /* Default filename */
3176 sprintf(tmp, "%s.prf", player_base);
3178 /* Get a filename */
3179 if (!askfor(tmp, 70)) continue;
3181 /* Build the filename */
3182 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3184 /* Append to the file */
3185 if (!open_auto_dump(buf, mark)) continue;
3188 auto_dump_printf(_("\n# 地形の[色/文字]の設定\n\n", "\n# Feature attr/char definitions\n\n"));
3191 for (i = 0; i < max_f_idx; i++)
3193 feature_type *f_ptr = &f_info[i];
3195 /* Skip non-entries */
3196 if (!f_ptr->name) continue;
3198 /* Skip mimiccing features */
3199 if (f_ptr->mimic != i) continue;
3201 /* Dump a comment */
3202 auto_dump_printf("# %s\n", (f_name + f_ptr->name));
3204 /* Dump the feature attr/char info */
3205 auto_dump_printf("F:%d:0x%02X/0x%02X:0x%02X/0x%02X:0x%02X/0x%02X\n\n", i,
3206 (byte)(f_ptr->x_attr[F_LIT_STANDARD]), (byte)(f_ptr->x_char[F_LIT_STANDARD]),
3207 (byte)(f_ptr->x_attr[F_LIT_LITE]), (byte)(f_ptr->x_char[F_LIT_LITE]),
3208 (byte)(f_ptr->x_attr[F_LIT_DARK]), (byte)(f_ptr->x_char[F_LIT_DARK]));
3214 msg_print(_("地形の[色/文字]をファイルに書き出しました。", "Dumped feature attr/chars."));
3219 /* Modify monster attr/chars (numeric operation) */
3222 static cptr choice_msg = _("モンスターの[色/文字]を変更します", "Change monster attr/chars");
3225 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3227 /* Hack -- query until done */
3230 monster_race *r_ptr = &r_info[r];
3234 TERM_COLOR da = r_ptr->d_attr;
3235 byte dc = r_ptr->d_char;
3236 TERM_COLOR ca = r_ptr->x_attr;
3237 byte cc = r_ptr->x_char;
3239 /* Label the object */
3240 Term_putstr(5, 17, -1, TERM_WHITE,
3241 format(_("モンスター = %d, 名前 = %-40.40s", "Monster = %d, Name = %-40.40s"), r, (r_name + r_ptr->name)));
3243 /* Label the Default values */
3244 Term_putstr(10, 19, -1, TERM_WHITE,
3245 format(_("初期値 色 / 文字 = %3u / %3u", "Default attr/char = %3u / %3u"), da, dc));
3247 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3248 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3250 /* Label the Current values */
3251 Term_putstr(10, 20, -1, TERM_WHITE,
3252 format(_("現在値 色 / 文字 = %3u / %3u", "Current attr/char = %3u / %3u"), ca, cc));
3254 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3255 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3258 Term_putstr(0, 22, -1, TERM_WHITE,
3259 _("コマンド (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): "));
3264 if (i == ESCAPE) break;
3266 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3267 else if (isupper(i)) c = 'a' + i - 'A';
3277 if (!cmd_visuals_aux(i, &r, max_r_idx))
3283 while (!r_info[r].name);
3287 t = (int)r_ptr->x_attr;
3288 (void)cmd_visuals_aux(i, &t, 256);
3289 r_ptr->x_attr = (byte)t;
3293 t = (int)r_ptr->x_char;
3294 (void)cmd_visuals_aux(i, &t, 256);
3295 r_ptr->x_char = (byte)t;
3299 do_cmd_knowledge_monsters(&need_redraw, TRUE, r);
3301 print_visuals_menu(choice_msg);
3309 /* Modify object attr/chars (numeric operation) */
3312 static cptr choice_msg = _("アイテムの[色/文字]を変更します", "Change object attr/chars");
3314 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3316 /* Hack -- query until done */
3319 object_kind *k_ptr = &k_info[k];
3323 TERM_COLOR da = k_ptr->d_attr;
3324 SYMBOL_CODE dc = k_ptr->d_char;
3325 TERM_COLOR ca = k_ptr->x_attr;
3326 SYMBOL_CODE cc = k_ptr->x_char;
3328 /* Label the object */
3329 Term_putstr(5, 17, -1, TERM_WHITE,
3330 format(_("アイテム = %d, 名前 = %-40.40s", "Object = %d, Name = %-40.40s"),
3331 k, k_name + (!k_ptr->flavor ? k_ptr->name : k_ptr->flavor_name)));
3333 /* Label the Default values */
3334 Term_putstr(10, 19, -1, TERM_WHITE,
3335 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3337 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3338 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3340 /* Label the Current values */
3341 Term_putstr(10, 20, -1, TERM_WHITE,
3342 format(_("現在値 色 / 文字 = %3d / %3d", "Current attr/char = %3d / %3d"), ca, cc));
3344 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3345 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3348 Term_putstr(0, 22, -1, TERM_WHITE,
3349 _("コマンド (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): "));
3354 if (i == ESCAPE) break;
3356 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3357 else if (isupper(i)) c = 'a' + i - 'A';
3367 if (!cmd_visuals_aux(i, &k, max_k_idx))
3373 while (!k_info[k].name);
3377 t = (int)k_ptr->x_attr;
3378 (void)cmd_visuals_aux(i, &t, 256);
3379 k_ptr->x_attr = (byte)t;
3383 t = (int)k_ptr->x_char;
3384 (void)cmd_visuals_aux(i, &t, 256);
3385 k_ptr->x_char = (byte)t;
3389 do_cmd_knowledge_objects(&need_redraw, TRUE, k);
3391 print_visuals_menu(choice_msg);
3399 /* Modify feature attr/chars (numeric operation) */
3402 static cptr choice_msg = _("地形の[色/文字]を変更します", "Change feature attr/chars");
3404 static IDX lighting_level = F_LIT_STANDARD;
3405 prt(format(_("コマンド: %s", "Command: %s"), choice_msg), 15, 0);
3407 /* Hack -- query until done */
3410 feature_type *f_ptr = &f_info[f];
3414 TERM_COLOR da = f_ptr->d_attr[lighting_level];
3415 byte dc = f_ptr->d_char[lighting_level];
3416 TERM_COLOR ca = f_ptr->x_attr[lighting_level];
3417 byte cc = f_ptr->x_char[lighting_level];
3419 /* Label the object */
3421 Term_putstr(5, 17, -1, TERM_WHITE,
3422 format(_("地形 = %d, 名前 = %s, 明度 = %s", "Terrain = %d, Name = %s, Lighting = %s"),
3423 f, (f_name + f_ptr->name), lighting_level_str[lighting_level]));
3425 /* Label the Default values */
3426 Term_putstr(10, 19, -1, TERM_WHITE,
3427 format(_("初期値 色 / 文字 = %3d / %3d", "Default attr/char = %3d / %3d"), da, dc));
3429 Term_putstr(40, 19, -1, TERM_WHITE, empty_symbol);
3430 Term_queue_bigchar(43, 19, da, dc, 0, 0);
3432 /* Label the Current values */
3434 Term_putstr(10, 20, -1, TERM_WHITE,
3435 format("現在値 色 / 文字 = %3d / %3d", ca, cc));
3437 Term_putstr(10, 20, -1, TERM_WHITE,
3438 format("Current attr/char = %3d / %3d", ca, cc));
3441 Term_putstr(40, 20, -1, TERM_WHITE, empty_symbol);
3442 Term_queue_bigchar(43, 20, ca, cc, 0, 0);
3446 Term_putstr(0, 22, -1, TERM_WHITE,
3447 "コマンド (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3449 Term_putstr(0, 22, -1, TERM_WHITE,
3450 "Command (n/N/^N/a/A/^A/c/C/^C/l/L/^L/d/D/^D/v/V/^V): ");
3456 if (i == ESCAPE) break;
3458 if (iscntrl(i)) c = 'a' + i - KTRL('A');
3459 else if (isupper(i)) c = 'a' + i - 'A';
3469 if (!cmd_visuals_aux(i, &f, max_f_idx))
3475 while (!f_info[f].name || (f_info[f].mimic != f));
3479 t = (int)f_ptr->x_attr[lighting_level];
3480 (void)cmd_visuals_aux(i, &t, 256);
3481 f_ptr->x_attr[lighting_level] = (byte)t;
3485 t = (int)f_ptr->x_char[lighting_level];
3486 (void)cmd_visuals_aux(i, &t, 256);
3487 f_ptr->x_char[lighting_level] = (byte)t;
3491 (void)cmd_visuals_aux(i, &lighting_level, F_LIT_MAX);
3494 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
3498 do_cmd_knowledge_features(&need_redraw, TRUE, f, &lighting_level);
3500 print_visuals_menu(choice_msg);
3508 /* Modify monster attr/chars (visual mode) */
3510 do_cmd_knowledge_monsters(&need_redraw, TRUE, -1);
3513 /* Modify object attr/chars (visual mode) */
3515 do_cmd_knowledge_objects(&need_redraw, TRUE, -1);
3518 /* Modify feature attr/chars (visual mode) */
3521 IDX lighting_level = F_LIT_STANDARD;
3522 do_cmd_knowledge_features(&need_redraw, TRUE, -1, &lighting_level);
3526 #endif /* ALLOW_VISUALS */
3534 msg_print(_("画面上の[色/文字]を初期値にリセットしました。", "Visual attr/char tables reset."));
3538 /* Unknown option */
3548 if (need_redraw) do_cmd_redraw();
3553 * Interact with "colors"
3555 void do_cmd_colors(void)
3564 /* File type is "TEXT" */
3565 FILE_TYPE(FILE_TYPE_TEXT);
3570 /* Interact until done */
3575 /* Ask for a choice */
3576 prt(_("[ カラーの設定 ]", "Interact with Colors"), 2, 0);
3578 /* Give some choices */
3579 prt(_("(1) ユーザー設定ファイルのロード", "(1) Load a user pref file"), 4, 5);
3582 prt(_("(2) カラーの設定をファイルに書き出す", "(2) Dump colors"), 5, 5);
3583 prt(_("(3) カラーの設定を変更する", "(3) Modify colors"), 6, 5);
3587 prt(_("コマンド: ", "Command: "), 8, 0);
3591 if (i == ESCAPE) break;
3593 /* Load a 'pref' file */
3597 prt(_("コマンド: ユーザー設定ファイルをロードします", "Command: Load a user pref file"), 8, 0);
3600 prt(_("ファイル: ", "File: "), 10, 0);
3603 sprintf(tmp, "%s.prf", player_base);
3606 if (!askfor(tmp, 70)) continue;
3608 /* Process the given filename */
3609 (void)process_pref_file(tmp);
3611 /* Mega-Hack -- react to changes */
3612 Term_xtra(TERM_XTRA_REACT, 0);
3614 /* Mega-Hack -- redraw */
3623 static cptr mark = "Colors";
3626 prt(_("コマンド: カラーの設定をファイルに書き出します", "Command: Dump colors"), 8, 0);
3629 prt(_("ファイル: ", "File: "), 10, 0);
3631 /* Default filename */
3632 sprintf(tmp, "%s.prf", player_base);
3634 /* Get a filename */
3635 if (!askfor(tmp, 70)) continue;
3637 /* Build the filename */
3638 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
3640 /* Append to the file */
3641 if (!open_auto_dump(buf, mark)) continue;
3644 auto_dump_printf(_("\n# カラーの設定\n\n", "\n# Color redefinitions\n\n"));
3647 for (i = 0; i < 256; i++)
3649 int kv = angband_color_table[i][0];
3650 int rv = angband_color_table[i][1];
3651 int gv = angband_color_table[i][2];
3652 int bv = angband_color_table[i][3];
3654 cptr name = _("未知", "unknown");
3656 /* Skip non-entries */
3657 if (!kv && !rv && !gv && !bv) continue;
3659 /* Extract the color name */
3660 if (i < 16) name = color_names[i];
3662 /* Dump a comment */
3663 auto_dump_printf(_("# カラー '%s'\n", "# Color '%s'\n"), name);
3665 /* Dump the monster attr/char info */
3666 auto_dump_printf("V:%d:0x%02X:0x%02X:0x%02X:0x%02X\n\n",
3673 msg_print(_("カラーの設定をファイルに書き出しました。", "Dumped color redefinitions."));
3682 prt(_("コマンド: カラーの設定を変更します", "Command: Modify colors"), 8, 0);
3684 /* Hack -- query until done */
3693 /* Exhibit the normal colors */
3694 for (j = 0; j < 16; j++)
3696 /* Exhibit this color */
3697 Term_putstr(j*4, 20, -1, a, "###");
3699 /* Exhibit all colors */
3700 Term_putstr(j*4, 22, -1, j, format("%3d", j));
3703 /* Describe the color */
3704 name = ((a < 16) ? color_names[a] : _("未定義", "undefined"));
3706 /* Describe the color */
3707 Term_putstr(5, 10, -1, TERM_WHITE,
3708 format(_("カラー = %d, 名前 = %s", "Color = %d, Name = %s"), a, name));
3710 /* Label the Current values */
3711 Term_putstr(5, 12, -1, TERM_WHITE,
3712 format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
3713 angband_color_table[a][0],
3714 angband_color_table[a][1],
3715 angband_color_table[a][2],
3716 angband_color_table[a][3]));
3719 Term_putstr(0, 14, -1, TERM_WHITE,
3720 _("コマンド (n/N/k/K/r/R/g/G/b/B): ", "Command (n/N/k/K/r/R/g/G/b/B): "));
3725 if (i == ESCAPE) break;
3728 if (i == 'n') a = (byte)(a + 1);
3729 if (i == 'N') a = (byte)(a - 1);
3730 if (i == 'k') angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
3731 if (i == 'K') angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
3732 if (i == 'r') angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
3733 if (i == 'R') angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
3734 if (i == 'g') angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
3735 if (i == 'G') angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
3736 if (i == 'b') angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
3737 if (i == 'B') angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);
3739 /* Hack -- react to changes */
3740 Term_xtra(TERM_XTRA_REACT, 0);
3742 /* Hack -- redraw */
3749 /* Unknown option */
3763 * Note something in the message recall
3765 void do_cmd_note(void)
3773 if (!get_string(_("メモ: ", "Note: "), buf, 60)) return;
3775 /* Ignore empty notes */
3776 if (!buf[0] || (buf[0] == ' ')) return;
3778 /* Add the note to the message recall */
3779 msg_format(_("メモ: %s", "Note: %s"), buf);
3784 * Mention the current version
3786 void do_cmd_version(void)
3788 #if FAKE_VER_EXTRA > 0
3789 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d.%d", "You are playing Hengband %d.%d.%d.%d."),
3790 FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH, FAKE_VER_EXTRA);
3792 msg_format(_("変愚蛮怒(Hengband) %d.%d.%d", "You are playing Hengband %d.%d.%d."),
3793 FAKE_VER_MAJOR - 10, FAKE_VER_MINOR, FAKE_VER_PATCH);
3800 * Array of feeling strings
3802 static cptr do_cmd_feeling_text[11] =
3804 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3805 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3806 _("恐ろしい死の幻が目に浮かび、気絶しそうになった!", "You nearly faint as horrible visions of death fill your mind!"),
3807 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3808 _("とても悪い予感がする...", "You have a very bad feeling..."),
3809 _("悪い予感がする...", "You have a bad feeling..."),
3810 _("何か緊張する。", "You feel nervous."),
3811 _("少し不運な気がする...", "You feel your luck is turning..."),
3812 _("この場所は好きになれない。", "You don't like the look of this place."),
3813 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3814 _("なんて退屈なところだ...", "What a boring place...")
3817 static cptr do_cmd_feeling_text_combat[11] =
3819 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3820 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3821 _("今夜もまた、誰かが命を落とす...", "You nearly faint as horrible visions of death fill your mind!"),
3822 _("この階はとても危険なようだ。", "This level looks very dangerous."),
3823 _("とても悪い予感がする...", "You have a very bad feeling..."),
3824 _("悪い予感がする...", "You have a bad feeling..."),
3825 _("何か緊張する。", "You feel nervous."),
3826 _("少し不運な気がする...", "You feel your luck is turning..."),
3827 _("この場所は好きになれない。", "You don't like the look of this place."),
3828 _("この階はそれなりに安全なようだ。", "This level looks reasonably safe."),
3829 _("なんて退屈なところだ...", "What a boring place...")
3832 static cptr do_cmd_feeling_text_lucky[11] =
3834 _("この階の雰囲気を感じとれなかった...", "Looks like any other level."),
3835 _("この階には何か特別なものがあるような気がする。", "You feel there is something special about this level."),
3836 _("この階はこの上なく素晴らしい感じがする。", "You have a superb feeling about this level."),
3837 _("素晴らしい感じがする...", "You have an excellent feeling..."),
3838 _("とても良い感じがする...", "You have a very good feeling..."),
3839 _("良い感じがする...", "You have a good feeling..."),
3840 _("ちょっと幸運な感じがする...", "You feel strangely lucky..."),
3841 _("多少は運が向いてきたか...", "You feel your luck is turning..."),
3842 _("見た感じ悪くはない...", "You like the look of this place..."),
3843 _("全然駄目ということはないが...", "This level can't be all bad..."),
3844 _("なんて退屈なところだ...", "What a boring place...")
3849 * Note that "feeling" is set to zero unless some time has passed.
3850 * Note that this is done when the level is GENERATED, not entered.
3852 void do_cmd_feeling(void)
3854 if (p_ptr->wild_mode) return;
3856 /* No useful feeling in quests */
3857 if (p_ptr->inside_quest && !random_quest_number(dun_level))
3859 msg_print(_("典型的なクエストのダンジョンのようだ。", "Looks like a typical quest level."));
3863 /* No useful feeling in town */
3864 else if (p_ptr->town_num && !dun_level)
3866 if (!strcmp(town[p_ptr->town_num].name, _("荒野", "wilderness")))
3868 msg_print(_("何かありそうな荒野のようだ。", "Looks like a strange wilderness."));
3873 msg_print(_("典型的な町のようだ。", "Looks like a typical town."));
3878 /* No useful feeling in the wilderness */
3879 else if (!dun_level)
3881 msg_print(_("典型的な荒野のようだ。", "Looks like a typical wilderness."));
3885 /* Display the feeling */
3886 if (p_ptr->muta3 & MUT3_GOOD_LUCK)
3887 msg_print(do_cmd_feeling_text_lucky[p_ptr->feeling]);
3888 else if (p_ptr->pseikaku == SEIKAKU_COMBAT ||
3889 inventory[INVEN_BOW].name1 == ART_CRIMSON)
3890 msg_print(do_cmd_feeling_text_combat[p_ptr->feeling]);
3892 msg_print(do_cmd_feeling_text[p_ptr->feeling]);
3898 * Description of each monster group.
3900 static cptr monster_group_text[] =
3903 "ユニーク", /* "Uniques" */
3904 "乗馬可能なモンスター", /* "Riding" */
3905 "賞金首", /* "Wanted */
3906 "アンバーの王族", /* "Ambertite" */
3935 /* "古代ドラゴン/ワイアーム", */
3996 /* "Ancient Dragon/Wyrm", */
4005 "Multi-Headed Reptile",
4010 "Reptile/Amphibian",
4011 "Spider/Scorpion/Tick",
4013 /* "Major Demon", */
4030 * Symbols of monsters in each group. Note the "Uniques" group
4031 * is handled differently.
4033 static cptr monster_group_char[] =
4090 "!$&()+./=>?[\\]`{|~",
4100 * hook function to sort monsters by level
4102 static bool ang_sort_comp_monster_level(vptr u, vptr v, int a, int b)
4104 u16b *who = (u16b*)(u);
4109 monster_race *r_ptr1 = &r_info[w1];
4110 monster_race *r_ptr2 = &r_info[w2];
4115 if (r_ptr2->level > r_ptr1->level) return TRUE;
4116 if (r_ptr1->level > r_ptr2->level) return FALSE;
4118 if ((r_ptr2->flags1 & RF1_UNIQUE) && !(r_ptr1->flags1 & RF1_UNIQUE)) return TRUE;
4119 if ((r_ptr1->flags1 & RF1_UNIQUE) && !(r_ptr2->flags1 & RF1_UNIQUE)) return FALSE;
4124 * Build a list of monster indexes in the given group. Return the number
4125 * of monsters in the group.
4127 * mode & 0x01 : check for non-empty group
4128 * mode & 0x02 : visual operation only
4130 static IDX collect_monsters(IDX grp_cur, IDX mon_idx[], BIT_FLAGS8 mode)
4136 /* Get a list of x_char in this group */
4137 cptr group_char = monster_group_char[grp_cur];
4139 /* XXX Hack -- Check if this is the "Uniques" group */
4140 bool grp_unique = (monster_group_char[grp_cur] == (char *) -1L);
4142 /* XXX Hack -- Check if this is the "Riding" group */
4143 bool grp_riding = (monster_group_char[grp_cur] == (char *) -2L);
4145 /* XXX Hack -- Check if this is the "Wanted" group */
4146 bool grp_wanted = (monster_group_char[grp_cur] == (char *) -3L);
4148 /* XXX Hack -- Check if this is the "Amberite" group */
4149 bool grp_amberite = (monster_group_char[grp_cur] == (char *) -4L);
4152 /* Check every race */
4153 for (i = 0; i < max_r_idx; i++)
4155 /* Access the race */
4156 monster_race *r_ptr = &r_info[i];
4158 /* Skip empty race */
4159 if (!r_ptr->name) continue ;
4161 /* Require known monsters */
4162 if (!(mode & 0x02) && !cheat_know && !r_ptr->r_sights) continue;
4166 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
4169 else if (grp_riding)
4171 if (!(r_ptr->flags7 & RF7_RIDING)) continue;
4174 else if (grp_wanted)
4176 bool wanted = FALSE;
4178 for (j = 0; j < MAX_KUBI; j++)
4180 if (kubi_r_idx[j] == i || kubi_r_idx[j] - 10000 == i ||
4181 (p_ptr->today_mon && p_ptr->today_mon == i))
4187 if (!wanted) continue;
4190 else if (grp_amberite)
4192 if (!(r_ptr->flags3 & RF3_AMBERITE)) continue;
4197 /* Check for race in the group */
4198 if (!my_strchr(group_char, r_ptr->d_char)) continue;
4202 mon_idx[mon_cnt++] = i;
4204 /* XXX Hack -- Just checking for non-empty group */
4205 if (mode & 0x01) break;
4208 /* Terminate the list */
4209 mon_idx[mon_cnt] = -1;
4211 /* Select the sort method */
4212 ang_sort_comp = ang_sort_comp_monster_level;
4213 ang_sort_swap = ang_sort_swap_hook;
4215 /* Sort by monster level */
4216 ang_sort(mon_idx, &dummy_why, mon_cnt);
4218 /* Return the number of races */
4224 * Description of each monster group.
4226 static cptr object_group_text[] =
4229 "キノコ", /* "Mushrooms" */
4230 "薬", /* "Potions" */
4231 "油つぼ", /* "Flasks" */
4232 "巻物", /* "Scrolls" */
4234 "アミュレット", /* "Amulets" */
4235 "笛", /* "Whistle" */
4236 "光源", /* "Lanterns" */
4237 "魔法棒", /* "Wands" */
4240 "カード", /* "Cards" */
4251 "刀剣類", /* "Swords" */
4252 "鈍器", /* "Blunt Weapons" */
4253 "長柄武器", /* "Polearms" */
4254 "採掘道具", /* "Diggers" */
4255 "飛び道具", /* "Bows" */
4259 "軽装鎧", /* "Soft Armor" */
4260 "重装鎧", /* "Hard Armor" */
4261 "ドラゴン鎧", /* "Dragon Armor" */
4262 "盾", /* "Shields" */
4263 "クローク", /* "Cloaks" */
4264 "籠手", /* "Gloves" */
4265 "ヘルメット", /* "Helms" */
4267 "ブーツ", /* "Boots" */
4320 * TVALs of items in each group
4322 static byte object_group_tval[] =
4363 TV_LIFE_BOOK, /* Hack -- all spellbooks */
4371 * Build a list of object indexes in the given group. Return the number
4372 * of objects in the group.
4374 * mode & 0x01 : check for non-empty group
4375 * mode & 0x02 : visual operation only
4377 static int collect_objects(int grp_cur, IDX object_idx[], BIT_FLAGS8 mode)
4380 int j, k, object_cnt = 0;
4382 /* Get a list of x_char in this group */
4383 byte group_tval = object_group_tval[grp_cur];
4385 /* Check every object */
4386 for (i = 0; i < max_k_idx; i++)
4388 /* Access the object */
4389 object_kind *k_ptr = &k_info[i];
4391 /* Skip empty objects */
4392 if (!k_ptr->name) continue;
4396 /* Any objects will be displayed */
4402 /* Skip non-flavoured objects */
4403 if (!k_ptr->flavor) continue;
4405 /* Require objects ever seen */
4406 if (!k_ptr->aware) continue;
4409 /* Skip items with no distribution (special artifacts) */
4410 for (j = 0, k = 0; j < 4; j++) k += k_ptr->chance[j];
4414 /* Check for objects in the group */
4415 if (TV_LIFE_BOOK == group_tval)
4417 /* Hack -- All spell books */
4418 if (TV_LIFE_BOOK <= k_ptr->tval && k_ptr->tval <= TV_HEX_BOOK)
4420 /* Add the object */
4421 object_idx[object_cnt++] = i;
4425 else if (k_ptr->tval == group_tval)
4427 /* Add the object */
4428 object_idx[object_cnt++] = i;
4432 /* XXX Hack -- Just checking for non-empty group */
4433 if (mode & 0x01) break;
4436 /* Terminate the list */
4437 object_idx[object_cnt] = -1;
4439 /* Return the number of objects */
4445 * Description of each feature group.
4447 static cptr feature_group_text[] =
4455 * Build a list of feature indexes in the given group. Return the number
4456 * of features in the group.
4458 * mode & 0x01 : check for non-empty group
4460 static int collect_features(int grp_cur, IDX *feat_idx, BIT_FLAGS8 mode)
4465 /* Unused; There is a single group. */
4468 /* Check every feature */
4469 for (i = 0; i < max_f_idx; i++)
4471 /* Access the index */
4472 feature_type *f_ptr = &f_info[i];
4474 /* Skip empty index */
4475 if (!f_ptr->name) continue;
4477 /* Skip mimiccing features */
4478 if (f_ptr->mimic != i) continue;
4481 feat_idx[feat_cnt++] = i;
4483 /* XXX Hack -- Just checking for non-empty group */
4484 if (mode & 0x01) break;
4487 /* Terminate the list */
4488 feat_idx[feat_cnt] = -1;
4490 /* Return the number of races */
4497 * Build a list of monster indexes in the given group. Return the number
4498 * of monsters in the group.
4500 static int collect_artifacts(int grp_cur, int object_idx[])
4502 int i, object_cnt = 0;
4504 /* Get a list of x_char in this group */
4505 byte group_tval = object_group_tval[grp_cur];
4507 /* Check every object */
4508 for (i = 0; i < max_a_idx; i++)
4510 /* Access the artifact */
4511 artifact_type *a_ptr = &a_info[i];
4513 /* Skip empty artifacts */
4514 if (!a_ptr->name) continue;
4516 /* Skip "uncreated" artifacts */
4517 if (!a_ptr->cur_num) continue;
4519 /* Check for race in the group */
4520 if (a_ptr->tval == group_tval)
4523 object_idx[object_cnt++] = i;
4527 /* Terminate the list */
4528 object_idx[object_cnt] = 0;
4530 /* Return the number of races */
4537 * Encode the screen colors
4539 static char hack[17] = "dwsorgbuDWvyRGBU";
4543 * Hack -- load a screen dump from a file
4545 void do_cmd_load_screen(void)
4560 Term_get_size(&wid, &hgt);
4562 /* Build the filename */
4563 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
4565 /* Append to the file */
4566 fff = my_fopen(buf, "r");
4569 msg_format(_("%s を開くことができませんでした。", "Failed to open %s."), buf);
4577 /* Load the screen */
4578 for (y = 0; okay; y++)
4580 /* Get a line of data including control code */
4581 if (!fgets(buf, 1024, fff)) okay = FALSE;
4583 /* Get the blank line */
4584 if (buf[0] == '\n' || buf[0] == '\0') break;
4586 /* Ignore too large screen image */
4587 if (y >= hgt) continue;
4590 for (x = 0; x < wid - 1; x++)
4593 if (buf[x] == '\n' || buf[x] == '\0') break;
4595 /* Put the attr/char */
4596 Term_draw(x, y, TERM_WHITE, buf[x]);
4600 /* Dump the screen */
4601 for (y = 0; okay; y++)
4603 /* Get a line of data including control code */
4604 if (!fgets(buf, 1024, fff)) okay = FALSE;
4606 /* Get the blank line */
4607 if (buf[0] == '\n' || buf[0] == '\0') break;
4609 /* Ignore too large screen image */
4610 if (y >= hgt) continue;
4613 for (x = 0; x < wid - 1; x++)
4616 if (buf[x] == '\n' || buf[x] == '\0') break;
4618 /* Get the attr/char */
4619 (void)(Term_what(x, y, &a, &c));
4621 /* Look up the attr */
4622 for (i = 0; i < 16; i++)
4624 /* Use attr matches */
4625 if (hack[i] == buf[x]) a = (byte_hack)i;
4628 /* Put the attr/char */
4629 Term_draw(x, y, a, c);
4638 prt(_("ファイルに書き出された画面(記念撮影)をロードしました。", "Screen dump loaded."), 0, 0);
4649 cptr inven_res_label = _(" 酸電火冷毒光闇破轟獄因沌劣 盲怖乱痺透命感消復浮",
4650 " AcElFiCoPoLiDkShSoNtNxCaDi BlFeCfFaSeHlEpSdRgLv");
4653 #define IM_FLAG_STR _("*", "* ")
4654 #define HAS_FLAG_STR _("+", "+ ")
4655 #define NO_FLAG_STR _("・", ". ")
4657 #define print_im_or_res_flag(IM, RES) \
4659 fputs(have_flag(flgs, (IM)) ? IM_FLAG_STR : \
4660 (have_flag(flgs, (RES)) ? HAS_FLAG_STR : NO_FLAG_STR), fff); \
4663 #define print_flag(TR) \
4665 fputs(have_flag(flgs, (TR)) ? HAS_FLAG_STR : NO_FLAG_STR, fff); \
4669 /* XTRA HACK RESLIST */
4670 static void do_cmd_knowledge_inven_aux(FILE *fff, object_type *o_ptr, int *j, OBJECT_TYPE_VALUE tval, char *where)
4672 GAME_TEXT o_name[MAX_NLEN];
4673 BIT_FLAGS flgs[TR_FLAG_SIZE];
4675 if (!o_ptr->k_idx) return;
4676 if (o_ptr->tval != tval) return;
4678 /* Identified items only */
4679 if (!object_is_known(o_ptr)) return;
4682 * HACK:Ring of Lordly protection and Dragon equipment
4683 * have random resistances.
4685 if ((object_is_wearable(o_ptr) && object_is_ego(o_ptr))
4686 || ((tval == TV_AMULET) && (o_ptr->sval == SV_AMULET_RESISTANCE))
4687 || ((tval == TV_RING) && (o_ptr->sval == SV_RING_LORDLY))
4688 || ((tval == TV_SHIELD) && (o_ptr->sval == SV_DRAGON_SHIELD))
4689 || ((tval == TV_HELM) && (o_ptr->sval == SV_DRAGON_HELM))
4690 || ((tval == TV_GLOVES) && (o_ptr->sval == SV_SET_OF_DRAGON_GLOVES))
4691 || ((tval == TV_BOOTS) && (o_ptr->sval == SV_PAIR_OF_DRAGON_GREAVE))
4692 || object_is_artifact(o_ptr))
4695 object_desc(o_name, o_ptr, OD_NAME_ONLY);
4697 while (o_name[i] && (i < 26))
4700 if (iskanji(o_name[i])) i++;
4709 o_name[i] = ' '; i++;
4714 fprintf(fff, "%s %s", where, o_name);
4716 if (!(o_ptr->ident & (IDENT_MENTAL)))
4718 fputs(_("-------不明--------------- -------不明---------\n",
4719 "-------unknown------------ -------unknown------\n"), fff);
4723 object_flags_known(o_ptr, flgs);
4725 print_im_or_res_flag(TR_IM_ACID, TR_RES_ACID);
4726 print_im_or_res_flag(TR_IM_ELEC, TR_RES_ELEC);
4727 print_im_or_res_flag(TR_IM_FIRE, TR_RES_FIRE);
4728 print_im_or_res_flag(TR_IM_COLD, TR_RES_COLD);
4729 print_flag(TR_RES_POIS);
4730 print_flag(TR_RES_LITE);
4731 print_flag(TR_RES_DARK);
4732 print_flag(TR_RES_SHARDS);
4733 print_flag(TR_RES_SOUND);
4734 print_flag(TR_RES_NETHER);
4735 print_flag(TR_RES_NEXUS);
4736 print_flag(TR_RES_CHAOS);
4737 print_flag(TR_RES_DISEN);
4741 print_flag(TR_RES_BLIND);
4742 print_flag(TR_RES_FEAR);
4743 print_flag(TR_RES_CONF);
4744 print_flag(TR_FREE_ACT);
4745 print_flag(TR_SEE_INVIS);
4746 print_flag(TR_HOLD_EXP);
4747 print_flag(TR_TELEPATHY);
4748 print_flag(TR_SLOW_DIGEST);
4749 print_flag(TR_REGEN);
4750 print_flag(TR_LEVITATION);
4758 fprintf(fff, "%s\n", inven_res_label);
4764 * Display *ID* ed weapons/armors's resistances
4766 static void do_cmd_knowledge_inven(void)
4770 GAME_TEXT file_name[1024];
4774 OBJECT_TYPE_VALUE tval;
4780 /* Open a new file */
4781 fff = my_fopen_temp(file_name, 1024);
4784 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
4788 fprintf(fff, "%s\n", inven_res_label);
4790 for (tval = TV_WEARABLE_BEGIN; tval <= TV_WEARABLE_END; tval++)
4794 for (; j < 9; j++) fputc('\n', fff);
4796 fprintf(fff, "%s\n", inven_res_label);
4798 strcpy(where, _("装", "E "));
4799 for (i = INVEN_RARM; i < INVEN_TOTAL; i++)
4801 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4803 strcpy(where, _("持", "I "));
4804 for (i = 0; i < INVEN_PACK; i++)
4806 do_cmd_knowledge_inven_aux(fff, &inventory[i], &j, tval, where);
4809 st_ptr = &town[1].store[STORE_HOME];
4810 strcpy(where, _("家", "H "));
4811 for (i = 0; i < st_ptr->stock_num; i++)
4813 do_cmd_knowledge_inven_aux(fff, &st_ptr->stock[i], &j, tval, where);
4818 /* Display the file contents */
4819 show_file(TRUE, file_name, _("*鑑定*済み武器/防具の耐性リスト", "Resistances of *identified* equipment"), 0, 0);
4821 /* Remove the file */
4826 void do_cmd_save_screen_html_aux(char *filename, int message)
4830 TERM_COLOR a = 0, old_a = 0;
4844 cptr html_head[] = {
4845 "<html>\n<body text=\"#ffffff\" bgcolor=\"#000000\">\n",
4849 cptr html_foot[] = {
4851 "</body>\n</html>\n",
4857 Term_get_size(&wid, &hgt);
4859 /* File type is "TEXT" */
4860 FILE_TYPE(FILE_TYPE_TEXT);
4862 /* Append to the file */
4863 fff = my_fopen(filename, "w");
4867 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), filename);
4873 if (message) screen_save();
4875 /* Build the filename */
4876 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "htmldump.prf");
4877 tmpfff = my_fopen(buf, "r");
4879 for (i = 0; html_head[i]; i++)
4880 fputs(html_head[i], fff);
4884 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4886 if (strncmp(buf, tags[0], strlen(tags[0])) == 0)
4890 if (strncmp(buf, tags[1], strlen(tags[1])) == 0)
4892 fprintf(fff, "%s\n", buf);
4897 /* Dump the screen */
4898 for (y = 0; y < hgt; y++)
4905 for (x = 0; x < wid - 1; x++)
4909 /* Get the attr/char */
4910 (void)(Term_what(x, y, &a, &c));
4914 case '&': cc = "&"; break;
4915 case '<': cc = "<"; break;
4916 case '>': cc = ">"; break;
4918 case 0x1f: c = '.'; break;
4919 case 0x7f: c = (a == 0x09) ? '%' : '#'; break;
4924 if ((y == 0 && x == 0) || a != old_a) {
4925 rv = angband_color_table[a][1];
4926 gv = angband_color_table[a][2];
4927 bv = angband_color_table[a][3];
4928 fprintf(fff, "%s<font color=\"#%02x%02x%02x\">",
4929 ((y == 0 && x == 0) ? "" : "</font>"), rv, gv, bv);
4933 fprintf(fff, "%s", cc);
4935 fprintf(fff, "%c", c);
4938 fprintf(fff, "</font>");
4941 for (i = 0; html_foot[i]; i++)
4942 fputs(html_foot[i], fff);
4947 while (!my_fgets(tmpfff, buf, sizeof(buf))) {
4949 if (strncmp(buf, tags[2], strlen(tags[2])) == 0)
4953 if (strncmp(buf, tags[3], strlen(tags[3])) == 0)
4955 fprintf(fff, "%s\n", buf);
4968 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
4976 * Hack -- save a screen dump to a file
4978 static void do_cmd_save_screen_html(void)
4980 char buf[1024], tmp[256] = "screen.html";
4982 if (!get_string(_("ファイル名: ", "File name: "), tmp, 80))
4985 /* Build the filename */
4986 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, tmp);
4990 do_cmd_save_screen_html_aux(buf, 1);
4995 * Redefinable "save_screen" action
4997 void (*screendump_aux)(void) = NULL;
5001 * Hack -- save a screen dump to a file
5003 void do_cmd_save_screen(void)
5005 bool old_use_graphics = use_graphics;
5006 bool html_dump = FALSE;
5010 prt(_("記念撮影しますか? [(y)es/(h)tml/(n)o] ", "Save screen dump? [(y)es/(h)tml/(n)o] "), 0, 0);
5014 if (c == 'Y' || c == 'y')
5016 else if (c == 'H' || c == 'h')
5028 Term_get_size(&wid, &hgt);
5030 if (old_use_graphics)
5032 use_graphics = FALSE;
5034 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5040 do_cmd_save_screen_html();
5044 /* Do we use a special screendump function ? */
5045 else if (screendump_aux)
5047 /* Dump the screen to a graphics file */
5048 (*screendump_aux)();
5050 else /* Dump the screen as text */
5061 /* Build the filename */
5062 path_build(buf, sizeof(buf), ANGBAND_DIR_USER, "dump.txt");
5064 /* File type is "TEXT" */
5065 FILE_TYPE(FILE_TYPE_TEXT);
5067 /* Append to the file */
5068 fff = my_fopen(buf, "w");
5072 msg_format(_("ファイル %s を開けませんでした。", "Failed to open file %s."), buf);
5080 /* Dump the screen */
5081 for (y = 0; y < hgt; y++)
5084 for (x = 0; x < wid - 1; x++)
5086 /* Get the attr/char */
5087 (void)(Term_what(x, y, &a, &c));
5097 fprintf(fff, "%s\n", buf);
5104 /* Dump the screen */
5105 for (y = 0; y < hgt; y++)
5108 for (x = 0; x < wid - 1; x++)
5110 /* Get the attr/char */
5111 (void)(Term_what(x, y, &a, &c));
5114 buf[x] = hack[a&0x0F];
5121 fprintf(fff, "%s\n", buf);
5130 msg_print(_("画面(記念撮影)をファイルに書き出しました。", "Screen dump saved."));
5135 if (old_use_graphics)
5137 use_graphics = TRUE;
5139 p_ptr->redraw |= (PR_WIPE | PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIPPY);
5146 * Sorting hook -- Comp function -- see below
5148 * We use "u" to point to array of monster indexes,
5149 * and "v" to select the type of sorting to perform on "u".
5151 static bool ang_sort_art_comp(vptr u, vptr v, int a, int b)
5153 u16b *who = (u16b*)(u);
5155 u16b *why = (u16b*)(v);
5162 /* Sort by total kills */
5165 /* Extract total kills */
5166 z1 = a_info[w1].tval;
5167 z2 = a_info[w2].tval;
5169 /* Compare total kills */
5170 if (z1 < z2) return (TRUE);
5171 if (z1 > z2) return (FALSE);
5175 /* Sort by monster level */
5178 /* Extract levels */
5179 z1 = a_info[w1].sval;
5180 z2 = a_info[w2].sval;
5182 /* Compare levels */
5183 if (z1 < z2) return (TRUE);
5184 if (z1 > z2) return (FALSE);
5188 /* Sort by monster experience */
5191 /* Extract experience */
5192 z1 = a_info[w1].level;
5193 z2 = a_info[w2].level;
5195 /* Compare experience */
5196 if (z1 < z2) return (TRUE);
5197 if (z1 > z2) return (FALSE);
5201 /* Compare indexes */
5207 * Sorting hook -- Swap function -- see below
5209 * We use "u" to point to array of monster indexes,
5210 * and "v" to select the type of sorting to perform.
5212 static void ang_sort_art_swap(vptr u, vptr v, int a, int b)
5214 u16b *who = (u16b*)(u);
5229 * Check the status of "artifacts"
5231 static void do_cmd_knowledge_artifacts(void)
5241 GAME_TEXT file_name[1024];
5242 GAME_TEXT base_name[MAX_NLEN];
5246 /* Open a new file */
5247 fff = my_fopen_temp(file_name, 1024);
5250 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5255 /* Allocate the "who" array */
5256 C_MAKE(who, max_a_idx, ARTIFACT_IDX);
5258 /* Allocate the "okay" array */
5259 C_MAKE(okay, max_a_idx, bool);
5261 /* Scan the artifacts */
5262 for (k = 0; k < max_a_idx; k++)
5264 artifact_type *a_ptr = &a_info[k];
5269 /* Skip "empty" artifacts */
5270 if (!a_ptr->name) continue;
5272 /* Skip "uncreated" artifacts */
5273 if (!a_ptr->cur_num) continue;
5279 /* Check the dungeon */
5280 for (y = 0; y < cur_hgt; y++)
5282 for (x = 0; x < cur_wid; x++)
5284 cave_type *c_ptr = &cave[y][x];
5286 OBJECT_IDX this_o_idx, next_o_idx = 0;
5288 /* Scan all objects in the grid */
5289 for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
5292 o_ptr = &o_list[this_o_idx];
5294 /* Acquire next object */
5295 next_o_idx = o_ptr->next_o_idx;
5297 /* Ignore non-artifacts */
5298 if (!object_is_fixed_artifact(o_ptr)) continue;
5300 /* Ignore known items */
5301 if (object_is_known(o_ptr)) continue;
5303 /* Note the artifact */
5304 okay[o_ptr->name1] = FALSE;
5309 /* Check the inventory and equipment */
5310 for (i = 0; i < INVEN_TOTAL; i++)
5312 object_type *o_ptr = &inventory[i];
5314 /* Ignore non-objects */
5315 if (!o_ptr->k_idx) continue;
5317 /* Ignore non-artifacts */
5318 if (!object_is_fixed_artifact(o_ptr)) continue;
5320 /* Ignore known items */
5321 if (object_is_known(o_ptr)) continue;
5323 /* Note the artifact */
5324 okay[o_ptr->name1] = FALSE;
5327 for (k = 0; k < max_a_idx; k++)
5329 if (okay[k]) who[n++] = k;
5332 /* Select the sort method */
5333 ang_sort_comp = ang_sort_art_comp;
5334 ang_sort_swap = ang_sort_art_swap;
5336 /* Sort the array by dungeon depth of monsters */
5337 ang_sort(who, &why, n);
5339 /* Scan the artifacts */
5340 for (k = 0; k < n; k++)
5342 artifact_type *a_ptr = &a_info[who[k]];
5345 strcpy(base_name, _("未知の伝説のアイテム", "Unknown Artifact"));
5347 /* Obtain the base object type */
5348 z = lookup_kind(a_ptr->tval, a_ptr->sval);
5357 /* Create fake object */
5358 object_prep(q_ptr, z);
5360 /* Make it an artifact */
5361 q_ptr->name1 = (byte)who[k];
5363 /* Display as if known */
5364 q_ptr->ident |= IDENT_STORE;
5366 /* Describe the artifact */
5367 object_desc(base_name, q_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
5370 /* Hack -- Build the artifact name */
5371 fprintf(fff, _(" %s\n", " The %s\n"), base_name);
5374 /* Free the "who" array */
5375 C_KILL(who, max_a_idx, ARTIFACT_IDX);
5377 /* Free the "okay" array */
5378 C_KILL(okay, max_a_idx, bool);
5381 /* Display the file contents */
5382 show_file(TRUE, file_name, _("既知の伝説のアイテム", "Artifacts Seen"), 0, 0);
5384 /* Remove the file */
5390 * Display known uniques
5391 * With "XTRA HACK UNIQHIST" (Originally from XAngband)
5393 static void do_cmd_knowledge_uniques(void)
5402 GAME_TEXT file_name[1024];
5405 int n_alive_surface = 0;
5406 int n_alive_over100 = 0;
5407 int n_alive_total = 0;
5410 for (i = 0; i < 10; i++) n_alive[i] = 0;
5412 /* Open a new file */
5413 fff = my_fopen_temp(file_name, 1024);
5417 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5422 /* Allocate the "who" array */
5423 C_MAKE(who, max_r_idx, s16b);
5425 /* Scan the monsters */
5426 for (i = 1; i < max_r_idx; i++)
5428 monster_race *r_ptr = &r_info[i];
5431 if (!r_ptr->name) continue;
5433 /* Require unique monsters */
5434 if (!(r_ptr->flags1 & RF1_UNIQUE)) continue;
5436 /* Only display "known" uniques */
5437 if (!cheat_know && !r_ptr->r_sights) continue;
5439 /* Only print rarity <= 100 uniques */
5440 if (!r_ptr->rarity || ((r_ptr->rarity > 100) && !(r_ptr->flags1 & RF1_QUESTOR))) continue;
5442 /* Only "alive" uniques */
5443 if (r_ptr->max_num == 0) continue;
5447 lev = (r_ptr->level - 1) / 10;
5451 if (max_lev < lev) max_lev = lev;
5453 else n_alive_over100++;
5455 else n_alive_surface++;
5457 /* Collect "appropriate" monsters */
5461 /* Select the sort method */
5462 ang_sort_comp = ang_sort_comp_hook;
5463 ang_sort_swap = ang_sort_swap_hook;
5465 /* Sort the array by dungeon depth of monsters */
5466 ang_sort(who, &why, n);
5468 if (n_alive_surface)
5470 fprintf(fff, _(" 地上 生存: %3d体\n", " Surface alive: %3d\n"), n_alive_surface);
5471 n_alive_total += n_alive_surface;
5473 for (i = 0; i <= max_lev; i++)
5475 fprintf(fff, _("%3d-%3d階 生存: %3d体\n", "Level %3d-%3d alive: %3d\n"), 1 + i * 10, 10 + i * 10, n_alive[i]);
5476 n_alive_total += n_alive[i];
5478 if (n_alive_over100)
5480 fprintf(fff, _("101- 階 生存: %3d体\n", "Level 101- alive: %3d\n"), n_alive_over100);
5481 n_alive_total += n_alive_over100;
5486 fputs(_("--------- -----------\n", "------------- ----------\n"), fff);
5487 fprintf(fff, _(" 合計 生存: %3d体\n\n", " Total alive: %3d\n\n"), n_alive_total);
5491 fputs(_("現在は既知の生存ユニークはいません。\n", "No known uniques alive.\n"), fff);
5494 /* Scan the monster races */
5495 for (k = 0; k < n; k++)
5497 monster_race *r_ptr = &r_info[who[k]];
5499 fprintf(fff, _(" %s (レベル%d)\n", " %s (level %d)\n"), r_name + r_ptr->name, (int)r_ptr->level);
5502 /* Free the "who" array */
5503 C_KILL(who, max_r_idx, s16b);
5506 /* Display the file contents */
5507 show_file(TRUE, file_name, _("まだ生きているユニーク・モンスター", "Alive Uniques"), 0, 0);
5509 /* Remove the file */
5515 * Display weapon-exp
5517 static void do_cmd_knowledge_weapon_exp(void)
5519 int i, num, weapon_exp;
5524 GAME_TEXT file_name[1024];
5527 /* Open a new file */
5528 fff = my_fopen_temp(file_name, 1024);
5530 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5535 for (i = 0; i < 5; i++)
5537 for (num = 0; num < 64; num++)
5539 for (j = 0; j < max_k_idx; j++)
5541 object_kind *k_ptr = &k_info[j];
5543 if ((k_ptr->tval == TV_SWORD - i) && (k_ptr->sval == num))
5545 if ((k_ptr->tval == TV_BOW) && (k_ptr->sval == SV_CRIMSON || k_ptr->sval == SV_HARP)) continue;
5547 weapon_exp = p_ptr->weapon_exp[4 - i][num];
5549 fprintf(fff, "%-25s ", tmp);
5550 if (weapon_exp >= s_info[p_ptr->pclass].w_max[4 - i][num]) fprintf(fff, "!");
5551 else fprintf(fff, " ");
5552 fprintf(fff, "%s", exp_level_str[weapon_exp_level(weapon_exp)]);
5553 if (cheat_xtra) fprintf(fff, " %d", weapon_exp);
5562 /* Display the file contents */
5563 show_file(TRUE, file_name, _("武器の経験値", "Weapon Proficiency"), 0, 0);
5565 /* Remove the file */
5571 * @brief 魔法の経験値を表示するコマンドのメインルーチン
5575 static void do_cmd_knowledge_spell_exp(void)
5578 int spell_exp, exp_level;
5581 const magic_type *s_ptr;
5583 GAME_TEXT file_name[1024];
5585 /* Open a new file */
5586 fff = my_fopen_temp(file_name, 1024);
5588 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5593 if (p_ptr->realm1 != REALM_NONE)
5595 fprintf(fff, _("%sの魔法書\n", "%s Spellbook\n"), realm_names[p_ptr->realm1]);
5596 for (i = 0; i < 32; i++)
5598 if (!is_magic(p_ptr->realm1))
5600 s_ptr = &technic_info[p_ptr->realm1 - MIN_TECHNIC][i];
5604 s_ptr = &mp_ptr->info[p_ptr->realm1 - 1][i];
5606 if (s_ptr->slevel >= 99) continue;
5607 spell_exp = p_ptr->spell_exp[i];
5608 exp_level = spell_exp_level(spell_exp);
5609 fprintf(fff, "%-25s ", do_spell(p_ptr->realm1, i, SPELL_NAME));
5610 if (p_ptr->realm1 == REALM_HISSATSU)
5611 fprintf(fff, "[--]");
5614 if (exp_level >= EXP_LEVEL_MASTER) fprintf(fff, "!");
5615 else fprintf(fff, " ");
5616 fprintf(fff, "%s", exp_level_str[exp_level]);
5618 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5623 if (p_ptr->realm2 != REALM_NONE)
5625 fprintf(fff, _("%sの魔法書\n", "\n%s Spellbook\n"), realm_names[p_ptr->realm2]);
5626 for (i = 0; i < 32; i++)
5628 if (!is_magic(p_ptr->realm1))
5630 s_ptr = &technic_info[p_ptr->realm2 - MIN_TECHNIC][i];
5634 s_ptr = &mp_ptr->info[p_ptr->realm2 - 1][i];
5636 if (s_ptr->slevel >= 99) continue;
5638 spell_exp = p_ptr->spell_exp[i + 32];
5639 exp_level = spell_exp_level(spell_exp);
5640 fprintf(fff, "%-25s ", do_spell(p_ptr->realm2, i, SPELL_NAME));
5641 if (exp_level >= EXP_LEVEL_EXPERT) fprintf(fff, "!");
5642 else fprintf(fff, " ");
5643 fprintf(fff, "%s", exp_level_str[exp_level]);
5644 if (cheat_xtra) fprintf(fff, " %d", spell_exp);
5650 /* Display the file contents */
5651 show_file(TRUE, file_name, _("魔法の経験値", "Spell Proficiency"), 0, 0);
5653 /* Remove the file */
5659 * @brief スキル情報を表示するコマンドのメインルーチン /
5663 static void do_cmd_knowledge_skill_exp(void)
5665 int i = 0, skill_exp;
5669 GAME_TEXT file_name[1024];
5670 GAME_TEXT skill_name[3][20]={_("マーシャルアーツ", "Martial Arts "),
5671 _("二刀流 ", "Dual Wielding "),
5672 _("乗馬 ", "Riding ")};
5674 /* Open a new file */
5675 fff = my_fopen_temp(file_name, 1024);
5677 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5682 for (i = 0; i < 3; i++)
5684 skill_exp = p_ptr->skill_exp[i];
5685 fprintf(fff, "%-20s ", skill_name[i]);
5686 if (skill_exp >= s_info[p_ptr->pclass].s_max[i]) fprintf(fff, "!");
5687 else fprintf(fff, " ");
5688 fprintf(fff, "%s", exp_level_str[(i == GINOU_RIDING) ? riding_exp_level(skill_exp) : weapon_exp_level(skill_exp)]);
5689 if (cheat_xtra) fprintf(fff, " %d", skill_exp);
5694 /* Display the file contents */
5695 show_file(TRUE, file_name, _("技能の経験値", "Miscellaneous Proficiency"), 0, 0);
5697 /* Remove the file */
5703 * @brief 英単語、句、説を複数形を変換する / Pluralize a monster name
5704 * @param Name 変換したい文字列の参照ポインタ
5707 void plural_aux(char *Name)
5709 int NameLen = strlen(Name);
5711 if (my_strstr(Name, "Disembodied hand"))
5713 strcpy(Name, "Disembodied hands that strangled people");
5715 else if (my_strstr(Name, "Colour out of space"))
5717 strcpy(Name, "Colours out of space");
5719 else if (my_strstr(Name, "stairway to hell"))
5721 strcpy(Name, "stairways to hell");
5723 else if (my_strstr(Name, "Dweller on the threshold"))
5725 strcpy(Name, "Dwellers on the threshold");
5727 else if (my_strstr(Name, " of "))
5729 cptr aider = my_strstr(Name, " of ");
5740 if (dummy[i-1] == 's')
5742 strcpy(&(dummy[i]), "es");
5747 strcpy(&(dummy[i]), "s");
5750 strcpy(&(dummy[i+1]), aider);
5751 strcpy(Name, dummy);
5753 else if (my_strstr(Name, "coins"))
5756 strcpy(dummy, "piles of ");
5757 strcat(dummy, Name);
5758 strcpy(Name, dummy);
5761 else if (my_strstr(Name, "Manes"))
5765 else if (streq(&(Name[NameLen - 2]), "ey"))
5767 strcpy(&(Name[NameLen - 2]), "eys");
5769 else if (Name[NameLen - 1] == 'y')
5771 strcpy(&(Name[NameLen - 1]), "ies");
5773 else if (streq(&(Name[NameLen - 4]), "ouse"))
5775 strcpy(&(Name[NameLen - 4]), "ice");
5777 else if (streq(&(Name[NameLen - 2]), "us"))
5779 strcpy(&(Name[NameLen - 2]), "i");
5781 else if (streq(&(Name[NameLen - 6]), "kelman"))
5783 strcpy(&(Name[NameLen - 6]), "kelmen");
5785 else if (streq(&(Name[NameLen - 8]), "wordsman"))
5787 strcpy(&(Name[NameLen - 8]), "wordsmen");
5789 else if (streq(&(Name[NameLen - 7]), "oodsman"))
5791 strcpy(&(Name[NameLen - 7]), "oodsmen");
5793 else if (streq(&(Name[NameLen - 7]), "eastman"))
5795 strcpy(&(Name[NameLen - 7]), "eastmen");
5797 else if (streq(&(Name[NameLen - 8]), "izardman"))
5799 strcpy(&(Name[NameLen - 8]), "izardmen");
5801 else if (streq(&(Name[NameLen - 5]), "geist"))
5803 strcpy(&(Name[NameLen - 5]), "geister");
5805 else if (streq(&(Name[NameLen - 2]), "ex"))
5807 strcpy(&(Name[NameLen - 2]), "ices");
5809 else if (streq(&(Name[NameLen - 2]), "lf"))
5811 strcpy(&(Name[NameLen - 2]), "lves");
5813 else if (suffix(Name, "ch") ||
5814 suffix(Name, "sh") ||
5815 suffix(Name, "nx") ||
5816 suffix(Name, "s") ||
5819 strcpy(&(Name[NameLen]), "es");
5823 strcpy(&(Name[NameLen]), "s");
5828 * @brief 現在のペットを表示するコマンドのメインルーチン /
5829 * Display current pets
5832 static void do_cmd_knowledge_pets(void)
5836 monster_type *m_ptr;
5837 GAME_TEXT pet_name[MAX_NLEN];
5839 int show_upkeep = 0;
5840 GAME_TEXT file_name[1024];
5843 /* Open a new file */
5844 fff = my_fopen_temp(file_name, 1024);
5846 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5851 /* Process the monsters (backwards) */
5852 for (i = m_max - 1; i >= 1; i--)
5854 /* Access the monster */
5857 /* Ignore "dead" monsters */
5858 if (!m_ptr->r_idx) continue;
5860 /* Calculate "upkeep" for pets */
5864 monster_desc(pet_name, m_ptr, MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
5865 fprintf(fff, "%s (%s)\n", pet_name, look_mon_desc(m_ptr, 0x00));
5869 show_upkeep = calculate_upkeep();
5871 fprintf(fff, "----------------------------------------------\n");
5873 fprintf(fff, " 合計: %d 体のペット\n", t_friends);
5875 fprintf(fff, " Total: %d pet%s.\n", t_friends, (t_friends == 1 ? "" : "s"));
5877 fprintf(fff, _(" 維持コスト: %d%% MP\n", " Upkeep: %d%% mana.\n"), show_upkeep);
5882 /* Display the file contents */
5883 show_file(TRUE, file_name, _("現在のペット", "Current Pets"), 0, 0);
5885 /* Remove the file */
5891 * @brief 現在のペットを表示するコマンドのメインルーチン /
5894 * @note the player ghosts are ignored.
5896 static void do_cmd_knowledge_kill_count(void)
5903 GAME_TEXT file_name[1024];
5908 /* Open a new file */
5909 fff = my_fopen_temp(file_name, 1024);
5912 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
5917 /* Allocate the "who" array */
5918 C_MAKE(who, max_r_idx, MONRACE_IDX);
5921 /* Monsters slain */
5924 for (kk = 1; kk < max_r_idx; kk++)
5926 monster_race *r_ptr = &r_info[kk];
5928 if (r_ptr->flags1 & (RF1_UNIQUE))
5930 bool dead = (r_ptr->max_num == 0);
5939 MONSTER_NUMBER This = r_ptr->r_pkills;
5949 fprintf(fff,_("あなたはまだ敵を倒していない。\n\n", "You have defeated no enemies yet.\n\n"));
5952 fprintf(fff,"あなたは%ld体の敵を倒している。\n\n", (long int)Total);
5954 fprintf(fff,"You have defeated %ld %s.\n\n", (long int)Total, (Total == 1) ? "enemy" : "enemies");
5960 /* Scan the monsters */
5961 for (i = 1; i < max_r_idx; i++)
5963 monster_race *r_ptr = &r_info[i];
5965 /* Use that monster */
5966 if (r_ptr->name) who[n++] = i;
5969 /* Select the sort method */
5970 ang_sort_comp = ang_sort_comp_hook;
5971 ang_sort_swap = ang_sort_swap_hook;
5973 /* Sort the array by dungeon depth of monsters */
5974 ang_sort(who, &why, n);
5976 /* Scan the monster races */
5977 for (k = 0; k < n; k++)
5979 monster_race *r_ptr = &r_info[who[k]];
5981 if (r_ptr->flags1 & (RF1_UNIQUE))
5983 bool dead = (r_ptr->max_num == 0);
5987 fprintf(fff, " %s\n", (r_name + r_ptr->name));
5993 MONSTER_NUMBER This = r_ptr->r_pkills;
5998 /* p,tは人と数える by ita */
5999 if (my_strchr("pt", r_ptr->d_char))
6000 fprintf(fff, " %3d 人の %s\n", (int)This, r_name + r_ptr->name);
6002 fprintf(fff, " %3d 体の %s\n", (int)This, r_name + r_ptr->name);
6006 if (my_strstr(r_name + r_ptr->name, "coins"))
6008 fprintf(fff, " 1 pile of %s\n", (r_name + r_ptr->name));
6012 fprintf(fff, " 1 %s\n", (r_name + r_ptr->name));
6018 strcpy(ToPlural, (r_name + r_ptr->name));
6019 plural_aux(ToPlural);
6020 fprintf(fff, " %d %s\n", This, ToPlural);
6030 fprintf(fff,"----------------------------------------------\n");
6032 fprintf(fff," 合計: %lu 体を倒した。\n", (unsigned long int)Total);
6034 fprintf(fff," Total: %lu creature%s killed.\n", (unsigned long int)Total, (Total == 1 ? "" : "s"));
6038 /* Free the "who" array */
6039 C_KILL(who, max_r_idx, s16b);
6042 /* Display the file contents */
6043 show_file(TRUE, file_name, _("倒した敵の数", "Kill Count"), 0, 0);
6045 /* Remove the file */
6051 * @brief モンスター情報リスト中のグループを表示する /
6052 * Display the object groups.
6056 * @param per_page リストの表示行
6057 * @param grp_idx グループのID配列
6058 * @param group_text グループ名の文字列配列
6059 * @param grp_cur 現在の選択ID
6060 * @param grp_top 現在の選択リスト最上部ID
6063 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)
6067 /* Display lines until done */
6068 for (i = 0; i < per_page && (grp_idx[i] >= 0); i++)
6070 /* Get the group index */
6071 int grp = grp_idx[grp_top + i];
6073 /* Choose a color */
6074 TERM_COLOR attr = (grp_top + i == grp_cur) ? TERM_L_BLUE : TERM_WHITE;
6076 /* Erase the entire line */
6077 Term_erase(col, row + i, wid);
6079 /* Display the group label */
6080 c_put_str(attr, group_text[grp], row + i, col);
6086 * Move the cursor in a browser window
6088 static void browser_cursor(char ch, int *column, IDX *grp_cur, int grp_cnt,
6089 IDX *list_cur, int list_cnt)
6094 IDX list = *list_cur;
6096 /* Extract direction */
6099 /* Hack -- scroll up full screen */
6104 /* Hack -- scroll down full screen */
6109 d = get_keymap_dir(ch);
6114 /* Diagonals - hack */
6115 if ((ddx[d] > 0) && ddy[d])
6120 Term_get_size(&wid, &hgt);
6122 browser_rows = hgt - 8;
6124 /* Browse group list */
6129 /* Move up or down */
6130 grp += ddy[d] * (browser_rows - 1);
6133 if (grp >= grp_cnt) grp = grp_cnt - 1;
6134 if (grp < 0) grp = 0;
6135 if (grp != old_grp) list = 0;
6138 /* Browse sub-list list */
6141 /* Move up or down */
6142 list += ddy[d] * browser_rows;
6145 if (list >= list_cnt) list = list_cnt - 1;
6146 if (list < 0) list = 0;
6158 if (col < 0) col = 0;
6159 if (col > 1) col = 1;
6166 /* Browse group list */
6171 /* Move up or down */
6175 if (grp >= grp_cnt) grp = grp_cnt - 1;
6176 if (grp < 0) grp = 0;
6177 if (grp != old_grp) list = 0;
6180 /* Browse sub-list list */
6183 /* Move up or down */
6187 if (list >= list_cnt) list = list_cnt - 1;
6188 if (list < 0) list = 0;
6199 static void display_visual_list(int col, int row, int height, int width, TERM_COLOR attr_top, byte char_left)
6203 /* Clear the display lines */
6204 for (i = 0; i < height; i++)
6206 Term_erase(col, row + i, width);
6209 /* Bigtile mode uses double width */
6210 if (use_bigtile) width /= 2;
6212 /* Display lines until done */
6213 for (i = 0; i < height; i++)
6215 /* Display columns until done */
6216 for (j = 0; j < width; j++)
6220 TERM_LEN x = col + j;
6221 TERM_LEN y = row + i;
6224 /* Bigtile mode uses double width */
6225 if (use_bigtile) x += j;
6230 /* Ignore illegal characters */
6231 if (ia > 0x7f || ic > 0xff || ic < ' ' ||
6232 (!use_graphics && ic > 0x7f))
6238 /* Force correct code for both ASCII character and tile */
6239 if (c & 0x80) a |= 0x80;
6241 /* Display symbol */
6242 Term_queue_bigchar(x, y, a, c, 0, 0);
6249 * Place the cursor at the collect position for visual mode
6251 static void place_visual_list_cursor(TERM_LEN col, TERM_LEN row, TERM_COLOR a, byte c, TERM_COLOR attr_top, byte char_left)
6253 int i = (a & 0x7f) - attr_top;
6254 int j = c - char_left;
6256 TERM_LEN x = col + j;
6257 TERM_LEN y = row + i;
6259 /* Bigtile mode uses double width */
6260 if (use_bigtile) x += j;
6262 /* Place the cursor */
6268 * Clipboard variables for copy&paste in visual mode
6270 static TERM_COLOR attr_idx = 0;
6271 static byte char_idx = 0;
6273 /* Hack -- for feature lighting */
6274 static TERM_COLOR attr_idx_feat[F_LIT_MAX];
6275 static byte char_idx_feat[F_LIT_MAX];
6278 * Do visual mode command -- Change symbols
6280 static bool visual_mode_command(char ch, bool *visual_list_ptr,
6281 int height, int width,
6282 TERM_COLOR *attr_top_ptr, byte *char_left_ptr,
6283 TERM_COLOR *cur_attr_ptr, SYMBOL_CODE *cur_char_ptr, bool *need_redraw)
6285 static TERM_COLOR attr_old = 0;
6286 static SYMBOL_CODE char_old = 0;
6291 if (*visual_list_ptr)
6294 *cur_attr_ptr = attr_old;
6295 *cur_char_ptr = char_old;
6296 *visual_list_ptr = FALSE;
6304 if (*visual_list_ptr)
6307 *visual_list_ptr = FALSE;
6308 *need_redraw = TRUE;
6316 if (!*visual_list_ptr)
6318 *visual_list_ptr = TRUE;
6320 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6321 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6323 attr_old = *cur_attr_ptr;
6324 char_old = *cur_char_ptr;
6335 /* Set the visual */
6336 attr_idx = *cur_attr_ptr;
6337 char_idx = *cur_char_ptr;
6339 /* Hack -- for feature lighting */
6340 for (i = 0; i < F_LIT_MAX; i++)
6342 attr_idx_feat[i] = 0;
6343 char_idx_feat[i] = 0;
6350 if (attr_idx || (!(char_idx & 0x80) && char_idx)) /* Allow TERM_DARK text */
6353 *cur_attr_ptr = attr_idx;
6354 *attr_top_ptr = MAX(0, (*cur_attr_ptr & 0x7f) - 5);
6355 if (!*visual_list_ptr) *need_redraw = TRUE;
6361 *cur_char_ptr = char_idx;
6362 *char_left_ptr = MAX(0, *cur_char_ptr - 10);
6363 if (!*visual_list_ptr) *need_redraw = TRUE;
6369 if (*visual_list_ptr)
6372 int d = get_keymap_dir(ch);
6373 byte a = (*cur_attr_ptr & 0x7f);
6374 byte c = *cur_char_ptr;
6376 if (use_bigtile) eff_width = width / 2;
6377 else eff_width = width;
6379 /* Restrict direction */
6380 if ((a == 0) && (ddy[d] < 0)) d = 0;
6381 if ((c == 0) && (ddx[d] < 0)) d = 0;
6382 if ((a == 0x7f) && (ddy[d] > 0)) d = 0;
6383 if ((c == 0xff) && (ddx[d] > 0)) d = 0;
6388 /* Force correct code for both ASCII character and tile */
6389 if (c & 0x80) a |= 0x80;
6391 /* Set the visual */
6396 /* Move the frame */
6397 if ((ddx[d] < 0) && *char_left_ptr > MAX(0, (int)c - 10)) (*char_left_ptr)--;
6398 if ((ddx[d] > 0) && *char_left_ptr + eff_width < MIN(0xff, (int)c + 10)) (*char_left_ptr)++;
6399 if ((ddy[d] < 0) && *attr_top_ptr > MAX(0, (int)(a & 0x7f) - 4)) (*attr_top_ptr)--;
6400 if ((ddy[d] > 0) && *attr_top_ptr + height < MIN(0x7f, (a & 0x7f) + 4)) (*attr_top_ptr)++;
6406 /* Visual mode command is not used */
6412 * Display the monsters in a group.
6414 static void display_monster_list(int col, int row, int per_page, s16b mon_idx[],
6415 int mon_cur, int mon_top, bool visual_only)
6419 /* Display lines until done */
6420 for (i = 0; i < per_page && (mon_idx[mon_top + i] >= 0); i++)
6424 /* Get the race index */
6425 MONRACE_IDX r_idx = mon_idx[mon_top + i] ;
6427 /* Access the race */
6428 monster_race *r_ptr = &r_info[r_idx];
6430 /* Choose a color */
6431 attr = ((i + mon_top == mon_cur) ? TERM_L_BLUE : TERM_WHITE);
6433 /* Display the name */
6434 c_prt(attr, (r_name + r_ptr->name), row + i, col);
6436 /* Hack -- visual_list mode */
6439 c_prt(attr, format("%02x/%02x", r_ptr->x_attr, r_ptr->x_char), row + i, (p_ptr->wizard || visual_only) ? 56 : 61);
6441 if (p_ptr->wizard || visual_only)
6443 c_prt(attr, format("%d", r_idx), row + i, 62);
6446 /* Erase chars before overwritten by the race letter */
6447 Term_erase(69, row + i, 255);
6449 /* Display symbol */
6450 Term_queue_bigchar(use_bigtile ? 69 : 70, row + i, r_ptr->x_attr, r_ptr->x_char, 0, 0);
6455 if (!(r_ptr->flags1 & RF1_UNIQUE))
6456 put_str(format("%5d", r_ptr->r_pkills), row + i, 73);
6458 c_put_str((r_ptr->max_num == 0 ? TERM_L_DARK : TERM_WHITE),
6459 (r_ptr->max_num == 0 ? _("死亡", " dead") : _("生存", "alive")), row + i, 74);
6463 /* Clear remaining lines */
6464 for (; i < per_page; i++)
6466 Term_erase(col, row + i, 255);
6472 * Display known monsters.
6474 static void do_cmd_knowledge_monsters(bool *need_redraw, bool visual_only, IDX direct_r_idx)
6478 IDX grp_cur, grp_top, old_grp_cur;
6479 IDX mon_cur, mon_top;
6480 IDX grp_cnt, grp_idx[100];
6488 bool visual_list = FALSE;
6489 TERM_COLOR attr_top = 0;
6497 Term_get_size(&wid, &hgt);
6499 browser_rows = hgt - 8;
6501 /* Allocate the "mon_idx" array */
6502 C_MAKE(mon_idx, max_r_idx, s16b);
6507 if (direct_r_idx < 0)
6509 mode = visual_only ? 0x03 : 0x01;
6511 /* Check every group */
6512 for (i = 0; monster_group_text[i] != NULL; i++)
6514 /* Measure the label */
6515 len = strlen(monster_group_text[i]);
6517 /* Save the maximum length */
6518 if (len > max) max = len;
6520 /* See if any monsters are known */
6521 if ((monster_group_char[i] == ((char *) -1L)) || collect_monsters(i, mon_idx, mode))
6523 /* Build a list of groups with known monsters */
6524 grp_idx[grp_cnt++] = i;
6532 mon_idx[0] = direct_r_idx;
6535 /* Terminate the list */
6538 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6539 &attr_top, &char_left, &r_info[direct_r_idx].x_attr, &r_info[direct_r_idx].x_char, need_redraw);
6542 /* Terminate the list */
6543 grp_idx[grp_cnt] = -1;
6546 grp_cur = grp_top = 0;
6547 mon_cur = mon_top = 0;
6552 mode = visual_only ? 0x02 : 0x00;
6557 monster_race *r_ptr;
6562 prt(format(_("%s - モンスター", "%s - monsters"), !visual_only ? _("知識", "Knowledge") : _("表示", "Visuals")), 2, 0);
6563 if (direct_r_idx < 0) prt(_("グループ", "Group"), 4, 0);
6564 prt(_("名前", "Name"), 4, max + 3);
6565 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
6566 prt(_("文字", "Sym"), 4, 67);
6567 if (!visual_only) prt(_("殺害数", "Kills"), 4, 72);
6569 for (i = 0; i < 78; i++)
6571 Term_putch(i, 5, TERM_WHITE, '=');
6574 if (direct_r_idx < 0)
6576 for (i = 0; i < browser_rows; i++)
6578 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6585 if (direct_r_idx < 0)
6587 /* Scroll group list */
6588 if (grp_cur < grp_top) grp_top = grp_cur;
6589 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6591 /* Display a list of monster groups */
6592 display_group_list(0, 6, max, browser_rows, grp_idx, monster_group_text, grp_cur, grp_top);
6594 if (old_grp_cur != grp_cur)
6596 old_grp_cur = grp_cur;
6598 /* Get a list of monsters in the current group */
6599 mon_cnt = collect_monsters(grp_idx[grp_cur], mon_idx, mode);
6602 /* Scroll monster list */
6603 while (mon_cur < mon_top)
6604 mon_top = MAX(0, mon_top - browser_rows/2);
6605 while (mon_cur >= mon_top + browser_rows)
6606 mon_top = MIN(mon_cnt - browser_rows, mon_top + browser_rows/2);
6611 /* Display a list of monsters in the current group */
6612 display_monster_list(max + 3, 6, browser_rows, mon_idx, mon_cur, mon_top, visual_only);
6618 /* Display a monster name */
6619 display_monster_list(max + 3, 6, 1, mon_idx, mon_cur, mon_top, visual_only);
6621 /* Display visual list below first monster */
6622 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
6626 prt(format(_("<方向>%s%s%s, ESC", "<dir>%s%s%s, ESC"),
6627 (!visual_list && !visual_only) ? _(", 'r'で思い出を見る", ", 'r' to recall") : "",
6628 visual_list ? _(", ENTERで決定", ", ENTER to accept") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
6629 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
6632 /* Get the current monster */
6633 r_ptr = &r_info[mon_idx[mon_cur]];
6637 /* Mega Hack -- track this monster race */
6638 if (mon_cnt) monster_race_track(mon_idx[mon_cur]);
6644 place_visual_list_cursor(max + 3, 7, r_ptr->x_attr, r_ptr->x_char, attr_top, char_left);
6648 Term_gotoxy(0, 6 + (grp_cur - grp_top));
6652 Term_gotoxy(max + 3, 6 + (mon_cur - mon_top));
6657 /* Do visual mode command if needed */
6658 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))
6660 if (direct_r_idx >= 0)
6685 /* Recall on screen */
6686 if (!visual_list && !visual_only && (mon_idx[mon_cur] > 0))
6688 screen_roff(mon_idx[mon_cur], 0);
6699 /* Move the cursor */
6700 browser_cursor(ch, &column, &grp_cur, grp_cnt, &mon_cur, mon_cnt);
6707 /* Free the "mon_idx" array */
6708 C_KILL(mon_idx, max_r_idx, s16b);
6713 * Display the objects in a group.
6715 static void display_object_list(int col, int row, int per_page, IDX object_idx[],
6716 int object_cur, int object_top, bool visual_only)
6720 /* Display lines until done */
6721 for (i = 0; i < per_page && (object_idx[object_top + i] >= 0); i++)
6723 GAME_TEXT o_name[MAX_NLEN];
6726 object_kind *flavor_k_ptr;
6728 /* Get the object index */
6729 KIND_OBJECT_IDX k_idx = object_idx[object_top + i];
6731 /* Access the object */
6732 object_kind *k_ptr = &k_info[k_idx];
6734 /* Choose a color */
6735 TERM_COLOR attr = ((k_ptr->aware || visual_only) ? TERM_WHITE : TERM_SLATE);
6736 byte cursor = ((k_ptr->aware || visual_only) ? TERM_L_BLUE : TERM_BLUE);
6739 if (!visual_only && k_ptr->flavor)
6741 /* Appearance of this object is shuffled */
6742 flavor_k_ptr = &k_info[k_ptr->flavor];
6746 /* Appearance of this object is very normal */
6747 flavor_k_ptr = k_ptr;
6752 attr = ((i + object_top == object_cur) ? cursor : attr);
6754 if (!k_ptr->flavor || (!visual_only && k_ptr->aware))
6757 strip_name(o_name, k_idx);
6762 strcpy(o_name, k_name + flavor_k_ptr->flavor_name);
6765 /* Display the name */
6766 c_prt(attr, o_name, row + i, col);
6768 /* Hack -- visual_list mode */
6771 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);
6773 if (p_ptr->wizard || visual_only)
6775 c_prt(attr, format("%d", k_idx), row + i, 70);
6778 a = flavor_k_ptr->x_attr;
6779 c = flavor_k_ptr->x_char;
6781 /* Display symbol */
6782 Term_queue_bigchar(use_bigtile ? 76 : 77, row + i, a, c, 0, 0);
6785 /* Clear remaining lines */
6786 for (; i < per_page; i++)
6788 Term_erase(col, row + i, 255);
6793 * Describe fake object
6795 static void desc_obj_fake(KIND_OBJECT_IDX k_idx)
6798 object_type object_type_body;
6799 o_ptr = &object_type_body;
6802 /* Create the artifact */
6803 object_prep(o_ptr, k_idx);
6805 /* It's fully know */
6806 o_ptr->ident |= IDENT_KNOWN;
6808 /* Track the object */
6809 /* object_actual_track(o_ptr); */
6811 /* Hack - mark as fake */
6812 /* term_obj_real = FALSE; */
6815 if (!screen_object(o_ptr, SCROBJ_FAKE_OBJECT | SCROBJ_FORCE_DETAIL))
6817 msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
6825 * Display known objects
6827 static void do_cmd_knowledge_objects(bool *need_redraw, bool visual_only, IDX direct_k_idx)
6831 IDX grp_cur, grp_top, old_grp_cur;
6832 IDX object_old, object_cur, object_top;
6842 bool visual_list = FALSE;
6843 TERM_COLOR attr_top = 0;
6851 Term_get_size(&wid, &hgt);
6853 browser_rows = hgt - 8;
6855 /* Allocate the "object_idx" array */
6856 C_MAKE(object_idx, max_k_idx, IDX);
6861 if (direct_k_idx < 0)
6863 mode = visual_only ? 0x03 : 0x01;
6865 /* Check every group */
6866 for (i = 0; object_group_text[i] != NULL; i++)
6868 /* Measure the label */
6869 len = strlen(object_group_text[i]);
6871 /* Save the maximum length */
6872 if (len > max) max = len;
6874 /* See if any monsters are known */
6875 if (collect_objects(i, object_idx, mode))
6877 /* Build a list of groups with known monsters */
6878 grp_idx[grp_cnt++] = i;
6887 object_kind *k_ptr = &k_info[direct_k_idx];
6888 object_kind *flavor_k_ptr;
6890 if (!visual_only && k_ptr->flavor)
6892 /* Appearance of this object is shuffled */
6893 flavor_k_ptr = &k_info[k_ptr->flavor];
6897 /* Appearance of this object is very normal */
6898 flavor_k_ptr = k_ptr;
6901 object_idx[0] = direct_k_idx;
6902 object_old = direct_k_idx;
6905 /* Terminate the list */
6908 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
6909 &attr_top, &char_left, &flavor_k_ptr->x_attr, &flavor_k_ptr->x_char, need_redraw);
6912 /* Terminate the list */
6913 grp_idx[grp_cnt] = -1;
6916 grp_cur = grp_top = 0;
6917 object_cur = object_top = 0;
6922 mode = visual_only ? 0x02 : 0x00;
6927 object_kind *k_ptr, *flavor_k_ptr;
6934 prt(format("%s - アイテム", !visual_only ? "知識" : "表示"), 2, 0);
6935 if (direct_k_idx < 0) prt("グループ", 4, 0);
6936 prt("名前", 4, max + 3);
6937 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6940 prt(format("%s - objects", !visual_only ? "Knowledge" : "Visuals"), 2, 0);
6941 if (direct_k_idx < 0) prt("Group", 4, 0);
6942 prt("Name", 4, max + 3);
6943 if (p_ptr->wizard || visual_only) prt("Idx", 4, 70);
6947 for (i = 0; i < 78; i++)
6949 Term_putch(i, 5, TERM_WHITE, '=');
6952 if (direct_k_idx < 0)
6954 for (i = 0; i < browser_rows; i++)
6956 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
6963 if (direct_k_idx < 0)
6965 /* Scroll group list */
6966 if (grp_cur < grp_top) grp_top = grp_cur;
6967 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
6969 /* Display a list of object groups */
6970 display_group_list(0, 6, max, browser_rows, grp_idx, object_group_text, grp_cur, grp_top);
6972 if (old_grp_cur != grp_cur)
6974 old_grp_cur = grp_cur;
6976 /* Get a list of objects in the current group */
6977 object_cnt = collect_objects(grp_idx[grp_cur], object_idx, mode);
6980 /* Scroll object list */
6981 while (object_cur < object_top)
6982 object_top = MAX(0, object_top - browser_rows/2);
6983 while (object_cur >= object_top + browser_rows)
6984 object_top = MIN(object_cnt - browser_rows, object_top + browser_rows/2);
6989 /* Display a list of objects in the current group */
6990 display_object_list(max + 3, 6, browser_rows, object_idx, object_cur, object_top, visual_only);
6994 object_top = object_cur;
6996 /* Display a list of objects in the current group */
6997 display_object_list(max + 3, 6, 1, object_idx, object_cur, object_top, visual_only);
6999 /* Display visual list below first object */
7000 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7003 /* Get the current object */
7004 k_ptr = &k_info[object_idx[object_cur]];
7006 if (!visual_only && k_ptr->flavor)
7008 /* Appearance of this object is shuffled */
7009 flavor_k_ptr = &k_info[k_ptr->flavor];
7013 /* Appearance of this object is very normal */
7014 flavor_k_ptr = k_ptr;
7019 prt(format("<方向>%s%s%s, ESC",
7020 (!visual_list && !visual_only) ? ", 'r'で詳細を見る" : "",
7021 visual_list ? ", ENTERで決定" : ", 'v'でシンボル変更",
7022 (attr_idx || char_idx) ? ", 'c', 'p'でペースト" : ", 'c'でコピー"),
7025 prt(format("<dir>%s%s%s, ESC",
7026 (!visual_list && !visual_only) ? ", 'r' to recall" : "",
7027 visual_list ? ", ENTER to accept" : ", 'v' for visuals",
7028 (attr_idx || char_idx) ? ", 'c', 'p' to paste" : ", 'c' to copy"),
7034 /* Mega Hack -- track this object */
7035 if (object_cnt) object_kind_track(object_idx[object_cur]);
7037 /* The "current" object changed */
7038 if (object_old != object_idx[object_cur])
7042 /* Remember the "current" object */
7043 object_old = object_idx[object_cur];
7049 place_visual_list_cursor(max + 3, 7, flavor_k_ptr->x_attr, flavor_k_ptr->x_char, attr_top, char_left);
7053 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7057 Term_gotoxy(max + 3, 6 + (object_cur - object_top));
7062 /* Do visual mode command if needed */
7063 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))
7065 if (direct_k_idx >= 0)
7090 /* Recall on screen */
7091 if (!visual_list && !visual_only && (grp_cnt > 0))
7093 desc_obj_fake(object_idx[object_cur]);
7101 /* Move the cursor */
7102 browser_cursor(ch, &column, &grp_cur, grp_cnt, &object_cur, object_cnt);
7108 /* Free the "object_idx" array */
7109 C_KILL(object_idx, max_k_idx, IDX);
7114 * Display the features in a group.
7116 static void display_feature_list(int col, int row, int per_page, FEAT_IDX *feat_idx,
7117 FEAT_IDX feat_cur, FEAT_IDX feat_top, bool visual_only, int lighting_level)
7119 int lit_col[F_LIT_MAX], i, j;
7120 int f_idx_col = use_bigtile ? 62 : 64;
7122 /* Correct columns 1 and 4 */
7123 lit_col[F_LIT_STANDARD] = use_bigtile ? (71 - F_LIT_MAX) : 71;
7124 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7125 lit_col[i] = lit_col[F_LIT_STANDARD] + 2 + (i - F_LIT_NS_BEGIN) * 2 + (use_bigtile ? i : 0);
7127 /* Display lines until done */
7128 for (i = 0; i < per_page && (feat_idx[feat_top + i] >= 0); i++)
7133 FEAT_IDX f_idx = feat_idx[feat_top + i];
7135 /* Access the index */
7136 feature_type *f_ptr = &f_info[f_idx];
7138 int row_i = row + i;
7140 /* Choose a color */
7141 attr = ((i + feat_top == feat_cur) ? TERM_L_BLUE : TERM_WHITE);
7143 /* Display the name */
7144 c_prt(attr, f_name + f_ptr->name, row_i, col);
7146 /* Hack -- visual_list mode */
7149 /* Display lighting level */
7150 c_prt(attr, format("(%s)", lighting_level_str[lighting_level]), row_i, col + 1 + strlen(f_name + f_ptr->name));
7152 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));
7154 if (p_ptr->wizard || visual_only)
7156 c_prt(attr, format("%d", f_idx), row_i, f_idx_col);
7159 /* Display symbol */
7160 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);
7162 Term_putch(lit_col[F_LIT_NS_BEGIN], row_i, TERM_SLATE, '(');
7163 for (j = F_LIT_NS_BEGIN + 1; j < F_LIT_MAX; j++)
7165 Term_putch(lit_col[j], row_i, TERM_SLATE, '/');
7167 Term_putch(lit_col[F_LIT_MAX - 1] + (use_bigtile ? 3 : 2), row_i, TERM_SLATE, ')');
7169 /* Mega-hack -- Use non-standard colour */
7170 for (j = F_LIT_NS_BEGIN; j < F_LIT_MAX; j++)
7172 Term_queue_bigchar(lit_col[j] + 1, row_i, f_ptr->x_attr[j], f_ptr->x_char[j], 0, 0);
7176 /* Clear remaining lines */
7177 for (; i < per_page; i++)
7179 Term_erase(col, row + i, 255);
7185 * Interact with feature visuals.
7187 static void do_cmd_knowledge_features(bool *need_redraw, bool visual_only, IDX direct_f_idx, IDX *lighting_level)
7191 FEAT_IDX grp_cur, grp_top, old_grp_cur;
7192 FEAT_IDX feat_cur, feat_top;
7194 FEAT_IDX grp_idx[100];
7198 TERM_LEN column = 0;
7202 bool visual_list = FALSE;
7203 TERM_COLOR attr_top = 0;
7206 TERM_LEN browser_rows;
7209 TERM_COLOR attr_old[F_LIT_MAX];
7210 SYMBOL_CODE char_old[F_LIT_MAX];
7211 TERM_COLOR *cur_attr_ptr;
7212 SYMBOL_CODE *cur_char_ptr;
7214 (void)C_WIPE(attr_old, F_LIT_MAX, byte);
7215 (void)C_WIPE(char_old, F_LIT_MAX, byte);
7217 Term_get_size(&wid, &hgt);
7219 browser_rows = hgt - 8;
7221 /* Allocate the "feat_idx" array */
7222 C_MAKE(feat_idx, max_f_idx, FEAT_IDX);
7227 if (direct_f_idx < 0)
7229 /* Check every group */
7230 for (i = 0; feature_group_text[i] != NULL; i++)
7232 /* Measure the label */
7233 len = strlen(feature_group_text[i]);
7235 /* Save the maximum length */
7236 if (len > max) max = len;
7238 /* See if any features are known */
7239 if (collect_features(i, feat_idx, 0x01))
7241 /* Build a list of groups with known features */
7242 grp_idx[grp_cnt++] = i;
7250 feature_type *f_ptr = &f_info[direct_f_idx];
7252 feat_idx[0] = direct_f_idx;
7255 /* Terminate the list */
7258 (void)visual_mode_command('v', &visual_list, browser_rows - 1, wid - (max + 3),
7259 &attr_top, &char_left, &f_ptr->x_attr[*lighting_level], &f_ptr->x_char[*lighting_level], need_redraw);
7261 for (i = 0; i < F_LIT_MAX; i++)
7263 attr_old[i] = f_ptr->x_attr[i];
7264 char_old[i] = f_ptr->x_char[i];
7268 /* Terminate the list */
7269 grp_idx[grp_cnt] = -1;
7272 grp_cur = grp_top = 0;
7273 feat_cur = feat_top = 0;
7281 feature_type *f_ptr;
7287 prt(_("表示 - 地形", "Visuals - features"), 2, 0);
7288 if (direct_f_idx < 0) prt(_("グループ", "Group"), 4, 0);
7289 prt(_("名前", "Name"), 4, max + 3);
7292 if (p_ptr->wizard || visual_only) prt("Idx", 4, 62);
7293 prt(_("文字 ( l/ d)", "Sym ( l/ d)"), 4, 66);
7297 if (p_ptr->wizard || visual_only) prt("Idx", 4, 64);
7298 prt(_("文字 (l/d)", "Sym (l/d)"), 4, 68);
7301 for (i = 0; i < 78; i++)
7303 Term_putch(i, 5, TERM_WHITE, '=');
7306 if (direct_f_idx < 0)
7308 for (i = 0; i < browser_rows; i++)
7310 Term_putch(max + 1, 6 + i, TERM_WHITE, '|');
7317 if (direct_f_idx < 0)
7319 /* Scroll group list */
7320 if (grp_cur < grp_top) grp_top = grp_cur;
7321 if (grp_cur >= grp_top + browser_rows) grp_top = grp_cur - browser_rows + 1;
7323 /* Display a list of feature groups */
7324 display_group_list(0, 6, max, browser_rows, grp_idx, feature_group_text, grp_cur, grp_top);
7326 if (old_grp_cur != grp_cur)
7328 old_grp_cur = grp_cur;
7330 /* Get a list of features in the current group */
7331 feat_cnt = collect_features(grp_idx[grp_cur], feat_idx, 0x00);
7334 /* Scroll feature list */
7335 while (feat_cur < feat_top)
7336 feat_top = MAX(0, feat_top - browser_rows/2);
7337 while (feat_cur >= feat_top + browser_rows)
7338 feat_top = MIN(feat_cnt - browser_rows, feat_top + browser_rows/2);
7343 /* Display a list of features in the current group */
7344 display_feature_list(max + 3, 6, browser_rows, feat_idx, feat_cur, feat_top, visual_only, F_LIT_STANDARD);
7348 feat_top = feat_cur;
7350 /* Display a list of features in the current group */
7351 display_feature_list(max + 3, 6, 1, feat_idx, feat_cur, feat_top, visual_only, *lighting_level);
7353 /* Display visual list below first object */
7354 display_visual_list(max + 3, 7, browser_rows-1, wid - (max + 3), attr_top, char_left);
7358 prt(format(_("<方向>%s, 'd'で標準光源効果%s, ESC", "<dir>%s, 'd' for default lighting%s, ESC"),
7359 visual_list ? _(", ENTERで決定, 'a'で対象明度変更", ", ENTER to accept, 'a' for lighting level") : _(", 'v'でシンボル変更", ", 'v' for visuals"),
7360 (attr_idx || char_idx) ? _(", 'c', 'p'でペースト", ", 'c', 'p' to paste") : _(", 'c'でコピー", ", 'c' to copy")),
7363 /* Get the current feature */
7364 f_ptr = &f_info[feat_idx[feat_cur]];
7365 cur_attr_ptr = &f_ptr->x_attr[*lighting_level];
7366 cur_char_ptr = &f_ptr->x_char[*lighting_level];
7370 place_visual_list_cursor(max + 3, 7, *cur_attr_ptr, *cur_char_ptr, attr_top, char_left);
7374 Term_gotoxy(0, 6 + (grp_cur - grp_top));
7378 Term_gotoxy(max + 3, 6 + (feat_cur - feat_top));
7383 if (visual_list && ((ch == 'A') || (ch == 'a')))
7385 int prev_lighting_level = *lighting_level;
7389 if (*lighting_level <= 0) *lighting_level = F_LIT_MAX - 1;
7390 else (*lighting_level)--;
7394 if (*lighting_level >= F_LIT_MAX - 1) *lighting_level = 0;
7395 else (*lighting_level)++;
7398 if (f_ptr->x_attr[prev_lighting_level] != f_ptr->x_attr[*lighting_level])
7399 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7401 if (f_ptr->x_char[prev_lighting_level] != f_ptr->x_char[*lighting_level])
7402 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7407 else if ((ch == 'D') || (ch == 'd'))
7409 TERM_COLOR prev_x_attr = f_ptr->x_attr[*lighting_level];
7410 byte prev_x_char = f_ptr->x_char[*lighting_level];
7412 apply_default_feat_lighting(f_ptr->x_attr, f_ptr->x_char);
7416 if (prev_x_attr != f_ptr->x_attr[*lighting_level])
7417 attr_top = MAX(0, (f_ptr->x_attr[*lighting_level] & 0x7f) - 5);
7419 if (prev_x_char != f_ptr->x_char[*lighting_level])
7420 char_left = MAX(0, f_ptr->x_char[*lighting_level] - 10);
7422 else *need_redraw = TRUE;
7427 /* Do visual mode command if needed */
7428 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))
7432 /* Restore previous visual settings */
7434 for (i = 0; i < F_LIT_MAX; i++)
7436 f_ptr->x_attr[i] = attr_old[i];
7437 f_ptr->x_char[i] = char_old[i];
7444 if (direct_f_idx >= 0) flag = TRUE;
7445 else *lighting_level = F_LIT_STANDARD;
7448 /* Preserve current visual settings */
7451 for (i = 0; i < F_LIT_MAX; i++)
7453 attr_old[i] = f_ptr->x_attr[i];
7454 char_old[i] = f_ptr->x_char[i];
7456 *lighting_level = F_LIT_STANDARD;
7463 for (i = 0; i < F_LIT_MAX; i++)
7465 attr_idx_feat[i] = f_ptr->x_attr[i];
7466 char_idx_feat[i] = f_ptr->x_char[i];
7475 /* Allow TERM_DARK text */
7476 for (i = F_LIT_NS_BEGIN; i < F_LIT_MAX; i++)
7478 if (attr_idx_feat[i] || (!(char_idx_feat[i] & 0x80) && char_idx_feat[i])) f_ptr->x_attr[i] = attr_idx_feat[i];
7479 if (char_idx_feat[i]) f_ptr->x_char[i] = char_idx_feat[i];
7497 /* Move the cursor */
7498 browser_cursor(ch, &column, &grp_cur, grp_cnt, &feat_cur, feat_cnt);
7504 /* Free the "feat_idx" array */
7505 C_KILL(feat_idx, max_f_idx, FEAT_IDX);
7510 * List wanted monsters
7512 static void do_cmd_knowledge_kubi(void)
7517 GAME_TEXT file_name[1024];
7520 /* Open a new file */
7521 fff = my_fopen_temp(file_name, 1024);
7523 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7530 bool listed = FALSE;
7533 fprintf(fff, "今日のターゲット : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "不明"));
7535 fprintf(fff, "賞金首リスト\n");
7537 fprintf(fff, "Today target : %s\n", (p_ptr->today_mon ? r_name + r_info[p_ptr->today_mon].name : "unknown"));
7539 fprintf(fff, "List of wanted monsters\n");
7541 fprintf(fff, "----------------------------------------------\n");
7543 for (i = 0; i < MAX_KUBI; i++)
7545 if (kubi_r_idx[i] <= 10000)
7547 fprintf(fff,"%s\n", r_name + r_info[kubi_r_idx[i]].name);
7555 fprintf(fff,"\n%s\n", _("賞金首はもう残っていません。", "There is no more wanted monster."));
7560 /* Display the file contents */
7561 show_file(TRUE, file_name, _("賞金首の一覧", "Wanted monsters"), 0, 0);
7563 /* Remove the file */
7568 * List virtues & status
7570 static void do_cmd_knowledge_virtues(void)
7573 GAME_TEXT file_name[1024];
7575 /* Open a new file */
7576 fff = my_fopen_temp(file_name, 1024);
7578 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7585 fprintf(fff, _("現在の属性 : %s\n\n", "Your alighnment : %s\n\n"), your_alignment());
7590 /* Display the file contents */
7591 show_file(TRUE, file_name, _("八つの徳", "Virtues"), 0, 0);
7593 /* Remove the file */
7601 static void do_cmd_knowledge_dungeon(void)
7605 GAME_TEXT file_name[1024];
7608 /* Open a new file */
7609 fff = my_fopen_temp(file_name, 1024);
7611 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7618 for (i = 1; i < max_d_idx; i++)
7622 if (!d_info[i].maxdepth) continue;
7623 if (!max_dlv[i]) continue;
7624 if (d_info[i].final_guardian)
7626 if (!r_info[d_info[i].final_guardian].max_num) seiha = TRUE;
7628 else if (max_dlv[i] == d_info[i].maxdepth) seiha = TRUE;
7630 fprintf(fff, _("%c%-12s : %3d 階\n", "%c%-16s : level %3d\n"), seiha ? '!' : ' ', d_name + d_info[i].name, (int)max_dlv[i]);
7635 /* Display the file contents */
7636 show_file(TRUE, file_name, _("今までに入ったダンジョン", "Dungeon"), 0, 0);
7638 /* Remove the file */
7643 * List virtues & status
7646 static void do_cmd_knowledge_stat(void)
7650 GAME_TEXT file_name[1024];
7653 /* Open a new file */
7654 fff = my_fopen_temp(file_name, 1024);
7656 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
7663 percent = (int)(((long)p_ptr->player_hp[PY_MAX_LEVEL - 1] * 200L) /
7664 (2 * p_ptr->hitdie +
7665 ((PY_MAX_LEVEL - 1+3) * (p_ptr->hitdie + 1))));
7668 if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "現在の体力ランク : %d/100\n\n", percent);
7669 else fprintf(fff, "現在の体力ランク : ???\n\n");
7670 fprintf(fff, "能力の最大値\n\n");
7672 if (p_ptr->knowledge & KNOW_HPRATE) fprintf(fff, "Your current Life Rating is %d/100.\n\n", percent);
7673 else fprintf(fff, "Your current Life Rating is ???.\n\n");
7674 fprintf(fff, "Limits of maximum stats\n\n");
7676 for (v_nr = 0; v_nr < A_MAX; v_nr++)
7678 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);
7679 else fprintf(fff, "%s ???\n", stat_names[v_nr]);
7686 /* Display the file contents */
7687 show_file(TRUE, file_name, _("自分に関する情報", "HP-rate & Max stat"), 0, 0);
7689 /* Remove the file */
7695 * Print all active quests
7697 static void do_cmd_knowledge_quests_current(FILE *fff)
7700 char rand_tmp_str[120] = "\0";
7701 GAME_TEXT name[MAX_NLEN];
7702 monster_race *r_ptr;
7704 int rand_level = 100;
7707 fprintf(fff, _("《遂行中のクエスト》\n", "< Current Quest >\n"));
7709 for (i = 1; i < max_q_idx; i++)
7711 if ((quest[i].status == QUEST_STATUS_TAKEN) ||
7712 ((quest[i].status == QUEST_STATUS_STAGE_COMPLETED) && (quest[i].type == QUEST_TYPE_TOWER)) ||
7713 (quest[i].status == QUEST_STATUS_COMPLETED))
7715 /* Set the quest number temporary */
7716 IDX old_quest = p_ptr->inside_quest;
7719 /* Clear the text */
7720 for (j = 0; j < 10; j++) quest_text[j][0] = '\0';
7721 quest_text_line = 0;
7723 p_ptr->inside_quest = i;
7725 /* Get the quest text */
7726 init_flags = INIT_SHOW_TEXT;
7728 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7730 /* Reset the old quest number */
7731 p_ptr->inside_quest = old_quest;
7733 /* No info from "silent" quests */
7734 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7738 if (quest[i].type != QUEST_TYPE_RANDOM)
7740 char note[80] = "\0";
7742 if (quest[i].status == QUEST_STATUS_TAKEN || quest[i].status == QUEST_STATUS_STAGE_COMPLETED)
7744 switch (quest[i].type)
7746 case QUEST_TYPE_KILL_LEVEL:
7747 case QUEST_TYPE_KILL_ANY_LEVEL:
7748 r_ptr = &r_info[quest[i].r_idx];
7749 strcpy(name, r_name + r_ptr->name);
7750 if (quest[i].max_num > 1)
7753 sprintf(note," - %d 体の%sを倒す。(あと %d 体)",
7754 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7757 sprintf(note," - kill %d %s, have killed %d.",
7758 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7762 sprintf(note,_(" - %sを倒す。", " - kill %s."),name);
7765 case QUEST_TYPE_FIND_ARTIFACT:
7768 artifact_type *a_ptr = &a_info[quest[i].k_idx];
7770 object_type *q_ptr = &forge;
7771 KIND_OBJECT_IDX k_idx = lookup_kind(a_ptr->tval, a_ptr->sval);
7772 object_prep(q_ptr, k_idx);
7773 q_ptr->name1 = quest[i].k_idx;
7774 q_ptr->ident = IDENT_STORE;
7775 object_desc(name, q_ptr, OD_NAME_ONLY);
7777 sprintf(note,_("\n - %sを見つけ出す。", "\n - Find out %s."), name);
7779 case QUEST_TYPE_FIND_EXIT:
7780 sprintf(note,_(" - 出口に到達する。", " - Reach to Exit."));
7783 case QUEST_TYPE_KILL_NUMBER:
7785 sprintf(note," - %d 体のモンスターを倒す。(あと %d 体)",
7786 (int)quest[i].max_num, (int)(quest[i].max_num - quest[i].cur_num));
7788 sprintf(note," - Kill %d monsters, have killed %d.",
7789 (int)quest[i].max_num, (int)quest[i].cur_num);
7793 case QUEST_TYPE_KILL_ALL:
7794 case QUEST_TYPE_TOWER:
7795 sprintf(note,_(" - 全てのモンスターを倒す。", " - Kill all monsters."));
7800 /* Print the quest info */
7801 sprintf(tmp_str, _(" %s (危険度:%d階相当)%s\n", " %s (Danger level: %d)%s\n"),
7802 quest[i].name, (int)quest[i].level, note);
7804 fputs(tmp_str, fff);
7806 if (quest[i].status == QUEST_STATUS_COMPLETED)
7808 sprintf(tmp_str, _(" クエスト達成 - まだ報酬を受けとってない。\n", " Quest Completed - Unrewarded\n"));
7809 fputs(tmp_str, fff);
7815 while (quest_text[j][0] && j < 10)
7817 fprintf(fff, " %s\n", quest_text[j]);
7822 else if (quest[i].level < rand_level) /* QUEST_TYPE_RANDOM */
7825 rand_level = quest[i].level;
7827 if (max_dlv[DUNGEON_ANGBAND] >= rand_level)
7829 /* Print the quest info */
7830 r_ptr = &r_info[quest[i].r_idx];
7831 strcpy(name, r_name + r_ptr->name);
7833 if (quest[i].max_num > 1)
7836 sprintf(rand_tmp_str," %s (%d 階) - %d 体の%sを倒す。(あと %d 体)\n",
7837 quest[i].name, (int)quest[i].level,
7838 (int)quest[i].max_num, name, (int)(quest[i].max_num - quest[i].cur_num));
7842 sprintf(rand_tmp_str," %s (Dungeon level: %d)\n Kill %d %s, have killed %d.\n",
7843 quest[i].name, (int)quest[i].level,
7844 (int)quest[i].max_num, name, (int)quest[i].cur_num);
7849 sprintf(rand_tmp_str,_(" %s (%d 階) - %sを倒す。\n", " %s (Dungeon level: %d)\n Kill %s.\n"),
7850 quest[i].name, (int)quest[i].level, name);
7857 /* Print the current random quest */
7858 if (rand_tmp_str[0]) fputs(rand_tmp_str, fff);
7860 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7864 static bool do_cmd_knowledge_quests_aux(FILE *fff, IDX q_idx)
7867 char playtime_str[16];
7868 quest_type* const q_ptr = &quest[q_idx];
7870 if (is_fixed_quest_idx(q_idx))
7872 /* Set the quest number temporary */
7873 IDX old_quest = p_ptr->inside_quest;
7875 p_ptr->inside_quest = q_idx;
7878 init_flags = INIT_NAME_ONLY;
7880 process_dungeon_file("q_info.txt", 0, 0, 0, 0);
7882 /* Reset the old quest number */
7883 p_ptr->inside_quest = old_quest;
7885 /* No info from "silent" quests */
7886 if (q_ptr->flags & QUEST_FLAG_SILENT) return FALSE;
7889 strnfmt(playtime_str, sizeof(playtime_str), "%02d:%02d:%02d",
7890 q_ptr->comptime/(60*60), (q_ptr->comptime/60)%60, q_ptr->comptime%60);
7892 if (!is_fixed_quest_idx(q_idx) && q_ptr->r_idx)
7894 /* Print the quest info */
7895 if (q_ptr->complev == 0)
7898 _(" %-35s (%3d階) - 不戦勝 - %s\n",
7899 " %-35s (Dungeon level: %3d) - Unearned - %s\n") ,
7900 r_name+r_info[q_ptr->r_idx].name,
7901 (int)q_ptr->level, playtime_str);
7906 _(" %-35s (%3d階) - レベル%2d - %s\n",
7907 " %-35s (Dungeon level: %3d) - level %2d - %s\n") ,
7908 r_name+r_info[q_ptr->r_idx].name,
7916 /* Print the quest info */
7918 _(" %-35s (危険度:%3d階相当) - レベル%2d - %s\n",
7919 " %-35s (Danger level: %3d) - level %2d - %s\n") ,
7920 q_ptr->name, (int)q_ptr->level, q_ptr->complev, playtime_str);
7923 fputs(tmp_str, fff);
7929 * Print all finished quests
7931 void do_cmd_knowledge_quests_completed(FILE *fff, IDX quest_num[])
7936 fprintf(fff, _("《達成したクエスト》\n", "< Completed Quest >\n"));
7937 for (i = 1; i < max_q_idx; i++)
7939 IDX q_idx = quest_num[i];
7940 quest_type* const q_ptr = &quest[q_idx];
7942 if (q_ptr->status == QUEST_STATUS_FINISHED &&
7943 do_cmd_knowledge_quests_aux(fff, q_idx))
7948 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7953 * Print all failed quests
7955 void do_cmd_knowledge_quests_failed(FILE *fff, IDX quest_num[])
7960 fprintf(fff, _("《失敗したクエスト》\n", "< Failed Quest >\n"));
7961 for (i = 1; i < max_q_idx; i++)
7963 IDX q_idx = quest_num[i];
7964 quest_type* const q_ptr = &quest[q_idx];
7966 if (((q_ptr->status == QUEST_STATUS_FAILED_DONE) || (q_ptr->status == QUEST_STATUS_FAILED)) &&
7967 do_cmd_knowledge_quests_aux(fff, q_idx))
7972 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
7977 * Print all random quests
7979 static void do_cmd_knowledge_quests_wiz_random(FILE *fff)
7985 fprintf(fff, _("《残りのランダムクエスト》\n", "< Remaining Random Quest >\n"));
7986 for (i = 1; i < max_q_idx; i++)
7988 /* No info from "silent" quests */
7989 if (quest[i].flags & QUEST_FLAG_SILENT) continue;
7991 if ((quest[i].type == QUEST_TYPE_RANDOM) && (quest[i].status == QUEST_STATUS_TAKEN))
7995 /* Print the quest info */
7996 sprintf(tmp_str, _(" %s (%d階, %s)\n", " %s (%d, %s)\n"),
7997 quest[i].name, (int)quest[i].level, r_name+r_info[quest[i].r_idx].name);
7998 fputs(tmp_str, fff);
8001 if (!total) fprintf(fff, _(" なし\n", " Nothing.\n"));
8005 bool ang_sort_comp_quest_num(vptr u, vptr v, int a, int b)
8007 QUEST_IDX *q_num = (QUEST_IDX *)u;
8008 quest_type *qa = &quest[q_num[a]];
8009 quest_type *qb = &quest[q_num[b]];
8014 return (qa->comptime != qb->comptime) ?
8015 (qa->comptime < qb->comptime) :
8016 (qa->level <= qb->level);
8019 void ang_sort_swap_quest_num(vptr u, vptr v, int a, int b)
8021 QUEST_IDX *q_num = (QUEST_IDX *)u;
8028 q_num[a] = q_num[b];
8034 * Print quest status of all active quests
8036 static void do_cmd_knowledge_quests(void)
8039 GAME_TEXT file_name[1024];
8044 /* Open a new file */
8045 fff = my_fopen_temp(file_name, 1024);
8048 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8053 /* Allocate Memory */
8054 C_MAKE(quest_num, max_q_idx, IDX);
8056 /* Sort by compete level */
8057 for (i = 1; i < max_q_idx; i++) quest_num[i] = i;
8058 ang_sort_comp = ang_sort_comp_quest_num;
8059 ang_sort_swap = ang_sort_swap_quest_num;
8060 ang_sort(quest_num, &dummy, max_q_idx);
8062 /* Dump Quest Information */
8063 do_cmd_knowledge_quests_current(fff);
8065 do_cmd_knowledge_quests_completed(fff, quest_num);
8067 do_cmd_knowledge_quests_failed(fff, quest_num);
8071 do_cmd_knowledge_quests_wiz_random(fff);
8075 /* Display the file contents */
8076 show_file(TRUE, file_name, _("クエスト達成状況", "Quest status"), 0, 0);
8078 /* Remove the file */
8082 C_KILL(quest_num, max_q_idx, IDX);
8089 static void do_cmd_knowledge_home(void)
8094 GAME_TEXT file_name[1024];
8096 GAME_TEXT o_name[MAX_NLEN];
8099 process_dungeon_file("w_info.txt", 0, 0, max_wild_y, max_wild_x);
8101 /* Open a new file */
8102 fff = my_fopen_temp(file_name, 1024);
8104 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8111 /* Print all homes in the different towns */
8112 st_ptr = &town[1].store[STORE_HOME];
8114 /* Home -- if anything there */
8115 if (st_ptr->stock_num)
8120 /* Header with name of the town */
8121 fprintf(fff, _(" [ 我が家のアイテム ]\n", " [Home Inventory]\n"));
8123 /* Dump all available items */
8124 for (i = 0; i < st_ptr->stock_num; i++)
8127 if ((i % 12) == 0) fprintf(fff, "\n ( %d ページ )\n", x++);
8128 object_desc(o_name, &st_ptr->stock[i], 0);
8129 if (strlen(o_name) <= 80-3)
8131 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8137 for (n = 0, t = o_name; n < 80-3; n++, t++)
8138 if(iskanji(*t)) {t++; n++;}
8139 if (n == 81-3) n = 79-3; /* 最後が漢字半分 */
8141 fprintf(fff, "%c%s %.*s\n", I2A(i%12), paren, n, o_name);
8142 fprintf(fff, " %.77s\n", o_name+n);
8145 object_desc(o_name, &st_ptr->stock[i], 0);
8146 fprintf(fff, "%c%s %s\n", I2A(i%12), paren, o_name);
8151 /* Add an empty line */
8152 fprintf(fff, "\n\n");
8157 /* Display the file contents */
8158 show_file(TRUE, file_name, _("我が家のアイテム", "Home Inventory"), 0, 0);
8160 /* Remove the file */
8166 * Check the status of "autopick"
8168 static void do_cmd_knowledge_autopick(void)
8172 GAME_TEXT file_name[1024];
8174 /* Open a new file */
8175 fff = my_fopen_temp(file_name, 1024);
8179 msg_format(_("一時ファイル %s を作成できませんでした。", "Failed to create temporary file %s."), file_name);
8186 fprintf(fff, _("自動破壊/拾いには何も登録されていません。", "No preference for auto picker/destroyer."));
8190 fprintf(fff, _(" 自動拾い/破壊には現在 %d行登録されています。\n\n",
8191 " There are %d registered lines for auto picker/destroyer.\n\n"), max_autopick);
8194 for (k = 0; k < max_autopick; k++)
8197 byte act = autopick_list[k].action;
8198 if (act & DONT_AUTOPICK)
8200 tmp = _("放置", "Leave");
8202 else if (act & DO_AUTODESTROY)
8204 tmp = _("破壊", "Destroy");
8206 else if (act & DO_AUTOPICK)
8208 tmp = _("拾う", "Pickup");
8212 tmp = _("確認", "Query");
8215 if (act & DO_DISPLAY)
8216 fprintf(fff, "%11s", format("[%s]", tmp));
8218 fprintf(fff, "%11s", format("(%s)", tmp));
8220 tmp = autopick_line_from_entry(&autopick_list[k]);
8221 fprintf(fff, " %s", tmp);
8226 /* Display the file contents */
8227 show_file(TRUE, file_name, _("自動拾い/破壊 設定リスト", "Auto-picker/Destroyer"), 0, 0);
8229 /* Remove the file */
8235 * Interact with "knowledge"
8237 void do_cmd_knowledge(void)
8240 bool need_redraw = FALSE;
8242 /* File type is "TEXT" */
8243 FILE_TYPE(FILE_TYPE_TEXT);
8246 /* Interact until done */
8251 /* Ask for a choice */
8252 prt(format(_("%d/2 ページ", "page %d/2"), (p+1)), 2, 65);
8253 prt(_("現在の知識を確認する", "Display current knowledge"), 3, 0);
8255 /* Give some choices */
8259 prt("(1) 既知の伝説のアイテム の一覧", 6, 5);
8260 prt("(2) 既知のアイテム の一覧", 7, 5);
8261 prt("(3) 既知の生きているユニーク・モンスター の一覧", 8, 5);
8262 prt("(4) 既知のモンスター の一覧", 9, 5);
8263 prt("(5) 倒した敵の数 の一覧", 10, 5);
8264 if (!vanilla_town) prt("(6) 賞金首 の一覧", 11, 5);
8265 prt("(7) 現在のペット の一覧", 12, 5);
8266 prt("(8) 我が家のアイテム の一覧", 13, 5);
8267 prt("(9) *鑑定*済み装備の耐性 の一覧", 14, 5);
8268 prt("(0) 地形の表示文字/タイル の一覧", 15, 5);
8272 prt("(a) 自分に関する情報 の一覧", 6, 5);
8273 prt("(b) 突然変異 の一覧", 7, 5);
8274 prt("(c) 武器の経験値 の一覧", 8, 5);
8275 prt("(d) 魔法の経験値 の一覧", 9, 5);
8276 prt("(e) 技能の経験値 の一覧", 10, 5);
8277 prt("(f) プレイヤーの徳 の一覧", 11, 5);
8278 prt("(g) 入ったダンジョン の一覧", 12, 5);
8279 prt("(h) 実行中のクエスト の一覧", 13, 5);
8280 prt("(i) 現在の自動拾い/破壊設定 の一覧", 14, 5);
8285 prt("(1) Display known artifacts", 6, 5);
8286 prt("(2) Display known objects", 7, 5);
8287 prt("(3) Display remaining uniques", 8, 5);
8288 prt("(4) Display known monster", 9, 5);
8289 prt("(5) Display kill count", 10, 5);
8290 if (!vanilla_town) prt("(6) Display wanted monsters", 11, 5);
8291 prt("(7) Display current pets", 12, 5);
8292 prt("(8) Display home inventory", 13, 5);
8293 prt("(9) Display *identified* equip.", 14, 5);
8294 prt("(0) Display terrain symbols.", 15, 5);
8298 prt("(a) Display about yourself", 6, 5);
8299 prt("(b) Display mutations", 7, 5);
8300 prt("(c) Display weapon proficiency", 8, 5);
8301 prt("(d) Display spell proficiency", 9, 5);
8302 prt("(e) Display misc. proficiency", 10, 5);
8303 prt("(f) Display virtues", 11, 5);
8304 prt("(g) Display dungeons", 12, 5);
8305 prt("(h) Display current quests", 13, 5);
8306 prt("(i) Display auto pick/destroy", 14, 5);
8310 prt(_("-続く-", "-more-"), 17, 8);
8311 prt(_("ESC) 抜ける", "ESC) Exit menu"), 21, 1);
8312 prt(_("SPACE) 次ページ", "SPACE) Next page"), 21, 30);
8313 /*prt("-) 前ページ", 21, 60);*/
8314 prt(_("コマンド:", "Command: "), 20, 0);
8317 if (i == ESCAPE) break;
8320 case ' ': /* Page change */
8324 case '1': /* Artifacts */
8325 do_cmd_knowledge_artifacts();
8327 case '2': /* Objects */
8328 do_cmd_knowledge_objects(&need_redraw, FALSE, -1);
8330 case '3': /* Uniques */
8331 do_cmd_knowledge_uniques();
8333 case '4': /* Monsters */
8334 do_cmd_knowledge_monsters(&need_redraw, FALSE, -1);
8336 case '5': /* Kill count */
8337 do_cmd_knowledge_kill_count();
8339 case '6': /* wanted */
8340 if (!vanilla_town) do_cmd_knowledge_kubi();
8342 case '7': /* Pets */
8343 do_cmd_knowledge_pets();
8345 case '8': /* Home */
8346 do_cmd_knowledge_home();
8348 case '9': /* Resist list */
8349 do_cmd_knowledge_inven();
8351 case '0': /* Feature list */
8353 IDX lighting_level = F_LIT_STANDARD;
8354 do_cmd_knowledge_features(&need_redraw, FALSE, -1, &lighting_level);
8358 case 'a': /* Max stat */
8359 do_cmd_knowledge_stat();
8361 case 'b': /* Mutations */
8362 do_cmd_knowledge_mutations();
8364 case 'c': /* weapon-exp */
8365 do_cmd_knowledge_weapon_exp();
8367 case 'd': /* spell-exp */
8368 do_cmd_knowledge_spell_exp();
8370 case 'e': /* skill-exp */
8371 do_cmd_knowledge_skill_exp();
8373 case 'f': /* Virtues */
8374 do_cmd_knowledge_virtues();
8376 case 'g': /* Dungeon */
8377 do_cmd_knowledge_dungeon();
8379 case 'h': /* Quests */
8380 do_cmd_knowledge_quests();
8382 case 'i': /* Autopick */
8383 do_cmd_knowledge_autopick();
8385 default: /* Unknown option */
8393 if (need_redraw) do_cmd_redraw();
8398 * Check on the status of an active quest
8400 void do_cmd_checkquest(void)
8402 /* File type is "TEXT" */
8403 FILE_TYPE(FILE_TYPE_TEXT);
8407 do_cmd_knowledge_quests();
8413 * Display the time and date
8415 void do_cmd_time(void)
8417 int day, hour, min, full, start, end, num;
8425 extract_day_hour_min(&day, &hour, &min);
8427 full = hour * 100 + min;
8434 strcpy(desc, _("変な時刻だ。", "It is a strange time."));
8436 if (day < MAX_DAYS) sprintf(day_buf, "%d", day);
8437 else strcpy(day_buf, "*****");
8440 msg_format("%s日目, 時刻は%d:%02d %sです。",
8441 day_buf, (hour % 12 == 0) ? 12 : (hour % 12),
8442 min, (hour < 12) ? "AM" : "PM");
8444 msg_format("This is day %s. The time is %d:%02d %s.",
8445 day_buf, (hour % 12 == 0) ? 12 : (hour % 12),
8446 min, (hour < 12) ? "AM" : "PM");
8451 if (!randint0(10) || p_ptr->image)
8453 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timefun_j.txt", "timefun.txt"));
8457 path_build(buf, sizeof(buf), ANGBAND_DIR_FILE, _("timenorm_j.txt", "timenorm.txt"));
8460 /* Open this file */
8461 fff = my_fopen(buf, "rt");
8465 /* Find this time */
8466 while (!my_fgets(fff, buf, sizeof(buf)))
8468 /* Ignore comments */
8469 if (!buf[0] || (buf[0] == '#')) continue;
8471 /* Ignore invalid lines */
8472 if (buf[1] != ':') continue;
8474 /* Process 'Start' */
8477 /* Extract the starting time */
8478 start = atoi(buf + 2);
8480 /* Assume valid for an hour */
8490 /* Extract the ending time */
8491 end = atoi(buf + 2);
8497 /* Ignore incorrect range */
8498 if ((start > full) || (full > end)) continue;
8500 /* Process 'Description' */
8505 /* Apply the randomizer */
8506 if (!randint0(num)) strcpy(desc, buf + 2);